Skip to content

Conversation

@ShoyuVanilla
Copy link
Member

@ShoyuVanilla ShoyuVanilla commented Nov 12, 2025

Fixes #148192

The ICE comes from the following line, calling normalize_erasing_regions to a projection type whose trait bound is not met:

pub(crate) fn variant_sub_tys(
&self,
ty: RevealedTy<'tcx>,
variant: &'tcx VariantDef,
) -> impl Iterator<Item = (&'tcx FieldDef, RevealedTy<'tcx>)> {
let ty::Adt(_, args) = ty.kind() else { bug!() };
variant.fields.iter().map(move |field| {
let ty = field.ty(self.tcx, args);
// `field.ty()` doesn't normalize after instantiating.
let ty = self.tcx.normalize_erasing_regions(self.typing_env, ty);

The above function is called while trying to lint missing match arms, or scrutinize ctors of missing(not necessary error) match arms.

So, the following code can trigger ICEs.

trait WhereTrait {
    type Type;
}

fn foo(e: Enum) {
    match e {
        Enum::Map(_) => (), // ICE, while trying to lint missing arms
    }

    if let Enum::Map(_) = e {} // ICE, while trying to scrutinize missing ctors (even worse)
}

enum Enum {
    Map(()),
    Map2(<() as WhereTrait>::Type),
}

This ICE won't be triggered with the following code, as this is filtered out before check_match as the existence of ill-formed type inside the variant marks the body as tainted by error in hir_typeck, but for the above code, the hir_typeck complains nothing because everything it sees is locally correct.

fn foo(e: Enum) {
    match e {
        Enum::Map2(_) => (), // No ICE
    }
}

I've considered visiting and wf checking for the match scrutinee before entering check_match, but that might regress the perf and I think just emitting delayed bug would enough as the normalization failure would be originated by other errors like ill-formdness.

@rustbot
Copy link
Collaborator

rustbot commented Nov 12, 2025

Some changes occurred in exhaustiveness checking

cc @Nadrieril

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 12, 2025
@rustbot
Copy link
Collaborator

rustbot commented Nov 12, 2025

r? @chenyukang

rustbot has assigned @chenyukang.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@chenyukang
Copy link
Member

Thanks!
@bors r=chenyukang

@bors
Copy link
Collaborator

bors commented Nov 13, 2025

📌 Commit dae003b has been approved by chenyukang

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 13, 2025
bors added a commit that referenced this pull request Nov 13, 2025
Rollup of 7 pull requests

Successful merges:

 - #147701 (rustdoc: don't ignore path distance for doc aliases)
 - #148735 (Fix ICE caused by invalid spans for shrink_file)
 - #148839 (fix rtsan_nonblocking_async lint closure ICE)
 - #148846 (add a test for combining RPIT with explicit tail calls)
 - #148872 (fix: Do not ICE when missing match arm with ill-formed subty is met)
 - #148880 (Remove explicit install of `eslint` inside of `tidy`'s Dockerfile)
 - #148883 (bootstrap: dont require cmake if local-rebuild is enabled)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 17c25e4 into rust-lang:main Nov 13, 2025
11 checks passed
@rustbot rustbot added this to the 1.93.0 milestone Nov 13, 2025
rust-timer added a commit that referenced this pull request Nov 13, 2025
Rollup merge of #148872 - ShoyuVanilla:issue-148192, r=chenyukang

fix: Do not ICE when missing match arm with ill-formed subty is met

Fixes #148192

The ICE comes from the following line, calling `normalize_erasing_regions` to a projection type whose trait bound is not met:
https://github.com/rust-lang/rust/blob/2fcbda6c1a70606bdb09857e01d01fc6229da712/compiler/rustc_pattern_analysis/src/rustc.rs#L185-L194

The above function is called while trying to lint missing match arms, or scrutinize ctors of missing(not necessary error) match arms.

So, the following code can trigger ICEs.
```rust
trait WhereTrait {
    type Type;
}

fn foo(e: Enum) {
    match e {
        Enum::Map(_) => (), // ICE, while trying to lint missing arms
    }

    if let Enum::Map(_) = e {} // ICE, while trying to scrutinize missing ctors (even worse)
}

enum Enum {
    Map(()),
    Map2(<() as WhereTrait>::Type),
}
```

This ICE won't be triggered with the following code, as this is filtered out before `check_match` as the existence of ill-formed type inside the variant marks the body as tainted by error in `hir_typeck`, but for the above code, the `hir_typeck` complains nothing because everything it sees is locally correct.

```rust
fn foo(e: Enum) {
    match e {
        Enum::Map2(_) => (), // No ICE
    }
}
```

I've considered visiting and wf checking for the match scrutinee before entering `check_match`, but that might regress the perf and I think just emitting delayed bug would enough as the normalization failure would be originated by other errors like ill-formdness.
@ShoyuVanilla ShoyuVanilla deleted the issue-148192 branch November 14, 2025 05:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ICE: Failed to normalize std::option::Option<Alias(Projection, AliasTy

4 participants