Skip to content

Commit 56b7416

Browse files
Do not replace closure capture place types with errors if they fail to normalize
This prevents panics, and we need to get rid of this normalization anyway, see rust-lang/rust#155767.
1 parent e26f9ee commit 56b7416

4 files changed

Lines changed: 23 additions & 10 deletions

File tree

crates/hir-ty/src/infer/closure/analysis.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -920,8 +920,8 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
920920
self.result.closures_data.insert(closure_def_id, closure_data);
921921
}
922922

923-
fn normalize_capture_place(&self, span: Span, place: Place) -> Place {
924-
let mut place = self.infcx().resolve_vars_if_possible(place);
923+
fn normalize_capture_place(&mut self, span: Span, place: Place) -> Place {
924+
let place = self.infcx().resolve_vars_if_possible(place);
925925

926926
// In the new solver, types in HIR `Place`s can contain unnormalized aliases,
927927
// which can ICE later (e.g. when projecting fields for diagnostics).
@@ -945,11 +945,8 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
945945
}
946946
normalized
947947
}
948-
Err(_errors) => {
949-
place.base_ty = self.types.types.error.store();
950-
for proj in &mut place.projections {
951-
proj.ty = self.types.types.error.store();
952-
}
948+
Err(errors) => {
949+
self.table.trait_errors.extend(errors);
953950
place
954951
}
955952
}
@@ -1002,7 +999,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
1002999
}
10031000
}
10041001

1005-
fn place_for_root_variable(&self, closure_def_id: ExprId, var_hir_id: BindingId) -> Place {
1002+
fn place_for_root_variable(&mut self, closure_def_id: ExprId, var_hir_id: BindingId) -> Place {
10061003
let place = Place {
10071004
base_ty: self.result.binding_ty(var_hir_id).store(),
10081005
base: PlaceBase::Upvar { closure: closure_def_id, var_id: var_hir_id },

crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,6 @@ impl<'a, 'b, 'db, D: Delegate<'db>> ExprUseVisitor<'a, 'b, 'db, D> {
475475
Ok(())
476476
}
477477

478-
// FIXME: It's suspicious that this is public; clippy should probably use `walk_expr`.
479478
#[instrument(skip(self), level = "debug")]
480479
pub(crate) fn consume_expr(&mut self, expr: ExprId) -> Result {
481480
let place_with_id = self.cat_expr(expr)?;

crates/hir-ty/src/infer/unify.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ pub(crate) struct InferenceTable<'db> {
134134
pub(crate) infer_ctxt: InferCtxt<'db>,
135135
pub(super) fulfillment_cx: FulfillmentCtxt<'db>,
136136
pub(super) diverging_type_vars: FxHashSet<Ty<'db>>,
137-
trait_errors: Vec<NextSolverError<'db>>,
137+
pub(super) trait_errors: Vec<NextSolverError<'db>>,
138138
}
139139

140140
impl<'db> InferenceTable<'db> {

crates/hir-ty/src/tests/closure_captures.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,3 +600,20 @@ fn f() {
600600
expect!["77..110;46..47;96..97 ByRef(Immutable) b &'<erased> i32"],
601601
);
602602
}
603+
604+
#[test]
605+
fn fail_to_normalize_place() {
606+
check_closure_captures(
607+
r#"
608+
//- minicore: index, slice
609+
const FAIL_CONST: usize = loop {};
610+
struct Foo {
611+
arr: [i32; FAIL_CONST],
612+
}
613+
fn foo(foo: &Foo) {
614+
|| { return foo.arr[0] };
615+
}
616+
"#,
617+
expect!["102..126;85..88;114..117 ByRef(Immutable) *foo &'<erased> Foo"],
618+
);
619+
}

0 commit comments

Comments
 (0)