Skip to content

Commit 52dcd8b

Browse files
authored
Merge pull request #20980 from ShoyuVanilla/shallow-normalize
fix: Remove some deep normalizations from infer
2 parents b533f95 + d5ea170 commit 52dcd8b

File tree

3 files changed

+93
-18
lines changed

3 files changed

+93
-18
lines changed

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ impl<'db> CastCheck<'db> {
110110
&mut self,
111111
ctx: &mut InferenceContext<'_, 'db>,
112112
) -> Result<(), InferenceDiagnostic<'db>> {
113-
self.expr_ty = ctx.table.eagerly_normalize_and_resolve_shallow_in(self.expr_ty);
114-
self.cast_ty = ctx.table.eagerly_normalize_and_resolve_shallow_in(self.cast_ty);
113+
self.expr_ty = ctx.table.try_structurally_resolve_type(self.expr_ty);
114+
self.cast_ty = ctx.table.try_structurally_resolve_type(self.cast_ty);
115115

116116
// This should always come first so that we apply the coercion, which impacts infer vars.
117117
if ctx
@@ -159,7 +159,7 @@ impl<'db> CastCheck<'db> {
159159
TyKind::FnDef(..) => {
160160
let sig =
161161
self.expr_ty.callable_sig(ctx.interner()).expect("FnDef had no sig");
162-
let sig = ctx.table.eagerly_normalize_and_resolve_shallow_in(sig);
162+
let sig = ctx.table.normalize_associated_types_in(sig);
163163
let fn_ptr = Ty::new_fn_ptr(ctx.interner(), sig);
164164
if ctx
165165
.coerce(
@@ -191,7 +191,7 @@ impl<'db> CastCheck<'db> {
191191
},
192192
// array-ptr-cast
193193
CastTy::Ptr(t, m) => {
194-
let t = ctx.table.eagerly_normalize_and_resolve_shallow_in(t);
194+
let t = ctx.table.try_structurally_resolve_type(t);
195195
if !ctx.table.is_sized(t) {
196196
return Err(CastError::IllegalCast);
197197
}
@@ -375,7 +375,7 @@ fn pointer_kind<'db>(
375375
ty: Ty<'db>,
376376
ctx: &mut InferenceContext<'_, 'db>,
377377
) -> Result<Option<PointerKind<'db>>, ()> {
378-
let ty = ctx.table.eagerly_normalize_and_resolve_shallow_in(ty);
378+
let ty = ctx.table.try_structurally_resolve_type(ty);
379379

380380
if ctx.table.is_sized(ty) {
381381
return Ok(Some(PointerKind::Thin));

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

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -284,17 +284,6 @@ impl<'db> InferenceTable<'db> {
284284
self.at(&ObligationCause::new()).deeply_normalize(ty.clone()).unwrap_or(ty)
285285
}
286286

287-
/// Works almost same as [`Self::normalize_associated_types_in`], but this also resolves shallow
288-
/// the inference variables
289-
pub(crate) fn eagerly_normalize_and_resolve_shallow_in<T>(&mut self, ty: T) -> T
290-
where
291-
T: TypeFoldable<DbInterner<'db>>,
292-
{
293-
let ty = self.resolve_vars_with_obligations(ty);
294-
let ty = self.normalize_associated_types_in(ty);
295-
self.resolve_vars_with_obligations(ty)
296-
}
297-
298287
pub(crate) fn normalize_alias_ty(&mut self, alias: Ty<'db>) -> Ty<'db> {
299288
self.infer_ctxt
300289
.at(&ObligationCause::new(), self.trait_env.env)
@@ -651,7 +640,7 @@ impl<'db> InferenceTable<'db> {
651640
}
652641

653642
let mut ty = ty;
654-
ty = self.eagerly_normalize_and_resolve_shallow_in(ty);
643+
ty = self.try_structurally_resolve_type(ty);
655644
if let Some(sized) = short_circuit_trivial_tys(ty) {
656645
return sized;
657646
}
@@ -673,7 +662,7 @@ impl<'db> InferenceTable<'db> {
673662
// Structs can have DST as its last field and such cases are not handled
674663
// as unsized by the chalk, so we do this manually.
675664
ty = last_field_ty;
676-
ty = self.eagerly_normalize_and_resolve_shallow_in(ty);
665+
ty = self.try_structurally_resolve_type(ty);
677666
if let Some(sized) = short_circuit_trivial_tys(ty) {
678667
return sized;
679668
}

crates/hir-ty/src/tests/regression/new_solver.rs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,5 +605,91 @@ impl SimpleModel for ExampleData {
605605
}
606606
}
607607
"#,
608+
)
609+
}
610+
611+
#[test]
612+
fn regression_20975() {
613+
check_infer(
614+
r#"
615+
//- minicore: future, iterators, range
616+
use core::future::Future;
617+
618+
struct Foo<T>(T);
619+
620+
trait X {}
621+
622+
impl X for i32 {}
623+
impl X for i64 {}
624+
625+
impl<T: X> Iterator for Foo<T> {
626+
type Item = T;
627+
fn next(&mut self) -> Option<Self::Item> {
628+
self.next_spec()
629+
}
630+
}
631+
632+
trait Bar {
633+
type Item;
634+
635+
fn next_spec(&mut self) -> Option<Self::Item>;
636+
}
637+
638+
impl<T: X> Bar for Foo<T> {
639+
type Item = T;
640+
641+
fn next_spec(&mut self) -> Option<Self::Item> {
642+
None
643+
}
644+
}
645+
646+
struct JoinAll<F>
647+
where
648+
F: Future,
649+
{
650+
f: F,
651+
}
652+
653+
fn join_all<I>(iter: I) -> JoinAll<<I as IntoIterator>::Item>
654+
where
655+
I: IntoIterator,
656+
<I as IntoIterator>::Item: Future,
657+
{
658+
loop {}
659+
}
660+
661+
fn main() {
662+
let x = Foo(42).filter_map(|_| Some(async {}));
663+
join_all(x);
664+
}
665+
"#,
666+
expect![[r#"
667+
164..168 'self': &'? mut Foo<T>
668+
192..224 '{ ... }': Option<T>
669+
202..206 'self': &'? mut Foo<T>
670+
202..218 'self.n...spec()': Option<T>
671+
278..282 'self': &'? mut Self
672+
380..384 'self': &'? mut Foo<T>
673+
408..428 '{ ... }': Option<T>
674+
418..422 'None': Option<T>
675+
501..505 'iter': I
676+
614..629 '{ loop {} }': JoinAll<impl Future>
677+
620..627 'loop {}': !
678+
625..627 '{}': ()
679+
641..713 '{ ...(x); }': ()
680+
651..652 'x': FilterMap<Foo<i32>, impl FnMut(i32) -> Option<impl Future<Output = ()>>>
681+
655..658 'Foo': fn Foo<i32>(i32) -> Foo<i32>
682+
655..662 'Foo(42)': Foo<i32>
683+
655..693 'Foo(42...c {}))': FilterMap<Foo<i32>, impl FnMut(i32) -> Option<impl Future<Output = ()>>>
684+
659..661 '42': i32
685+
674..692 '|_| So...nc {})': impl FnMut(i32) -> Option<impl Future<Output = ()>>
686+
675..676 '_': i32
687+
678..682 'Some': fn Some<impl Future<Output = ()>>(impl Future<Output = ()>) -> Option<impl Future<Output = ()>>
688+
678..692 'Some(async {})': Option<impl Future<Output = ()>>
689+
683..691 'async {}': impl Future<Output = ()>
690+
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>
691+
699..710 'join_all(x)': JoinAll<impl Future<Output = ()>>
692+
708..709 'x': FilterMap<Foo<i32>, impl FnMut(i32) -> Option<impl Future<Output = ()>>>
693+
"#]],
608694
);
609695
}

0 commit comments

Comments
 (0)