Skip to content

Error output regression: spurious integer inference error that only occurs if another error occurs #93450

Closed
@chris-morgan

Description

@chris-morgan

I was just going through my FizzBuzz article as I do every year or so to update compiler error messages and make any related changes necessary, and came across a regression in error output for Figure 3.

Given the following code:

fn main() {
for i in 1..101 {
    let result = if i % 15 == 0 {
        "FizzBuzz"
    } else if i % 5 == 0 {
        "Buzz"
    } else if i % 3 == 0 {
        "Fizz"
    } else {
        i.to_string()
    };
    println!("{}", result);
}
}

This is the output in 1.57.0 (and it’s been just the one error that we now call E0308 right from the outset):

$ rustc +1.57.0 x.rs
error[E0308]: `if` and `else` have incompatible types
  --> x.rs:10:9
   |
7  |       } else if i % 3 == 0 {
   |  ____________-
8  | |         "Fizz"
   | |         ------ expected because of this
9  | |     } else {
10 | |         i.to_string()
   | |         ^^^^^^^^^^^^^ expected `&str`, found struct `String`
11 | |     };
   | |_____- `if` and `else` have incompatible types

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.

But the output in 1.58.0 and in currently nightly adds another error, E0283:

$ rustc +1.58.0 x.rs
error[E0308]: `if` and `else` have incompatible types
  --> x.rs:10:9
   |
7  |       } else if i % 3 == 0 {
   |  ____________-
8  | |         "Fizz"
   | |         ------ expected because of this
9  | |     } else {
10 | |         i.to_string()
   | |         ^^^^^^^^^^^^^ expected `&str`, found struct `String`
11 | |     };
   | |_____- `if` and `else` have incompatible types

error[E0283]: type annotations needed for `{integer}`
  --> x.rs:10:11
   |
2  | for i in 1..101 {
   |          ------ the element type for this iterator is not specified
...
10 |         i.to_string()
   |           ^^^^^^^^^ cannot infer type for type `{integer}`
   |
   = note: multiple `impl`s satisfying `{integer}: ToString` found in the `alloc` crate:
           - impl ToString for i8;
           - impl ToString for u8;

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0283, E0308.
For more information about an error, try `rustc --explain E0283`.

The integer type inference error is spurious, because if you resolve the if/else type mismatch (e.g. tack on .to_string() on the other branches), it also vanishes (resolved to the default of i32, I presume).

Metadata

Metadata

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsP-mediumMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions