introduce AstConv::probe_adt
This commit is contained in:
parent
d227506683
commit
34329d6f6c
@ -106,9 +106,12 @@ pub trait AstConv<'tcx> {
|
||||
poly_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
) -> Ty<'tcx>;
|
||||
|
||||
fn normalize_ty_2(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
ty
|
||||
}
|
||||
/// Returns `AdtDef` if `ty` is an ADT.
|
||||
/// Note that `ty` might be a projection type that needs normalization.
|
||||
/// This used to get the enum variants in scope of the type.
|
||||
/// For example, `Self::A` could refer to an associated type
|
||||
/// or to an enum variant depending on the result of this function.
|
||||
fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>>;
|
||||
|
||||
/// Invoked when we encounter an error from some prior pass
|
||||
/// (e.g., resolve) that is translated into a ty-error. This is
|
||||
@ -1805,7 +1808,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) = self.normalize_ty_2(span, qself_ty).kind() {
|
||||
if let Some(adt_def) = self.probe_adt(span, qself_ty) {
|
||||
if adt_def.is_enum() {
|
||||
let variant_def = adt_def
|
||||
.variants()
|
||||
@ -1907,6 +1910,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
let Some(assoc_ty_did) = self.lookup_assoc_ty(assoc_ident, hir_ref_id, span, impl_) else {
|
||||
continue;
|
||||
};
|
||||
let ty::Adt(_, adt_substs) = qself_ty.kind() else {
|
||||
// FIXME(inherent_associated_types)
|
||||
bug!("unimplemented: non-adt self of inherent assoc ty");
|
||||
};
|
||||
let item_substs = self.create_substs_for_associated_item(
|
||||
span,
|
||||
assoc_ty_did,
|
||||
@ -2262,6 +2269,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
self_ty: Option<Ty<'tcx>>,
|
||||
kind: DefKind,
|
||||
def_id: DefId,
|
||||
span: Span,
|
||||
) -> Vec<PathSeg> {
|
||||
// We need to extract the type parameters supplied by the user in
|
||||
// the path `path`. Due to the current setup, this is a bit of a
|
||||
@ -2329,8 +2337,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
|
||||
// Case 2. Reference to a variant constructor.
|
||||
DefKind::Ctor(CtorOf::Variant, ..) | DefKind::Variant => {
|
||||
let adt_def = self_ty.map(|t| t.ty_adt_def().unwrap());
|
||||
let (generics_def_id, index) = if let Some(adt_def) = adt_def {
|
||||
let (generics_def_id, index) = if let Some(self_ty) = self_ty {
|
||||
let adt_def = self.probe_adt(span, self_ty).unwrap();
|
||||
debug_assert!(adt_def.is_enum());
|
||||
(adt_def.did(), last)
|
||||
} else if last >= 1 && segments[last - 1].args.is_some() {
|
||||
@ -2426,7 +2434,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
assert_eq!(opt_self_ty, None);
|
||||
|
||||
let path_segs =
|
||||
self.def_ids_for_value_path_segments(path.segments, None, kind, def_id);
|
||||
self.def_ids_for_value_path_segments(path.segments, None, kind, def_id, span);
|
||||
let generic_segs: FxHashSet<_> =
|
||||
path_segs.iter().map(|PathSeg(_, index)| index).collect();
|
||||
self.prohibit_generics(
|
||||
|
@ -505,6 +505,11 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn probe_adt(&self, _span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>> {
|
||||
// FIXME(#103640): Should we handle the case where `ty` is a projection?
|
||||
ty.ty_adt_def()
|
||||
}
|
||||
|
||||
fn set_tainted_by_errors(&self, _: ErrorGuaranteed) {
|
||||
// There's no obvious place to track this, so just let it go.
|
||||
}
|
||||
|
@ -1007,9 +1007,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
Res::Def(kind, def_id) => <dyn AstConv<'_>>::def_ids_for_value_path_segments(
|
||||
self,
|
||||
segments,
|
||||
self_ty.map(|ty| ty.normalized),
|
||||
self_ty.map(|ty| ty.raw),
|
||||
kind,
|
||||
def_id,
|
||||
span,
|
||||
),
|
||||
_ => bug!("instantiate_value_path on {:?}", res),
|
||||
};
|
||||
@ -1122,7 +1123,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
.unwrap_or(false);
|
||||
|
||||
let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
|
||||
let ty = self.normalize_ty_2(span, tcx.at(span).type_of(impl_def_id));
|
||||
let ty = tcx.at(span).type_of(impl_def_id);
|
||||
let ty = self.normalize(span, ty);
|
||||
match *ty.kind() {
|
||||
ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
|
||||
let variant = adt_def.non_enum_variant();
|
||||
@ -1238,10 +1240,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// If we have a default, then we it doesn't matter that we're not
|
||||
// inferring the type arguments: we provide the default where any
|
||||
// is missing.
|
||||
let default = tcx.bound_type_of(param.def_id);
|
||||
self.fcx
|
||||
.normalize_ty_2(self.span, default.subst(tcx, substs.unwrap()))
|
||||
.into()
|
||||
let default =
|
||||
tcx.bound_type_of(param.def_id).subst(tcx, substs.unwrap());
|
||||
self.fcx.normalize(self.span, default).into()
|
||||
} else {
|
||||
// If no type arguments were provided, we have to infer them.
|
||||
// This case also occurs as a result of some malformed input, e.g.
|
||||
|
@ -297,11 +297,14 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
|
||||
self.tcx().mk_projection(item_def_id, item_substs)
|
||||
}
|
||||
|
||||
fn normalize_ty_2(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
if ty.has_escaping_bound_vars() {
|
||||
ty // FIXME: normalization and escaping regions
|
||||
} else {
|
||||
self.normalize(span, ty)
|
||||
fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>> {
|
||||
match ty.kind() {
|
||||
ty::Adt(adt_def, _) => Some(*adt_def),
|
||||
// FIXME(#104767): Should we handle bound regions here?
|
||||
ty::Alias(ty::Projection, _) if !ty.has_escaping_bound_vars() => {
|
||||
self.normalize(span, ty).ty_adt_def()
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -310,7 +313,9 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span) {
|
||||
self.write_ty(hir_id, self.normalize_ty_2(span, ty))
|
||||
// FIXME: normalization and escaping regions
|
||||
let ty = if !ty.has_escaping_bound_vars() { self.normalize(span, ty) } else { ty };
|
||||
self.write_ty(hir_id, ty)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user