Skip to content

Misleading diagnostic output for typecheck failures that involve type inference #132165

Open
@Stevie-O

Description

@Stevie-O

Code

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=e5cc14f0aef315131a9e430f0ff34b06

Summarized:

  • The input is a vector of schedule events: vec[x] contains the start time and end time for event x, and a target event number
  • Whenever an event begins, the lowest-numbered resource must be allocated to that event
  • The output is the ID number of the resource allocated to the target event
  • My implementation used two BinaryHeaps, one to track allocated resources, and a freelist to track available resources
  • The first heap's item type is (Reverse(end_time), resource_id), so the heap is ordered by time-of-release ascending (so pop()/peek() refer to the next event that will end)
  • The second heap's item type is Reverse(resource_id) so that pop yields the lowest-numbered resource
  • A missing Reverse() when pushing onto the second heap caused the first heap's type to incorrectly inferred
  • This causes a typecheck failure on a correct insert into the first heap
  • The diagnostic hint explaining the first heap's type inference points to a statement that could not have possibly contributed to type inference

Current output

error[E0308]: mismatched types
   --> main.rs:58:30
    |
33  |                             departures.pop();
    |                             ---------- here the type of `departures` is inferred to be `BinaryHeap<(Reverse<_>, Reverse<i32>)>`
...
58  |             departures.push( dep_item );
    |                        ----  ^^^^^^^^ expected `(Reverse<_>, Reverse<i32>)`, found `(Reverse<i32>, i32)`
    |                        |
    |                        arguments to this method are incorrect
    |
    = note: expected tuple `(Reverse<_>, Reverse<i32>)`
               found tuple `(Reverse<i32>, i32)`
note: method defined here
   --> C:\Users\Stevie-O\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\alloc\src\collections\binary_heap\mod.rs:616:12
    |
616 |     pub fn push(&mut self, item: T) {
    |            ^^^^

Desired output

error[E0308]: mismatched types
   --> main.rs:58:30
    |
29  |                    Some( &(Reverse(dt), seat_num) )
    |                           ----------------------- here the type of `departures` is inferred to be `BinaryHeap<(Reverse<_>, Reverse<i32>)>`

Rationale and extra context

I don't really know exactly what it should say, but I'm quite certain that it shouldn't say that the type of departures was inferred from the departures.pop() call, a statement from which virtually zero type information can be inferred.

If I could get anything I wanted plus a pony, it would have wanted it to point me to line 29, which is where I'm pretty sure that the actual type inference came from line 29:

Some( &(Reverse(dt), seat_num) )

And then point out that seat_num is a Reverse<i32> because of line 34:

free_seats.push(seat_num); // <- NOTE the missing Reverse() around seat_num

Getting all of that seems rather impractical; however, I expect that if it had told me that the second tuple element was inferred to be a Reverse<> from the match pattern, I would have spent a less time looking for the real bug, which was the erroneous statement above.

Other cases

No response

Rust Version

rustc 1.82.0 (f6e511e 2024-10-15)
binary: rustc
commit-hash: f6e511e
commit-date: 2024-10-15
host: x86_64-pc-windows-msvc
release: 1.82.0
LLVM version: 19.1.1

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-inferenceArea: Type inferenceD-confusingDiagnostics: Confusing error or lint that should be reworked.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions