Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

sorted-derives

Level: warn · Fixed by rabot fmt · Article: Sorting

What it checks

The list inside #[derive(..)] is alphabetical, with one documented exception: a derive follows the trait it extends. Eq comes right after PartialEq, Ord right after PartialOrd, Copy right after Clone. Reading Eq, PartialEq backwards is what alphabetical order alone would give you, and nobody writes it that way.

Don’t

#![allow(unused)]
fn main() {
#[derive(Serialize, Debug, Eq, Clone, PartialEq, Ord, PartialOrd, Copy, Hash)]
struct UserId(Uuid);
}

Do

#![allow(unused)]
fn main() {
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize)]
struct UserId(Uuid);
}

Options

Pin derives to a position, in the manner of cargo-sort-derives: names before "..." come first in that order, names after it come last, and the rest sit in between under the rule above. Matching is on the last path segment, so serde::Serialize and Serialize are the same pin.

[sorting]
derive-order = ["Debug", "Clone", "Copy", "...", "Serialize", "Deserialize"]

With that setting the example becomes #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize)].

Silence it

#![allow(unused)]
fn main() {
// rabot: allow(sorted-derives) the proc macro must see Builder before Default
#[derive(Builder, Default)]
}