Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #22319 from ChayimFriedman2/closure-normalize
fix: Do not replace closure capture place types with errors if they fail to normalize
Shoyu Vanilla (Flint) 7 days ago
parent 6dbcc9b · parent 56b7416 · commit ecc571a
-rw-r--r--crates/hir-ty/src/infer/closure/analysis.rs13
-rw-r--r--crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs1
-rw-r--r--crates/hir-ty/src/infer/unify.rs2
-rw-r--r--crates/hir-ty/src/tests/closure_captures.rs17
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"],
+ );
+}