Merge pull request #20980 from ShoyuVanilla/shallow-normalize
fix: Remove some deep normalizations from infer
This commit is contained in:
commit
c4b8917db3
3 changed files with 93 additions and 18 deletions
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 = ()>>>
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue