don't normalize in astconv

We delay projection normalization to further stages in order to
register user type annotations before normalization in HIR typeck.

There are two consumers of astconv: ItemCtxt and FnCtxt.
The former already expects unnormalized types from astconv, see its
AstConv trait impl.
The latter needs `RawTy` for a cleaner interface.

Unfortunately astconv still needs the normalization machinery in
order to resolve enum variants that have projections in the self type,
e.g. `<<T as Trait>::Assoc>::StructVariant {}`.
This is why `AstConv::normalize_ty_2` is necessary.
This commit is contained in:
Ali MJ Al-Nasrawy 2022-09-17 21:35:47 +03:00
parent 93bf84c902
commit d227506683
25 changed files with 376 additions and 257 deletions

View file

@ -106,11 +106,9 @@ pub trait AstConv<'tcx> {
poly_trait_ref: ty::PolyTraitRef<'tcx>,
) -> Ty<'tcx>;
/// Normalize an associated type coming from the user.
///
/// This should only be used by astconv. Use `FnCtxt::normalize`
/// or `ObligationCtxt::normalize` in downstream crates.
fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>;
fn normalize_ty_2(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
ty
}
/// Invoked when we encounter an error from some prior pass
/// (e.g., resolve) that is translated into a ty-error. This is
@ -485,14 +483,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// Avoid ICE #86756 when type error recovery goes awry.
return tcx.ty_error().into();
}
self.astconv
.normalize_ty(
self.span,
tcx.at(self.span)
.bound_type_of(param.def_id)
.subst(tcx, substs),
)
.into()
tcx.at(self.span).bound_type_of(param.def_id).subst(tcx, substs).into()
} else if infer_args {
self.astconv.ty_infer(Some(param), self.span).into()
} else {
@ -1254,7 +1245,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
item_segment: &hir::PathSegment<'_>,
) -> Ty<'tcx> {
let substs = self.ast_path_substs_for_ty(span, did, item_segment);
self.normalize_ty(span, self.tcx().at(span).bound_type_of(did).subst(self.tcx(), substs))
self.tcx().at(span).bound_type_of(did).subst(self.tcx(), substs)
}
fn conv_object_ty_poly_trait_ref(
@ -1786,7 +1777,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
Ok(bound)
}
// Create a type from a path to an associated type.
// Create a type from a path to an associated type or to an enum variant.
// For a path `A::B::C::D`, `qself_ty` and `qself_def` are the type and def for `A::B::C`
// and item_segment is the path segment for `D`. We return a type and a def for
// the whole path.
@ -1814,7 +1805,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// Check if we have an enum variant.
let mut variant_resolution = None;
if let ty::Adt(adt_def, adt_substs) = qself_ty.kind() {
if let ty::Adt(adt_def, adt_substs) = self.normalize_ty_2(span, qself_ty).kind() {
if adt_def.is_enum() {
let variant_def = adt_def
.variants()
@ -1923,7 +1914,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
adt_substs,
);
let ty = tcx.bound_type_of(assoc_ty_did).subst(tcx, item_substs);
let ty = self.normalize_ty(span, ty);
return Ok((ty, DefKind::AssocTy, assoc_ty_did));
}
}
@ -2020,7 +2010,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
};
let ty = self.projected_ty_from_poly_trait_ref(span, assoc_ty_did, assoc_segment, bound);
let ty = self.normalize_ty(span, ty);
if let Some(variant_def_id) = variant_resolution {
tcx.struct_span_lint_hir(
@ -2156,7 +2145,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
debug!("qpath_to_ty: trait_ref={:?}", trait_ref);
self.normalize_ty(span, tcx.mk_projection(item_def_id, item_substs))
tcx.mk_projection(item_def_id, item_substs)
}
pub fn prohibit_generics<'a>(
@ -2417,7 +2406,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
err.note("`impl Trait` types can't have type parameters");
});
let substs = self.ast_path_substs_for_ty(span, did, item_segment.0);
self.normalize_ty(span, tcx.mk_opaque(did, substs))
tcx.mk_opaque(did, substs)
}
Res::Def(
DefKind::Enum
@ -2577,7 +2566,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
tcx.ty_error_with_guaranteed(err.emit())
} else {
self.normalize_ty(span, ty)
ty
}
}
Res::Def(DefKind::AssocTy, def_id) => {
@ -2720,8 +2709,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
None,
ty::BoundConstness::NotConst,
);
EarlyBinder(self.normalize_ty(span, tcx.at(span).type_of(def_id)))
.subst(tcx, substs)
EarlyBinder(tcx.at(span).type_of(def_id)).subst(tcx, substs)
}
hir::TyKind::Array(ref ty, ref length) => {
let length = match length {
@ -2731,8 +2719,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
};
let array_ty = tcx.mk_ty(ty::Array(self.ast_ty_to_ty(ty), length));
self.normalize_ty(ast_ty.span, array_ty)
tcx.mk_ty(ty::Array(self.ast_ty_to_ty(ty), length))
}
hir::TyKind::Typeof(ref e) => {
let ty_erased = tcx.type_of(e.def_id);