Skip to content

← Orientation and the Gate step 2 of 6

Easy Primitives

How to read a rustc error message

Return the sum of the integers in items. An empty slice sums to 0. Inputs in this exercise keep all intermediate sums within the i32 range.

pub fn tally(items: &[i32]) -> i32

For example, [1, 2, 3] returns 6, and [-5, 5] returns 0.

The starter deliberately contains four compilation problems. Use the diagnostics to understand each one, then simplify the implementation.

Read the message in context

Start with the error headline, then follow the file location and underlined expressions. A diagnostic may highlight both the expression with the wrong type and the declaration that establishes the expected type. Read any notes and suggestions before editing; a suggested change still needs to fit what your function is meant to do.

For the starter's return "nothing to tally", the important details are:

Detail What it tells you
E0308: mismatched types An expression has a different type from the one required.
Expected i32 The function's return type requires an integer.
Found &str The returned string literal is not an integer.

This table summarizes the diagnostic rather than reproducing its exact formatting. Run rustc --explain E0308 for examples of that error code.

Four problems to identify

Index type (E0277). The range 0..items.len() already gives usize indices. Casting i to i32 makes it unsuitable for indexing a single slice element. Use items[i], or avoid indices by iterating over the elements. Slices also accept range indices, such as items[0..2], to select a subslice. More generally, E0277 means a required trait implementation is missing.

Return type (E0308). A function returning i32 cannot return a string. Here the scratch vector and its conditional return are unnecessary: the result should come from the input integers. The same error code can appear when branches produce incompatible types or a trailing semicolon changes an intended return expression into a statement.

Missing type information (E0282). Neither Vec::new() nor a call to scratch.len() determines the vector's element type. If the vector were useful, let scratch: Vec<i32> = Vec::new(); would supply that information. Other uses, such as passing it to a function expecting Vec<i32>, could supply it too. This task needs no scratch vector, so removing it also removes the inference problem.

Immutable accumulator (E0384). let total = 0 creates an immutable binding. Reassigning it in the loop requires let mut total = 0. You can also use an iterator operation that returns the sum directly.

Recompile after a focused change

One error can prevent the compiler from reporting another. The messages you see depend on your edits and compiler version; the error count is not a count of all mistakes in the source.

One repair path is to remove the index cast and replace the string return with an integer. Recompiling can then expose the vector's missing type. After addressing that, the immutable accumulator still needs attention. Another path is to remove the unused scratch vector and its branch first. Both are useful ways to narrow down what is wrong.

Finish with the behavior and the lint gate

Compiling is only part of the task. Check the examples, including the empty slice, and address Clippy warnings because the exercise treats them as errors. For a loop, iterate over values directly and use += to accumulate. Alternatively, items.iter().sum() expresses the whole operation; the function's return type tells Rust which sum type is needed.