Coding Guidelines
This section describes coding and collaboration conventions for the Asterinas project. These guidelines aim to keep code clear, consistent, maintainable, correct, and efficient.
For the underlying philosophy, principles, and quality criteria for individual guidelines, see How Guidelines Are Written.
The guidelines are organized into the following pages:
- General Guidelines — Language-agnostic guidance for naming, comments, layout, formatting, and API design.
- Rust Guidelines — Rust-specific guidance for naming, language items, and cross-cutting topics.
- Git Guidelines — Commit hygiene and pull-request conventions.
- Testing Guidelines — Test behavior, assertions, regression policy, and cleanup.
- Assembly Guidelines —
.Sandglobal_asm!conventions for sectioning, function metadata, labels, and alignment.
The guidelines represent the desired state of the codebase. If you find conflicting cases in the codebase, you are welcome to fix the code to match the guidelines.
Index
| Category | Guideline | Short Name |
|---|---|---|
| General | Be descriptive | descriptive-names |
| General | Be accurate | accurate-names |
| General | Encode units and important attributes in names | encode-units |
| General | Use assertion-style boolean names | bool-names |
| General | Prefer semantic line breaks | semantic-line-breaks |
| General | Explain why, not what | explain-why |
| General | Document design decisions | design-decisions |
| General | Cite specifications and algorithm sources | cite-sources |
| General | One concept per file | one-concept-per-file |
| General | Organize code for top-down reading | top-down-reading |
| General | Group statements into logical paragraphs | logical-paragraphs |
| General | Format error messages consistently | error-message-format |
| General | Stick to familiar conventions | familiar-conventions |
| General | Hide implementation details | hide-impl-details |
| General | Validate at boundaries, trust internally | validate-at-boundaries |
| Rust | Follow Rust CamelCase and acronym capitalization | camel-case-acronyms |
| Rust | End closure variables with _fn | closure-fn-suffix |
| Rust | Introduce explaining variables | explain-variables |
| Rust | Use block expressions to scope temporary state | block-expressions |
| Rust | Use checked or saturating arithmetic | checked-arithmetic |
| Rust | Minimize nesting | minimize-nesting |
| Rust | Keep functions small and focused | small-functions |
| Rust | Avoid boolean arguments | no-bool-args |
| Rust | Use types to enforce invariants | rust-type-invariants |
| Rust | Prefer enum over trait objects for closed sets | enum-over-dyn |
| Rust | Encapsulate fields behind getters | getter-encapsulation |
| Rust | Follow RFC 1574 summary line conventions | rfc1574-summary |
| Rust | End sentence comments with punctuation | comment-punctuation |
| Rust | Wrap identifiers in backticks | backtick-identifiers |
| Rust | Do not disclose implementation details in doc comments | no-impl-in-docs |
| Rust | Add module-level documentation for major components | module-docs |
| Rust | Justify every use of unsafe | justify-unsafe-use |
| Rust | Document safety conditions | document-safety-conds |
| Rust | Deny unsafe code in kernel/ | deny-unsafe-kernel |
| Rust | Reason about safety at the module boundary | module-boundary-safety |
| Rust | Default to the narrowest visibility | narrow-visibility |
| Rust | Use workspace dependencies | workspace-deps |
| Rust | Suppress lints at the narrowest scope | narrow-lint-suppression |
| Rust | Use #[expect(dead_code)] with restraint | expect-dead-code |
| Rust | Prefer functions over macros | macros-as-last-resort |
| Rust | Establish and enforce a consistent lock order | lock-ordering |
| Rust | Never do I/O or blocking operations while holding a spinlock | no-io-under-spinlock |
| Rust | Do not use atomics casually | careful-atomics |
| Rust | Critical sections must not be split across lock boundaries | atomic-critical-sections |
| Rust | Use debug_assert for correctness-only checks | debug-assert |
| Rust | Propagate errors with ? | propagate-errors |
| Rust | Use log crate macros exclusively | log-crate-only |
| Rust | Choose appropriate log levels | log-levels |
| Rust | Use RAII for all resource acquisition and release | raii |
| Rust | Avoid O(n) algorithms on hot paths | no-linear-hot-paths |
| Rust | Minimize unnecessary copies and allocations | minimize-copies |
| Rust | No premature optimization without evidence | no-premature-optimization |
| Git | Write imperative, descriptive subject lines | imperative-subject |
| Git | One logical change per commit | atomic-commits |
| Git | Separate refactoring from features | refactor-then-feature |
| Git | Keep pull requests focused | focused-prs |
| Testing | Add regression tests for every bug fix | add-regression-tests |
| Testing | Test user-visible behavior, not internals | test-visible-behavior |
| Testing | Use assertion macros, not manual inspection | use-assertions |
| Testing | Clean up resources after every test | test-cleanup |
| Assembly | Use the correct section directive | asm-section-directives |
| Assembly | Place code-width directives after the section definition | asm-code-width |
| Assembly | Place attributes directly before the function | asm-function-attributes |
| Assembly | Add .type and .size for Rust-callable functions | asm-type-and-size |
| Assembly | Use unique label prefixes to avoid name clashes | asm-label-prefixes |
| Assembly | Prefer .balign over .align | asm-prefer-balign |