Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #20980 from ShoyuVanilla/shallow-normalize
fix: Remove some deep normalizations from infer
Shoyu Vanilla (Flint) 5 months ago
parent b533f95 · parent d5ea170 · commit 52dcd8b
-rw-r--r--crates/hir-ty/src/infer/cast.rs10
-rw-r--r--crates/hir-ty/src/infer/unify.rs15
-rw-r--r--crates/hir-ty/src/tests/regression/new_solver.rs86
3 files changed, 93 insertions, 18 deletions
diff --git a/crates/hir-ty/src/infer/cast.rs b/crates/hir-ty/src/infer/cast.rs
index 8b657dcb88..00a1dfff6d 100644
--- a/crates/hir-ty/src/infer/cast.rs
+++ b/crates/hir-ty/src/infer/cast.rs
@@ -110,8 +110,8 @@ impl<'db> CastCheck<'db> {
&mut self,
ctx: &mut InferenceContext<'_, 'db>,
) -> Result<(), InferenceDiagnostic<'db>> {
- self.expr_ty = ctx.table.eagerly_normalize_and_resolve_shallow_in(self.expr_ty);
- self.cast_ty = ctx.table.eagerly_normalize_and_resolve_shallow_in(self.cast_ty);
+ self.expr_ty = ctx.table.try_structurally_resolve_type(self.expr_ty);
+ self.cast_ty = ctx.table.try_structurally_resolve_type(self.cast_ty);
// This should always come first so that we apply the coercion, which impacts infer vars.
if ctx
@@ -159,7 +159,7 @@ impl<'db> CastCheck<'db> {
TyKind::FnDef(..) => {
let sig =
self.expr_ty.callable_sig(ctx.interner()).expect("FnDef had no sig");
- let sig = ctx.table.eagerly_normalize_and_resolve_shallow_in(sig);
+ let sig = ctx.table.normalize_associated_types_in(sig);
let fn_ptr = Ty::new_fn_ptr(ctx.interner(), sig);
if ctx
.coerce(
@@ -191,7 +191,7 @@ impl<'db> CastCheck<'db> {
},
// array-ptr-cast
CastTy::Ptr(t, m) => {
- let t = ctx.table.eagerly_normalize_and_resolve_shallow_in(t);
+ let t = ctx.table.try_structurally_resolve_type(t);
if !ctx.table.is_sized(t) {
return Err(CastError::IllegalCast);
}
@@ -375,7 +375,7 @@ fn pointer_kind<'db>(
ty: Ty<'db>,
ctx: &mut InferenceContext<'_, 'db>,
) -> Result<Option<PointerKind<'db>>, ()> {
- let ty = ctx.table.eagerly_normalize_and_resolve_shallow_in(ty);
+ let ty = ctx.table.try_structurally_resolve_type(ty);
if ctx.table.is_sized(ty) {
return Ok(Some(PointerKind::Thin));
diff --git a/crates/hir-ty/src/infer/unify.rs b/crates/hir-ty/src/infer/unify.rs
index fb195d4568..5bb71bc503 100644
--- a/crates/hir-ty/src/infer/unify.rs
+++ b/crates/hir-ty/src/infer/unify.rs
@@ -284,17 +284,6 @@ impl<'db> InferenceTable<'db> {
self.at(&ObligationCause::new()).deeply_normalize(ty.clone()).unwrap_or(ty)
}
- /// Works almost same as [`Self::normalize_associated_types_in`], but this also resolves shallow
- /// the inference variables
- pub(crate) fn eagerly_normalize_and_resolve_shallow_in<T>(&mut self, ty: T) -> T
- where
- T: TypeFoldable<DbInterner<'db>>,
- {
- let ty = self.resolve_vars_with_obligations(ty);
- let ty = self.normalize_associated_types_in(ty);
- self.resolve_vars_with_obligations(ty)
- }
-
pub(crate) fn normalize_alias_ty(&mut self, alias: Ty<'db>) -> Ty<'db> {
self.infer_ctxt
.at(&ObligationCause::new(), self.trait_env.env)
@@ -651,7 +640,7 @@ impl<'db> InferenceTable<'db> {
}
let mut ty = ty;
- ty = self.eagerly_normalize_and_resolve_shallow_in(ty);
+ ty = self.try_structurally_resolve_type(ty);
if let Some(sized) = short_circuit_trivial_tys(ty) {
return sized;
}
@@ -673,7 +662,7 @@ impl<'db> InferenceTable<'db> {
// Structs can have DST as its last field and such cases are not handled
// as unsized by the chalk, so we do this manually.
ty = last_field_ty;
- ty = self.eagerly_normalize_and_resolve_shallow_in(ty);
+ ty = self.try_structurally_resolve_type(ty);
if let Some(sized) = short_circuit_trivial_tys(ty) {
return sized;
}
diff --git a/crates/hir-ty/src/tests/regression/new_solver.rs b/crates/hir-ty/src/tests/regression/new_solver.rs
index 18509c5284..5c1f85cb2a 100644
--- a/crates/hir-ty/src/tests/regression/new_solver.rs
+++ b/crates/hir-ty/src/tests/regression/new_solver.rs
@@ -605,5 +605,91 @@ impl SimpleModel for ExampleData {
}
}
"#,
+ )
+}
+
+#[test]
+fn regression_20975() {
+ check_infer(
+ r#"
+//- minicore: future, iterators, range
+use core::future::Future;
+
+struct Foo<T>(T);
+
+trait X {}
+
+impl X for i32 {}
+impl X for i64 {}
+
+impl<T: X> Iterator for Foo<T> {
+ type Item = T;
+ fn next(&mut self) -> Option<Self::Item> {
+ self.next_spec()
+ }
+}
+
+trait Bar {
+ type Item;
+
+ fn next_spec(&mut self) -> Option<Self::Item>;
+}
+
+impl<T: X> Bar for Foo<T> {
+ type Item = T;
+
+ fn next_spec(&mut self) -> Option<Self::Item> {
+ None
+ }
+}
+
+struct JoinAll<F>
+where
+ F: Future,
+{
+ f: F,
+}
+
+fn join_all<I>(iter: I) -> JoinAll<<I as IntoIterator>::Item>
+where
+ I: IntoIterator,
+ <I as IntoIterator>::Item: Future,
+{
+ loop {}
+}
+
+fn main() {
+ let x = Foo(42).filter_map(|_| Some(async {}));
+ join_all(x);
+}
+"#,
+ expect![[r#"
+ 164..168 'self': &'? mut Foo<T>
+ 192..224 '{ ... }': Option<T>
+ 202..206 'self': &'? mut Foo<T>
+ 202..218 'self.n...spec()': Option<T>
+ 278..282 'self': &'? mut Self
+ 380..384 'self': &'? mut Foo<T>
+ 408..428 '{ ... }': Option<T>
+ 418..422 'None': Option<T>
+ 501..505 'iter': I
+ 614..629 '{ loop {} }': JoinAll<impl Future>
+ 620..627 'loop {}': !
+ 625..627 '{}': ()
+ 641..713 '{ ...(x); }': ()
+ 651..652 'x': FilterMap<Foo<i32>, impl FnMut(i32) -> Option<impl Future<Output = ()>>>
+ 655..658 'Foo': fn Foo<i32>(i32) -> Foo<i32>
+ 655..662 'Foo(42)': Foo<i32>
+ 655..693 'Foo(42...c {}))': FilterMap<Foo<i32>, impl FnMut(i32) -> Option<impl Future<Output = ()>>>
+ 659..661 '42': i32
+ 674..692 '|_| So...nc {})': impl FnMut(i32) -> Option<impl Future<Output = ()>>
+ 675..676 '_': i32
+ 678..682 'Some': fn Some<impl Future<Output = ()>>(impl Future<Output = ()>) -> Option<impl Future<Output = ()>>
+ 678..692 'Some(async {})': Option<impl Future<Output = ()>>
+ 683..691 'async {}': impl Future<Output = ()>
+ 699..707 'join_all': fn join_all<FilterMap<Foo<i32>, impl FnMut(i32) -> Option<impl Future<Output = ()>>>>(FilterMap<Foo<i32>, impl FnMut(i32) -> Option<impl Future<Output = ()>>>) -> JoinAll<<FilterMap<Foo<i32>, impl FnMut(i32) -> Option<impl Future<Output = ()>>> as IntoIterator>::Item>
+ 699..710 'join_all(x)': JoinAll<impl Future<Output = ()>>
+ 708..709 'x': FilterMap<Foo<i32>, impl FnMut(i32) -> Option<impl Future<Output = ()>>>
+ "#]],
);
}