]> git.lizzy.rs Git - rust.git/commitdiff
introduce AstConv::probe_adt
authorAli MJ Al-Nasrawy <alimjalnasrawy@gmail.com>
Sat, 29 Oct 2022 13:19:57 +0000 (16:19 +0300)
committerAli MJ Al-Nasrawy <alimjalnasrawy@gmail.com>
Sat, 7 Jan 2023 10:38:38 +0000 (13:38 +0300)
compiler/rustc_hir_analysis/src/astconv/mod.rs
compiler/rustc_hir_analysis/src/collect.rs
compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

index bcb695cc8e3c2ad52ae12e7d067b8c6b9b567e4b..df6600626a30bd73f473d9fa62f9d041ca9de726 100644 (file)
@@ -106,9 +106,12 @@ fn projected_ty_from_poly_trait_ref(
         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 @@ pub fn associated_path_to_ty(
 
         // 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 @@ pub fn associated_path_to_ty(
                 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 @@ pub fn def_ids_for_value_path_segments(
         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 @@ pub fn def_ids_for_value_path_segments(
 
             // 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 @@ pub fn res_to_ty(
                 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(
index fd54aec480ab61a67e0e2d291f173479da1be7f3..b7f259668a1e48f005761958a12947e6986d77ea 100644 (file)
@@ -505,6 +505,11 @@ fn projected_ty_from_poly_trait_ref(
         }
     }
 
+    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.
     }
index 3e05f67b74bc8844935f5dc76f2d479b94e7b89d..6c2dfaf4413be48fe0bf554f4705f831ec1cc9ff 100644 (file)
@@ -1007,9 +1007,10 @@ pub fn instantiate_value_path(
             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 @@ pub fn instantiate_value_path(
             .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 @@ fn inferred_kind(
                             // 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.
index d7e53a0aa04771b9ab9d1dce83cac89a63ad7fa1..6347b9a69a0077906a78c12b1f1cce0be753ba85 100644 (file)
@@ -297,11 +297,14 @@ fn projected_ty_from_poly_trait_ref(
         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 @@ fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
     }
 
     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)
     }
 }