maintainability-agent docs
Languages

Rust

A method belongs to the type its impl block names. Rust splits data from behaviour — struct Store holds the fields, impl Store holds the methods, often far apart and sometimes in another file — so get alone is not an instruction in a tree with eleven of them. A method inside impl Store reports as Store::get, and impl Display for Widget reports its members under Widget, because the type is what a reader searches for and the trait is how it behaves.

That is the same problem Swift's extensions posed and it is solved the same way, with a pass over the block spans. Go needed none of it: a Go receiver is written on the method itself.

An impl block is not graded, exactly as a Swift extension is not. It is a container, and measuring it as well as its methods counts the same lines twice. A trait is graded — it is a declaration in its own right — and it also qualifies its default implementations, so Reader::describe rather than describe.

A bodyless fn mints nothing. A trait requirement is a signature with nothing to maintain, as a C prototype and a Swift protocol requirement are.

Attributes are stripped, not matched. #[derive(Clone)] is a name followed by a parenthesised list — the shape of a signature — and Java's annotations forced the same treatment.

What it misses, all under-reporting rather than over:

Measured with Rust's own keywords. Branches are counted on match arms rather than on the match keyword — counting both would score the construct and its first arm, which is the select case lesson Fortran taught. The wildcard _ => is a default and is not counted: it always matches, so it adds a path without a decision to reach it.

loop is not counted either. It has no condition; the if … break inside it is what decides.

? is counted. It was excluded at first on the reasoning that it "propagates an error and decides nothing", by analogy with JavaScript's optional chaining. The analogy is false, and the grammar settles it: let x = f()? either continues or returns early, and the operator expands to a match with two arms. Two paths, one decision. That idiomatic Rust is full of them is a fact about Rust, not a reason to under-count it (D118).