introduce AstConv::probe_adt

This commit is contained in:
Ali MJ Al-Nasrawy 2022-10-29 16:19:57 +03:00
parent d227506683
commit 34329d6f6c
4 changed files with 38 additions and 19 deletions

View file

@ -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(

View file

@ -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.
}