Clippy lints / Restriction
Clippy lint · Restriction · checked with Clippy 0.1.99
clippy::arbitrary_source_item_ordering: incorrect ordering of items (must be alphabetically ordered)
What it meansConfirms that items are sorted in source files as per configuration. It is in the restriction group and off by default.
What you see
warning: incorrect ordering of items (must be alphabetically ordered) --> main.rs:6:11 | 6 | const B: bool; | ^ | note: should be placed before `C` --> main.rs:5:11 | 5 | const C: bool; | ^ = help: for further information visit https://rust-lang.github.io/rust-clippy/stable/index.html#arbitrary_source_item_ordering = note: requested on the command line with `-W clippy::arbitrary-source-item-ordering`
Real output of Clippy 0.1.99 (Rust 1.99) on the example below. Names and line numbers in yours will differ.
Does it matter?
Keeping a consistent ordering throughout the codebase helps with working as a team, and possibly improves maintainability of the codebase. The idea is that by defining a consistent and enforceable rule for how source files are structured, less time will be wasted during reviews on a topic that is (under most circumstances) not relevant to the logic implemented in the code. Sometimes this will be referred to as “bikeshedding”. The content of items with a representation clause attribute, such as #[repr(C)] will not be checked, as the order of their fields or variants might be dictated by an external API (application binary interface).
Lints that forbid language features for specific codebases (no unwrap, no indexing...). Off by default; pick them one by one, never the whole group.
How to fix it
Clippy does not fix this one automatically. Change the code by hand:
Flagged
trait TraitUnordered {
const A: bool;
const C: bool;
const B: bool;
type SomeType;
fn a();
fn c();
fn b();
}
Write this instead
trait TraitOrdered {
const A: bool;
const B: bool;
const C: bool;
type SomeType;
fn a();
fn b();
fn c();
}
Turn it off, or on
It is off by default. To use it, set it to warn or deny:
Whole crate (Cargo.toml)
[lints.clippy]
arbitrary_source_item_ordering = "warn"In code
#![warn(clippy::arbitrary_source_item_ordering)]One run
cargo clippy -- -W clippy::arbitrary-source-item-orderingThe [lints] table needs Rust 1.74 or newer. In a workspace, put it under [workspace.lints.clippy] and add [lints] workspace = true to each member.
Settings in clippy.toml
module-item-order-groupings: The named groupings of different source item kinds within modules.module-items-ordered-within-groupings: Whether the items within module groups should be ordered alphabetically or not.source-item-ordering: Which kind of elements should be ordered internally, possible values being enum, impl, module, struct, trait.trait-assoc-item-kinds-order: The order of associated items in traits.trait-impl-item-order: The required ordering of associated items in trait impls: purely alphabetical, following the trait definition order, or accepting either.
Clippy's own documentation
What it does
Confirms that items are sorted in source files as per configuration.
Why restrict this?
Keeping a consistent ordering throughout the codebase helps with working as a team, and possibly improves maintainability of the codebase. The idea is that by defining a consistent and enforceable rule for how source files are structured, less time will be wasted during reviews on a topic that is (under most circumstances) not relevant to the logic implemented in the code. Sometimes this will be referred to as “bikeshedding”.
The content of items with a representation clause attribute, such as
#[repr(C)] will not be checked, as the order of their fields or
variants might be dictated by an external API (application binary
interface).
Default Ordering and Configuration
As there is no generally applicable rule, and each project may have different requirements, the lint can be configured with high granularity. The configuration is split into two stages:
- Which item kinds that should have an internal order enforced.
- Individual ordering rules per item kind.
The item kinds that can be linted are:
- Module (with customized groupings, alphabetical within - configurable)
- Trait (with customized order of associated items, alphabetical within)
- Enum, Impl, Struct (purely alphabetical)
Module Item Order
Due to the large variation of items within modules, the ordering can be configured on a very granular level. Item kinds can be grouped together arbitrarily, items within groups will be ordered alphabetically. The following table shows the default groupings:
| Group | Item Kinds |
|---|---|
modules | “mod”, “foreign_mod” |
use | “use” |
macros | “macro” |
global_asm | “global_asm” |
UPPER_SNAKE_CASE | “static”, “const” |
PascalCase | “ty_alias”, “opaque_ty”, “enum”, “struct”, “union”, “trait”, “trait_alias”, “impl” |
lower_snake_case | “fn” |
The groups’ names are arbitrary and can be changed to suit the conventions that should be enforced for a specific project.
All item kinds must be accounted for to create an enforceable linting rule set. Following are some example configurations that may be useful.
Example: module inclusions and use statements to be at the top
module-item-order-groupings = [
[ "modules", [ "extern_crate", "mod", "foreign_mod" ], ],
[ "use", [ "use", ], ],
[ "everything_else", [ "macro", "global_asm", "static", "const", "ty_alias", "enum", "struct", "union", "trait", "trait_alias", "impl", "fn", ], ],
]
Example: only consts and statics should be alphabetically ordered
It is also possible to configure a selection of module item groups that should be ordered alphabetically. This may be useful if for example statics and consts should be ordered, but the rest should be left open.
module-items-ordered-within-groupings = ["UPPER_SNAKE_CASE"]
Known Problems
Performance Impact
Keep in mind, that ordering source code alphabetically can lead to reduced performance in cases where the most commonly used enum variant isn’t the first entry anymore, and similar optimizations that can reduce branch misses, cache locality and such. Either don’t use this lint if that’s relevant, or disable the lint in modules or items specifically where it matters. Other solutions can be to use profile guided optimization (PGO), post-link optimization (e.g. using BOLT for LLVM), or other advanced optimization methods. A good starting point to dig into optimization is cargo-pgo.
Lints on a Contains basis
The lint can be disabled only on a “contains” basis, but not per element within a “container”, e.g. the lint works per-module, per-struct, per-enum, etc. but not for “don’t order this particular enum variant”.
Module documentation
Module level rustdoc comments are not part of the resulting syntax tree
and as such cannot be linted from within check_mod. Instead, the
rustdoc::missing_documentation lint may be used.
Module Tests
This lint does not implement detection of module tests (or other feature
dependent elements for that matter). To lint the location of mod tests,
the lint items_after_test_module can be used instead.
Example
trait TraitUnordered {
const A: bool;
const C: bool;
const B: bool;
type SomeType;
fn a();
fn c();
fn b();
}
Use instead:
trait TraitOrdered {
const A: bool;
const B: bool;
const C: bool;
type SomeType;
fn a();
fn b();
fn c();
}
Configuration
-
module-item-order-groupings: The named groupings of different source item kinds within modules.(default:
[["modules", ["extern_crate", "mod", "foreign_mod"]], ["use", ["use"]], ["macros", ["macro"]], ["global_asm", ["global_asm"]], ["UPPER_SNAKE_CASE", ["static", "const"]], ["PascalCase", ["ty_alias", "enum", "struct", "union", "trait", "trait_alias", "impl"]], ["lower_snake_case", ["fn"]]]) -
module-items-ordered-within-groupings: Whether the items within module groups should be ordered alphabetically or not.
This option can be configured to “all”, “none”, or a list of specific grouping names that should be checked (e.g. only “enums”).
(default: "none")
-
source-item-ordering: Which kind of elements should be ordered internally, possible values beingenum,impl,module,struct,trait.(default:
["enum", "impl", "module", "struct", "trait"]) -
trait-assoc-item-kinds-order: The order of associated items in traits.(default:
["const", "type", "fn"]) -
trait-impl-item-order: The required ordering of associated items in trait impls: purely alphabetical, following the trait definition order, or accepting either.
Note that the trait definition order may change between versions of the crate defining the trait without being considered a breaking change.
Examples: When using trait definition item ordering:
trait-impl-item-order = "trait_item_ordering"
When using trait definition item ordering and alphabetical for fallbacks:
trait-impl-item-order = "alphabetical_or_trait_item_ordering"
(default: "alphabetical")
From the Clippy lint list (0.1.99), part of the Rust project, MIT or Apache-2.0. Official entry.
Related lints
- unwrap_usedChecks for .unwrap() or .unwrap_err() calls on Results and .unwrap() call on Options
- module_name_repetitionsDetects public item names that are prefixed or suffixed by the containing public module’s name
- expect_usedChecks for .expect() or .expect_err() calls on Results and .expect() call on Options
- alloc_instead_of_coreFinds items imported through alloc when available through core
- allow_attributes#[allow] attribute found
- allow_attributes_without_reason`allow` attribute without specifying a reason
- arithmetic_side_effectsarithmetic operation that can potentially result in unexpected side-effects
- as_conversionsChecks for usage of as conversions. Note that this lint is specialized in linting every single use of as regardless of whether good alternatives exist or not
- as_pointer_underscoreusing inferred pointer cast
All 847 Clippy lints · Rust compiler errors · Cargo.toml checker
Up next
Related lintclippy::unwrap_usedChecks for .unwrap() or .unwrap_err() calls on Results and .unwrap() call on OptionsRead it next →Did this answer your question?