diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 1a2b76485f359..036e31d655f61 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -1634,7 +1634,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { if field_idx == i { Some(&projs[1..]) } else { None } } else { - unreachable!(); + // Non-field projections are unexpected here but + // can occur with associated type projections. + // Filter them out rather than panicking. + None } }) .collect(); @@ -1667,7 +1670,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { if field_idx.index() == i { Some(&projs[1..]) } else { None } } else { - unreachable!(); + // Non-field projections are unexpected here but + // can occur with associated type projections. + None } }) .collect(); @@ -1681,8 +1686,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) } - // Anything else would be completely captured and therefore handled already. - _ => unreachable!(), + // For associated type projections (ty::Alias) and any other unhandled + // type kinds, conservatively assume no significant drop outside of captures. + // This avoids ICEs while maintaining correct behavior for the migration lint. + _ => false, } } diff --git a/tests/ui/closures/upvar-associated-type-ice.rs b/tests/ui/closures/upvar-associated-type-ice.rs new file mode 100644 index 0000000000000..a64782314b369 --- /dev/null +++ b/tests/ui/closures/upvar-associated-type-ice.rs @@ -0,0 +1,34 @@ +// Regression test for #152205: ICE in upvar.rs with associated type projections +// +// The closure capture migration analysis hit `unreachable!()` when +// encountering associated type projections in closure captures. + +//@ check-pass +//@ edition:2021 + +#![deny(rust_2021_incompatible_closure_captures)] + +struct Foo; +struct S; + +impl Drop for S { + fn drop(&mut self) {} +} + +struct U(::Assoc); + +fn test_precise_analysis_long_path(u: U) { + let _ = || { + let _x = u.0.0; + }; +} + +trait NewTrait { + type Assoc; +} + +impl NewTrait for Foo { + type Assoc = (S,); +} + +fn main() {}