Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions compiler/rustc_hir_typeck/src/upvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand All @@ -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,
}
}

Expand Down
34 changes: 34 additions & 0 deletions tests/ui/closures/upvar-associated-type-ice.rs
Original file line number Diff line number Diff line change
@@ -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(<Foo as NewTrait>::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() {}