Skip to content

Commit 60f4102

Browse files
authored
Add more instructions for coding agents (#2834)
gherrit-pr-id: Icc2e26ad2a5c67a16f328a605b5821e36dbb343f
1 parent ce4e673 commit 60f4102

File tree

8 files changed

+440
-83
lines changed

8 files changed

+440
-83
lines changed

.gemini/styleguide.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,10 @@ those terms. -->
88

99
# Coding Guidelines
1010

11-
Please follow the development instructions and coding guidelines defined in `AGENTS.md` located in the root of this repository.
11+
Please follow the development instructions and coding guidelines defined in
12+
`AGENTS.md` and `CONTRIBUTING.md` files located in the root of this repository.
13+
14+
> [!IMPORTANT]
15+
> **READ `AGENTS.md` FIRST.**
16+
> All critical instructions, including build commands, safety rules, and code
17+
> style, are defined in `AGENTS.md`. You must read and follow them.

AGENTS.md

Lines changed: 46 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -6,100 +6,67 @@ license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
66
This file may not be copied, modified, or distributed except according to
77
those terms. -->
88

9-
# Development Instructions
9+
# Instructions for AI Agents
1010

11-
This repository uses a wrapper script around Cargo to ensure consistent toolchain usage and configuration.
11+
## Agent Persona & Role
1212

13-
## Build and Test
13+
You are an expert Rust systems programmer contributing to **zerocopy**, a
14+
library for zero-cost memory manipulation which presents a safe API over what
15+
would otherwise be dangerous operations. Your goal is to write high-quality,
16+
sound, and performant Rust code that adheres to strict safety and soundness
17+
guidelines and works across multiple Rust toolchains and compilation targets.
1418

15-
**IMPORTANT:** You must **NEVER** run `cargo` directly. Instead, you must **ALWAYS** use `yes | ./cargo.sh` for all `cargo` sub-commands (e.g., `check`, `test`, `build`). Using `yes |` is required to bypass interactive prompts for toolchain installation.
19+
## Critical Rules
1620

17-
### Syntax
18-
`yes | ./cargo.sh +<toolchain> <command> [args]`
21+
- **README Generation:** **DON'T** edit `README.md` directly. It is generated
22+
from `src/lib.rs`. Edit the top-level doc comment in `src/lib.rs` instead.
23+
- **To regenerate:**
24+
`./cargo.sh +stable run --manifest-path tools/generate-readme/Cargo.toml > README.md`
1925

20-
### Toolchains
21-
The `<toolchain>` argument is mandatory and can be one of the following:
26+
<!-- TODO-check-disable -->
27+
- **TODOs:** **DON'T** use `TODO` comments unless you explicitly intend to block
28+
the PR (CI fails on `TODO`). Use `FIXME` for non-blocking issues.
29+
<!-- TODO-check-enable -->
2230

23-
- `msrv`: Runs with the Minimum Supported Rust Version.
24-
- `stable`: Runs with the stable toolchain.
25-
- `nightly`: Runs with the nightly toolchain.
26-
- `all`: Runs the command on `msrv`, `stable`, and `nightly` sequentially.
27-
- Version-gated toolchains: You can also pass specific version-gated toolchains defined in `Cargo.toml`, such as `zerocopy-core-error-1-81-0`.
31+
- **Documentation:** **DO** ensure that changes do not cause documentation to
32+
become out of date (e.g., renaming files referenced here).
2833

29-
### Linting
34+
## Project Context
3035

31-
Clippy should **always** be run on the `nightly` toolchain.
36+
### Overview
3237

33-
```bash
34-
yes | ./cargo.sh +nightly clippy
35-
yes | ./cargo.sh +nightly clippy --tests
36-
```
38+
Zerocopy is a library designed to make zero-copy memory manipulation safe and
39+
easy. It relies heavily on Rust's type system and specific traits to ensure
40+
memory safety.
3741

38-
### Examples
42+
### Project Structure
3943

40-
```bash
41-
# Check the code using the nightly toolchain
42-
# DO NOT RUN: cargo check
43-
yes | ./cargo.sh +nightly check
44+
- `src/`: Core library source code.
45+
- `zerocopy-derive/`: Source code and tests for the procedural macros.
46+
- `tests/`: UI and integration tests for the main crate.
47+
- `tools/`: Internal tools and scripts.
48+
- `ci/`: CI configuration and scripts.
49+
- `githooks/`: Git hooks for pre-commit/pre-push checks.
50+
- `testdata/`: Data used for testing.
51+
- `testutil/`: Utility code for tests.
4452

45-
# Run tests on all supported toolchains
46-
# DO NOT RUN: cargo test
47-
yes | ./cargo.sh +all test
53+
## Development Workflow
4854

49-
# Run a specific test on stable
50-
yes | ./cargo.sh +stable test -- test_name
51-
```
55+
When developing code changes, you **MUST** read
56+
[agent_docs/development.md](./agent_docs/development.md).
5257

53-
## Workflow
58+
### Before submitting
5459

55-
### Pre-submission Checks
60+
Once you have made a change, you **MUST** read the relevant documents to ensure
61+
that your change is valid and follows the style guidelines.
5662

57-
Before submitting code, run `./githooks/pre-push` to confirm that all pre-push hooks succeed.
63+
- [agent_docs/validation.md](./agent_docs/validation.md) for validating code
64+
changes
65+
- [agent_docs/style.md](./agent_docs/style.md) for style and formatting
66+
guidelines for files and commit messages
5867

59-
### UI Tests
68+
#### Pre-submission Checks
6069

61-
When updating UI test files (in `tests/ui*` or `zerocopy-derive/tests/ui*`), run `./tools/update-ui-test-files.sh` to update the corresponding stderr files.
62-
63-
### Pull Requests and Commit Messages
64-
65-
When a PR resolves an issue, the PR description and commit message should include a line like `Closes #123`.
66-
When a PR makes progress on, but does not close, an issue, the PR description and commit message should include a line like `Makes progress on #123`.
67-
68-
## Safety
69-
70-
### Pointer Casts
71-
72-
- **Avoid `&slice[0] as *const T` or `&slice[0] as *mut T`.**
73-
Instead, use `slice.as_ptr()` or `slice.as_mut_ptr()`. Casting a reference to
74-
a single element creates a raw pointer that is only valid for that element.
75-
Accessing subsequent elements via pointer arithmetic is Undefined Behavior.
76-
See [unsafe-code-guidelines#134](https://github.com/rust-lang/unsafe-code-guidelines/issues/134).
77-
78-
- **Avoid converting `&mut T` to `*const T` (or `*const U`)**.
79-
This advice applies if you intend to later cast the pointer to `*mut T` and
80-
mutate the data. This conversion reborrows `&mut T` as a shared reference
81-
`&T`, which may restrict permissions under Stacked Borrows. Instead, cast
82-
`&mut T` directly to `*mut T` first, then to `*const T` if necessary. See
83-
[rust#56604](https://github.com/rust-lang/rust/issues/56604).
84-
85-
## Code Style
86-
87-
### File Headers
88-
89-
Each file should contain a copyright header (excluding auto-generated files such as `.stderr` files). The header should follow the format found in existing files (e.g. `src/lib.rs`), using the appropriate comment syntax for the file type.
90-
91-
### Formatting
92-
93-
To determine how to format code, read the formatting checker script in `ci/check_fmt.sh`.
94-
95-
### Comments
96-
97-
All comments (including `//`, `///`, and `//!`) should be wrapped at 80 columns.
98-
99-
**Exceptions:**
100-
- Markdown tables
101-
- Inline ASCII diagrams
102-
- Long URLs
103-
- Comments inside of code blocks
104-
- Comments which trail non-comment code
105-
- Other cases where wrapping would significantly degrade readability (use your judgment).
70+
Run `./githooks/pre-push` before submitting. This runs a comprehensive suite of
71+
checks, including formatting, toolchain verification, and script validation. It
72+
catches many issues that would otherwise fail in CI.

Cargo.toml

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,18 @@
1616
edition = "2021"
1717
name = "zerocopy"
1818
version = "0.8.31"
19-
authors = ["Joshua Liebow-Feeser <[email protected]>", "Jack Wrenn <[email protected]>"]
19+
authors = [
20+
"Joshua Liebow-Feeser <[email protected]>",
21+
"Jack Wrenn <[email protected]>",
22+
]
2023
description = "Zerocopy makes zero-cost memory manipulation effortless. We write \"unsafe\" so you don't have to."
21-
categories = ["embedded", "encoding", "no-std::no-alloc", "parsing", "rust-patterns"]
24+
categories = [
25+
"embedded",
26+
"encoding",
27+
"no-std::no-alloc",
28+
"parsing",
29+
"rust-patterns",
30+
]
2231
keywords = ["cast", "convert", "transmute", "transmutation", "type-punning"]
2332
license = "BSD-2-Clause OR Apache-2.0 OR MIT"
2433
repository = "https://github.com/google/zerocopy"
@@ -35,6 +44,18 @@ exclude = [".*"]
3544
# Each name is suffixed with the version it corresponds to. This is a convention
3645
# used in the codebase to make it less likely for us to make mistakes when
3746
# writing `doc_cfg` attributes.
47+
#
48+
# It may seem odd to name cfgs `no-zerocopy-foo` and emit these cfgs on
49+
# toolchains lower than that target toolchain. We do this because it is
50+
# friendlier to users who compile zerocopy by directly invoking rustc or by
51+
# invoking rustc from a build system other than Cargo. If such a user provides
52+
# no `--cfg` arguments, then, assuming they are on a sufficiently recent
53+
# toolchain, everything will "just work" without requiring extra configuration.
54+
# See [1] for an example of a user upgrading from a version of zerocopy which
55+
# did things in the inverse way. See #2259 for more context.
56+
#
57+
# [1] https://fuchsia-review.googlesource.com/c/fuchsia/+/1433139/1/third_party/rust_crates/Cargo.toml
58+
3859

3960
# From 1.89.0, Rust supports x86 AVX-12 SIMD types (previously gated by the
4061
# `stdarch_x86_avx512` feature).
@@ -83,7 +104,12 @@ std = ["alloc"]
83104
# This feature depends on all other features that work on the stable compiler.
84105
# We make no stability guarantees about this feature; it may be modified or
85106
# removed at any time.
86-
__internal_use_only_features_that_work_on_stable = ["alloc", "derive", "simd", "std"]
107+
__internal_use_only_features_that_work_on_stable = [
108+
"alloc",
109+
"derive",
110+
"simd",
111+
"std",
112+
]
87113

88114
[dependencies]
89115
zerocopy-derive = { version = "=0.8.31", path = "zerocopy-derive", optional = true }

agent_docs/development.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<!-- Copyright 2025 The Fuchsia Authors
2+
3+
Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
4+
<LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
5+
license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6+
This file may not be copied, modified, or distributed except according to
7+
those terms. -->
8+
9+
# Development Guidelines
10+
11+
This document covers guidelines for developing code changes.
12+
13+
## Build and Test
14+
15+
This repository uses a wrapper script (`cargo.sh`) to ensure consistent
16+
toolchain usage and configuration.
17+
18+
> [!IMPORTANT]
19+
> **NEVER** run `cargo` directly.
20+
> **ALWAYS** use `./cargo.sh` for all cargo sub-commands.
21+
>
22+
> **Why?** `cargo.sh` ensures that the toolchains used in development match
23+
> those in CI, which is important because some features are only available on
24+
> specific toolchains, and because UI tests rely on the text of compiler errors,
25+
> which changes between toolchain versions.
26+
27+
### Syntax
28+
29+
`./cargo.sh +<toolchain> <command> [args]`
30+
31+
This is equivalent to:
32+
33+
`cargo +1.2.3 <command> [args]`
34+
35+
...where `1.2.3` is the toolchain version named by `<toolchain>` (e.g., `msrv` ->
36+
`1.56.0`).
37+
38+
### Toolchains
39+
40+
The `<toolchain>` argument is mandatory:
41+
- `msrv`: Minimum Supported Rust Version.
42+
- `stable`: Stable toolchain.
43+
- `nightly`: Nightly toolchain.
44+
- `all`: Runs on `msrv`, `stable`, and `nightly` sequentially.
45+
- Version-gated: e.g., `no-zerocopy-core-error-1-81-0` (see `Cargo.toml`).
46+
47+
48+
## MSRV (Minimum Supported Rust Version)
49+
50+
The MSRV is **1.56.0**.
51+
52+
- **Do NOT** use features stabilized after 1.56.0 unless version-gated.
53+
- **Requirement:** Ask for user approval before introducing new version-gated
54+
behavior.
55+
- **Verify**: Ensure code compiles on 1.56.0 (`./cargo.sh +msrv ...`).
56+
57+
### Version Gating Convention
58+
59+
We use `[package.metadata.build-rs]` in `Cargo.toml` to gate features by Rust version.
60+
61+
1. **Define**: Add `no-zerocopy-<feature>-<version> = "<version>"` to `Cargo.toml`.
62+
2. **Use**: Use `#[cfg(not(no_zerocopy_<feature>_<version>))]` (note underscores).
63+
3. **Document**: For public items, use `#[cfg_attr(doc_cfg, doc(cfg(rust = "<version>")))]`.
64+
65+
**Important:** The toolchains listed in `.github/workflows/ci.yml` and
66+
`Cargo.toml` (under `[package.metadata.build-rs]`) must be kept in sync. If you
67+
add a new version-gated feature, ensure it is reflected in both places.
68+
69+
## UI Tests
70+
71+
For advice on how to add, modify, or remove UI tests (in `tests/ui-*` or
72+
`zerocopy-derive/tests/ui-*`), refer to [agent_docs/ui_tests.md](./ui_tests.md).
73+
74+
## Macro Development
75+
76+
- **Shared Logic:** Put shared macro logic in `src/util/macro_util.rs` to avoid
77+
code duplication in generated code.
78+
- **Lints:** Generated code often triggers lints. Use `#[allow(...)]` liberally
79+
in generated code to suppress them.
80+
```rust
81+
// GOOD: Suppress lints that might be triggered by generated names.
82+
// Example: Using a variant name (PascalCase) as a field name (snake_case).
83+
// Input: `enum MyEnum { VariantA }`
84+
// Generated: `union Variants { __field_VariantA: ... }`
85+
quote! {
86+
#[allow(non_snake_case)]
87+
union ___ZerocopyVariants {
88+
#(#fields)*
89+
}
90+
}
91+
```
92+
93+
## Unsafe Code
94+
95+
`unsafe` code is extremely dangerous and should be avoided unless absolutely
96+
necessary. For guidelines on writing unsafe code, including pointer casts and
97+
safety comments, refer to [agent_docs/unsafe_code.md](./unsafe_code.md).

agent_docs/style.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<!-- Copyright 2025 The Fuchsia Authors
2+
3+
Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
4+
<LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
5+
license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6+
This file may not be copied, modified, or distributed except according to
7+
those terms. -->
8+
9+
# Style Guidelines
10+
11+
This document covers code style and formatting guidelines for the project, as
12+
well as commit message requirements.
13+
14+
## File Headers
15+
16+
Each file must contain a copyright header (see `src/lib.rs` for example) which is
17+
based on that file's creation year.
18+
19+
## Formatting
20+
21+
Refer to `ci/check_fmt.sh`.
22+
23+
## Comments
24+
25+
- Wrap all comments (`//`, `///`, `//!`) at **80 columns** from the left margin,
26+
taking into account any preceding code or comments.
27+
- **Exceptions:** Markdown tables, ASCII diagrams, long URLs, code blocks, or
28+
other cases where wrapping would impair readability.
29+
30+
## Markdown Files
31+
32+
- Wrap paragraphs and bulleted lists at **80 columns** from the left margin,
33+
taking into account any preceding code or comments. For example, a markdown
34+
block inside of a `/// Lorem ipsum...` comment should have lines no more than
35+
76 columns wide.
36+
- In bulleted lists, indent subsequent lines by 2 spaces.
37+
- Do not wrap links if it breaks them.
38+
- Always put a blank line between a section header and the beginning of the section.
39+
40+
## Pull Requests and Commit Messages
41+
42+
Use GitHub issue syntax in commit messages:
43+
44+
- Resolves issue: `Closes #123`
45+
- Progress on issue: `Makes progress on #123`

0 commit comments

Comments
 (0)