]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/infer/anon_types/mod.rs
Remove Ty prefix from Ty{Adt|Array|Slice|RawPtr|Ref|FnDef|FnPtr|Dynamic|Closure|Gener...
[rust.git] / src / librustc / infer / anon_types / mod.rs
index 5e731871e2851e1497dc6c58d56355335ff52e78..96c64c05ccfbd9418868d5d1e8dbdf9d54a9976f 100644 (file)
@@ -592,7 +592,7 @@ fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
 
     fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
         match ty.sty {
-            ty::TyClosure(def_id, substs) => {
+            ty::Closure(def_id, substs) => {
                 // I am a horrible monster and I pray for death. When
                 // we encounter a closure here, it is always a closure
                 // from within the function that we are currently
@@ -653,8 +653,9 @@ fn instantiate_anon_types_in_map<T: TypeFoldable<'tcx>>(&mut self, value: &T) ->
         let tcx = self.infcx.tcx;
         value.fold_with(&mut BottomUpFolder {
             tcx,
+            reg_op: |reg| reg,
             fldop: |ty| {
-                if let ty::TyAnon(def_id, substs) = ty.sty {
+                if let ty::Anon(def_id, substs) = ty.sty {
                     // Check that this is `impl Trait` type is
                     // declared by `parent_def_id` -- i.e., one whose
                     // value we are inferring.  At present, this is
@@ -678,7 +679,7 @@ fn instantiate_anon_types_in_map<T: TypeFoldable<'tcx>>(&mut self, value: &T) ->
                     // ```
                     //
                     // Here, the return type of `foo` references a
-                    // `TyAnon` indeed, but not one whose value is
+                    // `Anon` indeed, but not one whose value is
                     // presently being inferred. You can get into a
                     // similar situation with closure return types
                     // today:
@@ -690,38 +691,51 @@ fn instantiate_anon_types_in_map<T: TypeFoldable<'tcx>>(&mut self, value: &T) ->
                     // }
                     // ```
                     if let Some(anon_node_id) = tcx.hir.as_local_node_id(def_id) {
-                        let anon_parent_def_id = match tcx.hir.expect_item(anon_node_id).node {
-                            // impl trait
-                            hir::ItemKind::Existential(hir::ExistTy {
-                                impl_trait_fn: Some(parent),
-                                ..
-                            }) => parent,
-                            // named existential types
-                            hir::ItemKind::Existential(hir::ExistTy {
-                                impl_trait_fn: None,
-                                ..
-                            }) if may_define_existential_type(
-                                tcx,
-                                self.parent_def_id,
-                                anon_node_id,
-                            ) => {
-                                return self.fold_anon_ty(ty, def_id, substs);
+                        let parent_def_id = self.parent_def_id;
+                        let def_scope_default = || {
+                            let anon_parent_node_id = tcx.hir.get_parent(anon_node_id);
+                            parent_def_id == tcx.hir.local_def_id(anon_parent_node_id)
+                        };
+                        let in_definition_scope = match tcx.hir.find(anon_node_id) {
+                            Some(hir::map::NodeItem(item)) => match item.node {
+                                // impl trait
+                                hir::ItemKind::Existential(hir::ExistTy {
+                                    impl_trait_fn: Some(parent),
+                                    ..
+                                }) => parent == self.parent_def_id,
+                                // named existential types
+                                hir::ItemKind::Existential(hir::ExistTy {
+                                    impl_trait_fn: None,
+                                    ..
+                                }) => may_define_existential_type(
+                                    tcx,
+                                    self.parent_def_id,
+                                    anon_node_id,
+                                ),
+                                _ => def_scope_default(),
                             },
-                            _ => {
-                                let anon_parent_node_id = tcx.hir.get_parent(anon_node_id);
-                                tcx.hir.local_def_id(anon_parent_node_id)
+                            Some(hir::map::NodeImplItem(item)) => match item.node {
+                                hir::ImplItemKind::Existential(_) => may_define_existential_type(
+                                    tcx,
+                                    self.parent_def_id,
+                                    anon_node_id,
+                                ),
+                                _ => def_scope_default(),
                             },
+                            _ => bug!(
+                                "expected (impl) item, found {}",
+                                tcx.hir.node_to_string(anon_node_id),
+                            ),
                         };
-                        if self.parent_def_id == anon_parent_def_id {
+                        if in_definition_scope {
                             return self.fold_anon_ty(ty, def_id, substs);
                         }
 
                         debug!(
                             "instantiate_anon_types_in_map: \
-                             encountered anon with wrong parent \
-                             def_id={:?} \
-                             anon_parent_def_id={:?}",
-                            def_id, anon_parent_def_id
+                             encountered anon outside it's definition scope \
+                             def_id={:?}",
+                            def_id,
                         );
                     }
                 }
@@ -741,11 +755,11 @@ fn fold_anon_ty(
         let tcx = infcx.tcx;
 
         debug!(
-            "instantiate_anon_types: TyAnon(def_id={:?}, substs={:?})",
+            "instantiate_anon_types: Anon(def_id={:?}, substs={:?})",
             def_id, substs
         );
 
-        // Use the same type variable if the exact same TyAnon appears more
+        // Use the same type variable if the exact same Anon appears more
         // than once in the return type (e.g. if it's passed to a type alias).
         if let Some(anon_defn) = self.anon_types.get(&def_id) {
             return anon_defn.concrete_ty;
@@ -791,7 +805,7 @@ fn fold_anon_ty(
 
         for predicate in bounds.predicates {
             // Change the predicate to refer to the type variable,
-            // which will be the concrete type, instead of the TyAnon.
+            // which will be the concrete type, instead of the Anon.
             // This also instantiates nested `impl Trait`.
             let predicate = self.instantiate_anon_types_in_map(&predicate);
 
@@ -808,6 +822,23 @@ fn fold_anon_ty(
 }
 
 /// Whether `anon_node_id` is a sibling or a child of a sibling of `def_id`
+///
+/// ```rust
+/// pub mod foo {
+///     pub mod bar {
+///         pub existential type Baz;
+///
+///         fn f1() -> Baz { .. }
+///     }
+///
+///     fn f2() -> bar::Baz { .. }
+/// }
+/// ```
+///
+/// Here, `def_id` will be the `DefId` of the existential type `Baz`.
+/// `anon_node_id` is the `NodeId` of the reference to Baz -- so either the return type of f1 or f2.
+/// We will return true if the reference is within the same module as the existential type
+/// So true for f1, false for f2.
 pub fn may_define_existential_type(
     tcx: TyCtxt,
     def_id: DefId,