Skip to content

← Orientation and the Gate step 3 of 6

Easy Primitives

Naming conventions and the style gate

Return the sum of a slice and how many elements it had.

pub fn summarize_scores(raw_scores: &[i32]) -> (i32, usize)

The starter is functionally correct. Every test passes. It still fails, four times over, and this problem exists so that it fails here — while you are expecting it — rather than in the middle of item 2.7 when you are trying to think about ownership.

Four rustc lints that are errors on this site

These are rustc‘s own lints, not clippy’s, and -D warnings promotes all of them to hard errors.

non_snake_case. Rust’s naming convention is not advisory; it ships as a lint. Variables and functions are snake_case; types, traits and enum variants are UpperCamelCase; constants and statics are SCREAMING_SNAKE_CASE. A binding called TotalSum looks to the compiler like you were trying to name a type, so it warns. There is a related clippy lint, upper_case_acronyms, that pushes struct HTTPResponse to HttpResponse — the convention treats an acronym as one word.

unused_variables. A binding you never read is either a leftover or a bug, and Rust makes you say which. If it is deliberate, prefix the name with an underscore: _score_limit. That underscore is a real part of the language, not a trick — it means “yes, I meant to ignore this.”

unused_mut. You wrote let mut x and never mutated x. Defensive mut is a habit imported from languages where mutability is free; here it is noise that misleads the next reader about your intent.

dead_code. A private function nobody calls. In a real crate this catches code you forgot to delete after a refactor; here it catches the helper you wrote before you found the standard-library method that did it for you. This one is genuine friction — it is not your mistake if it fires while you are experimenting — but it is the rule on this site, so it is better met now.

The habit worth building

Fixing lints one at a time by silencing them is a losing game. The real fix in this problem is to notice that the entire body — accumulator, counter, loop — is two standard-library calls, and that once you write those, three of the four lints have nothing left to complain about. Lints are usually a signal that the code is doing work the library already does.

Two things to know for the rest of the course:

  • #[allow(dead_code)] on an item silences a lint locally. It is a legitimate tool, and it is also the wrong first instinct — try deleting the code first.
  • #[expect(dead_code)] is the sharper version: it silences the lint and warns you if the lint stops firing, so the annotation cannot rot. Prefer it when you really do need a suppression.

The return type

(i32, usize) is a tuple — Rust’s lightweight way to return two values without inventing a struct. usize is the type of a length or an index; it is as wide as a pointer, which is 8 bytes on the machines that grade this. Item 1.18 covers tuples properly and item 1.3 covers usize; for now you only need to know that .len() already hands you a usize, so no conversion is needed.