Unnamed repository; edit this file 'description' to name the repository.
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 https://github.com/rust-lang/rust/pull/155767.
| -rw-r--r-- | crates/hir-ty/src/infer/closure/analysis.rs | 13 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs | 1 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/unify.rs | 2 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/closure_captures.rs | 17 |
4 files changed, 23 insertions, 10 deletions
diff --git a/crates/hir-ty/src/infer/closure/analysis.rs b/crates/hir-ty/src/infer/closure/analysis.rs index 82ace17ac0..5ea43bc03c 100644 --- a/crates/hir-ty/src/infer/closure/analysis.rs +++ b/crates/hir-ty/src/infer/closure/analysis.rs @@ -920,8 +920,8 @@ impl<'a, 'db> InferenceContext<'a, 'db> { self.result.closures_data.insert(closure_def_id, closure_data); } - fn normalize_capture_place(&self, span: Span, place: Place) -> Place { - let mut place = self.infcx().resolve_vars_if_possible(place); + fn normalize_capture_place(&mut self, span: Span, place: Place) -> Place { + let place = self.infcx().resolve_vars_if_possible(place); // In the new solver, types in HIR `Place`s can contain unnormalized aliases, // which can ICE later (e.g. when projecting fields for diagnostics). @@ -945,11 +945,8 @@ impl<'a, 'db> InferenceContext<'a, 'db> { } normalized } - Err(_errors) => { - place.base_ty = self.types.types.error.store(); - for proj in &mut place.projections { - proj.ty = self.types.types.error.store(); - } + Err(errors) => { + self.table.trait_errors.extend(errors); place } } @@ -1002,7 +999,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { } } - fn place_for_root_variable(&self, closure_def_id: ExprId, var_hir_id: BindingId) -> Place { + fn place_for_root_variable(&mut self, closure_def_id: ExprId, var_hir_id: BindingId) -> Place { let place = Place { base_ty: self.result.binding_ty(var_hir_id).store(), base: PlaceBase::Upvar { closure: closure_def_id, var_id: var_hir_id }, diff --git a/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs b/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs index f76e99aa78..deafff6b43 100644 --- a/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs +++ b/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs @@ -475,7 +475,6 @@ impl<'a, 'b, 'db, D: Delegate<'db>> ExprUseVisitor<'a, 'b, 'db, D> { Ok(()) } - // FIXME: It's suspicious that this is public; clippy should probably use `walk_expr`. #[instrument(skip(self), level = "debug")] pub(crate) fn consume_expr(&mut self, expr: ExprId) -> Result { let place_with_id = self.cat_expr(expr)?; diff --git a/crates/hir-ty/src/infer/unify.rs b/crates/hir-ty/src/infer/unify.rs index 33311412bf..8527b42d78 100644 --- a/crates/hir-ty/src/infer/unify.rs +++ b/crates/hir-ty/src/infer/unify.rs @@ -134,7 +134,7 @@ pub(crate) struct InferenceTable<'db> { pub(crate) infer_ctxt: InferCtxt<'db>, pub(super) fulfillment_cx: FulfillmentCtxt<'db>, pub(super) diverging_type_vars: FxHashSet<Ty<'db>>, - trait_errors: Vec<NextSolverError<'db>>, + pub(super) trait_errors: Vec<NextSolverError<'db>>, } impl<'db> InferenceTable<'db> { diff --git a/crates/hir-ty/src/tests/closure_captures.rs b/crates/hir-ty/src/tests/closure_captures.rs index b01f44acbc..d60cf83909 100644 --- a/crates/hir-ty/src/tests/closure_captures.rs +++ b/crates/hir-ty/src/tests/closure_captures.rs @@ -600,3 +600,20 @@ fn f() { expect!["77..110;46..47;96..97 ByRef(Immutable) b &'<erased> i32"], ); } + +#[test] +fn fail_to_normalize_place() { + check_closure_captures( + r#" +//- minicore: index, slice +const FAIL_CONST: usize = loop {}; +struct Foo { + arr: [i32; FAIL_CONST], +} +fn foo(foo: &Foo) { + || { return foo.arr[0] }; +} + "#, + expect!["102..126;85..88;114..117 ByRef(Immutable) *foo &'<erased> Foo"], + ); +} |