Skip to content

fix: Crash when computing diagnostics with MIR and error types#22707

Open
Wilfred wants to merge 2 commits into
rust-lang:masterfrom
Wilfred:mir_crash_projection
Open

fix: Crash when computing diagnostics with MIR and error types#22707
Wilfred wants to merge 2 commits into
rust-lang:masterfrom
Wilfred:mir_crash_projection

Conversation

@Wilfred

@Wilfred Wilfred commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Previously MIR would panic if we tried to access out-of-bounds tuple elements or fields in a value with an error type. This would produce an error of the form:

 field FieldIndex(1) out of range: (i32,)
 can't project out of {type error}
 field FieldIndex(99) out of range: (&'{region error} str, u32)

Instead, handle error types gracefully, and add unit tests.

AI disclosure: Some Fable 5 and GPT 5.5 usage, any errors are of course mine :)

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 2, 2026
@Wilfred

Wilfred commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

This has been the second most common LSP request panic I've seen recently (after #22705).

@ChayimFriedman2 ChayimFriedman2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer this to be done where we build the projection and can also return a lowering error, i.e. in push_field_projection().

View changes since this review

@Wilfred Wilfred force-pushed the mir_crash_projection branch from 34d8146 to 319ddaa Compare July 3, 2026 11:33
@rustbot

This comment has been minimized.

@Wilfred

Wilfred commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

OK, I've pushed the validation into MIR lowering, does this make sense? I've also split the PR into two commits, this is arguably two distinct fixes.

let place_ty = cond_place.ty(&self.result, &self.infcx, self.env).ty;
let mut ocx = ObligationCtxt::new(&self.infcx);
let normalized_ty = ocx
.structurally_normalize_ty(&ObligationCause::dummy(), self.env, place_ty)

@ChayimFriedman2 ChayimFriedman2 Jul 4, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see why we should normalize here. Inference already deeply normalizes at the end, and we already fail lowering if the type isn't a tuple. Do you have a test case where we fail only without normalization?

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, the test on this commit fails prior to this change:

thread 'tests::mir_alias_projection_recovery_does_not_panic' (58661203) panicked at crates/hir-ty/src/mir.rs:1277:22:
can't project out of Alias(AliasTy { args: [#0], kind: Projection { def_id: TypeAliasId("A") }, .. })
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a projection on an alias, something we cannot normalize before monomorphization. It's not normalization that solves this, and it's not the lack of it that causes the problem. The root of the problem is mismatch between the place type and the pattern type.

The code has a type error; we should not try to lower MIR for such code, but unfortunately that's something we do today. Still, no normalization is needed: just fetching the place type is enough.

Comment thread crates/ide-diagnostics/src/tests.rs Outdated
Wilfred added 2 commits July 8, 2026 14:39
Projection assumes the tuple is big enough for the field access, so
return a MIR lowering error earlier if the tuple isn't valid.

AI disclosure: Some Fable 5 and GPT 5.5 usage.
Ensure we normalise the type first, so projection always gets a valid tuple. Previously we panicked with:

    can't project out of Alias(AliasTy { kind: Projection { def_id: TypeAliasId("A") }, .. })

AI disclosure: Some Fable 5 and GPT 5.5 usage.
@Wilfred Wilfred force-pushed the mir_crash_projection branch from 319ddaa to 4632e79 Compare July 8, 2026 13:42
@rustbot

rustbot commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.

3 participants