]> git.lizzy.rs Git - rust.git/commitdiff
Generate the `NodeId` for `existential type` in the AST
authorOliver Schneider <github35764891676564198441@oli-obk.de>
Mon, 18 Jun 2018 14:23:13 +0000 (16:23 +0200)
committerOliver Schneider <github35764891676564198441@oli-obk.de>
Wed, 27 Jun 2018 09:17:25 +0000 (11:17 +0200)
src/librustc/hir/lowering.rs
src/librustc_driver/pretty.rs
src/librustc_passes/ast_validation.rs
src/librustc_save_analysis/sig.rs
src/libsyntax/ast.rs
src/libsyntax/fold.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/visit.rs

index 3350b046c97d5fbf1d99e099c2abb8cfb4f932fd..d8d222b9a39f7a55ef93f564689bd6082b6470ba 100644 (file)
@@ -1167,12 +1167,14 @@ fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> P<hir::Ty> {
                 }
                 hir::TyTraitObject(bounds, lifetime_bound)
             }
-            TyKind::ImplTrait(ref bounds) => {
+            TyKind::ImplTrait(exist_ty_node_id, ref bounds) => {
                 let span = t.span;
                 match itctx {
                     ImplTraitContext::Existential(fn_def_id) => {
                         self.lower_existential_impl_trait(
-                            span, fn_def_id, |this| this.lower_param_bounds(bounds, itctx))
+                            span, fn_def_id, exist_ty_node_id,
+                            |this| this.lower_param_bounds(bounds, itctx),
+                        )
                     }
                     ImplTraitContext::Universal(def_id) => {
                         let def_node_id = self.next_id().node_id;
@@ -1240,13 +1242,9 @@ fn lower_existential_impl_trait(
         &mut self,
         span: Span,
         fn_def_id: DefId,
+        exist_ty_node_id: NodeId,
         lower_bounds: impl FnOnce(&mut LoweringContext) -> hir::GenericBounds,
     ) -> hir::Ty_ {
-        // We need to manually repeat the code of `next_id` because the lowering
-        // needs to happen while the owner_id is pointing to the item itself,
-        // because items are their own owners
-        let exist_ty_node_id = self.sess.next_node_id();
-
         // Make sure we know that some funky desugaring has been going on here.
         // This is a first: there is code in other places like for loop
         // desugaring that explicitly states that we don't want to track that.
@@ -1365,18 +1363,18 @@ fn visit_generic_args(&mut self, span: Span, parameters: &'v hir::GenericArgs) {
 
             fn visit_ty(&mut self, t: &'v hir::Ty) {
                 match t.node {
-                // Don't collect elided lifetimes used inside of `fn()` syntax
+                    // Don't collect elided lifetimes used inside of `fn()` syntax
                     hir::Ty_::TyBareFn(_) => {
-                    let old_collect_elided_lifetimes = self.collect_elided_lifetimes;
-                    self.collect_elided_lifetimes = false;
+                        let old_collect_elided_lifetimes = self.collect_elided_lifetimes;
+                        self.collect_elided_lifetimes = false;
 
-                    // Record the "stack height" of `for<'a>` lifetime bindings
-                    // to be able to later fully undo their introduction.
-                    let old_len = self.currently_bound_lifetimes.len();
-                    hir::intravisit::walk_ty(self, t);
-                    self.currently_bound_lifetimes.truncate(old_len);
+                        // Record the "stack height" of `for<'a>` lifetime bindings
+                        // to be able to later fully undo their introduction.
+                        let old_len = self.currently_bound_lifetimes.len();
+                        hir::intravisit::walk_ty(self, t);
+                        self.currently_bound_lifetimes.truncate(old_len);
 
-                    self.collect_elided_lifetimes = old_collect_elided_lifetimes;
+                        self.collect_elided_lifetimes = old_collect_elided_lifetimes;
                     },
                     _ => hir::intravisit::walk_ty(self, t),
                 }
@@ -3093,12 +3091,28 @@ fn lower_item_id(&mut self, i: &Item) -> SmallVector<hir::ItemId> {
             ItemKind::Use(ref use_tree) => {
                 let mut vec = SmallVector::one(hir::ItemId { id: i.id });
                 self.lower_item_id_use_tree(use_tree, i.id, &mut vec);
-                return vec;
+                vec
             }
-            ItemKind::MacroDef(..) => return SmallVector::new(),
-            _ => {}
+            ItemKind::MacroDef(..) => SmallVector::new(),
+            ItemKind::Fn(ref decl, ..) => {
+                struct IdVisitor { ids: SmallVector<hir::ItemId> }
+                impl<'a> Visitor<'a> for IdVisitor {
+                    fn visit_ty(&mut self, ty: &'a Ty) {
+                        if let TyKind::ImplTrait(id, _) = ty.node {
+                            self.ids.push(hir::ItemId { id });
+                        }
+                        visit::walk_ty(self, ty);
+                    }
+                }
+                let mut visitor = IdVisitor { ids: SmallVector::one(hir::ItemId { id: i.id }) };
+                match decl.output {
+                    FunctionRetTy::Default(_) => {},
+                    FunctionRetTy::Ty(ref ty) => visitor.visit_ty(ty),
+                }
+                visitor.ids
+            },
+            _ => SmallVector::one(hir::ItemId { id: i.id }),
         }
-        SmallVector::one(hir::ItemId { id: i.id })
     }
 
     fn lower_item_id_use_tree(&mut self,
index 38ecbf5ca8ada5000191815c96870f7980a02c5a..711bcfbde2c6f4ff52f8fc6d583fe6f9ad274c6c 100644 (file)
@@ -669,7 +669,7 @@ fn should_ignore_fn(ret_ty: &ast::FnDecl) -> bool {
         if let ast::FunctionRetTy::Ty(ref ty) = ret_ty.output {
             fn involves_impl_trait(ty: &ast::Ty) -> bool {
                 match ty.node {
-                    ast::TyKind::ImplTrait(_) => true,
+                    ast::TyKind::ImplTrait(..) => true,
                     ast::TyKind::Slice(ref subty) |
                     ast::TyKind::Array(ref subty, _) |
                     ast::TyKind::Ptr(ast::MutTy { ty: ref subty, .. }) |
index 25187032fb47365bbb393100237b54893e0cc1e5..97140d18c08656be9b6ce0c6679c3ba988f3cae9 100644 (file)
@@ -208,7 +208,7 @@ fn visit_ty(&mut self, ty: &'a Ty) {
                 }
                 self.no_questions_in_bounds(bounds, "trait object types", false);
             }
-            TyKind::ImplTrait(ref bounds) => {
+            TyKind::ImplTrait(_, ref bounds) => {
                 if !bounds.iter()
                           .any(|b| if let GenericBound::Trait(..) = *b { true } else { false }) {
                     self.err_handler().span_err(ty.span, "at least one trait must be specified");
@@ -505,7 +505,7 @@ fn with_impl_trait<F>(&mut self, outer_impl_trait: Option<Span>, f: F)
 
 impl<'a> Visitor<'a> for NestedImplTraitVisitor<'a> {
     fn visit_ty(&mut self, t: &'a Ty) {
-        if let TyKind::ImplTrait(_) = t.node {
+        if let TyKind::ImplTrait(..) = t.node {
             if let Some(outer_impl_trait) = self.outer_impl_trait {
                 struct_span_err!(self.session, t.span, E0666,
                                  "nested `impl Trait` is not allowed")
@@ -570,7 +570,7 @@ fn with_ban<F>(&mut self, f: F)
 impl<'a> Visitor<'a> for ImplTraitProjectionVisitor<'a> {
     fn visit_ty(&mut self, t: &'a Ty) {
         match t.node {
-            TyKind::ImplTrait(_) => {
+            TyKind::ImplTrait(..) => {
                 if self.is_banned {
                     struct_span_err!(self.session, t.span, E0667,
                                  "`impl Trait` is not allowed in path parameters")
index 9f2ca20276cdc00910a12e149932f41fc88fb0cc..70feba1eff866bf2a571269847e8c4cb9226b27a 100644 (file)
@@ -306,7 +306,7 @@ fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext) ->
                 let nested = pprust::bounds_to_string(bounds);
                 Ok(text_sig(nested))
             }
-            ast::TyKind::ImplTrait(ref bounds) => {
+            ast::TyKind::ImplTrait(_, ref bounds) => {
                 // FIXME recurse into bounds
                 let nested = pprust::bounds_to_string(bounds);
                 Ok(text_sig(format!("impl {}", nested)))
index 53465c071f33a1db651f031967010d4b513baca4..ca07ac7988dfe8b06929a1fd4452eed6bf4439db 100644 (file)
@@ -1547,7 +1547,11 @@ pub enum TyKind {
     TraitObject(GenericBounds, TraitObjectSyntax),
     /// An `impl Bound1 + Bound2 + Bound3` type
     /// where `Bound` is a trait or a lifetime.
-    ImplTrait(GenericBounds),
+    ///
+    /// The `NodeId` exists to prevent lowering from having to
+    /// generate `NodeId`s on the fly, which would complicate
+    /// the generation of `existential type` items significantly
+    ImplTrait(NodeId, GenericBounds),
     /// No-op; kept solely so that we can pretty-print faithfully
     Paren(P<Ty>),
     /// Unused for now
index 712d00fde32db9293496c68b0716a1c064b56a83..1035be3a159792825928e916626a4f4fbe03ebc3 100644 (file)
@@ -396,8 +396,8 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
             TyKind::TraitObject(bounds, syntax) => {
                 TyKind::TraitObject(bounds.move_map(|b| fld.fold_param_bound(b)), syntax)
             }
-            TyKind::ImplTrait(bounds) => {
-                TyKind::ImplTrait(bounds.move_map(|b| fld.fold_param_bound(b)))
+            TyKind::ImplTrait(id, bounds) => {
+                TyKind::ImplTrait(fld.new_id(id), bounds.move_map(|b| fld.fold_param_bound(b)))
             }
             TyKind::Mac(mac) => {
                 TyKind::Mac(fld.fold_mac(mac))
index 21bd6c083244d0f8050d67dcf29bd313d5dee087..8690918c805253b93e5681d2e8a2f47a7b4ba008 100644 (file)
@@ -1537,7 +1537,7 @@ fn parse_ty_common(&mut self, allow_plus: bool, allow_qpath_recovery: bool)
             // Always parse bounds greedily for better error recovery.
             let bounds = self.parse_generic_bounds()?;
             impl_dyn_multi = bounds.len() > 1 || self.prev_token_kind == PrevTokenKind::Plus;
-            TyKind::ImplTrait(bounds)
+            TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds)
         } else if self.check_keyword(keywords::Dyn) &&
                   self.look_ahead(1, |t| t.can_begin_bound() &&
                                          !can_continue_type_after_non_fn_ident(t)) {
index 3359225e1596595647c813057f791f73c1e9375e..74edf538842c6bbb717d826597a4dfe6a3d5b7e4 100644 (file)
@@ -1078,7 +1078,7 @@ pub fn print_type(&mut self, ty: &ast::Ty) -> io::Result<()> {
                 let prefix = if syntax == ast::TraitObjectSyntax::Dyn { "dyn" } else { "" };
                 self.print_type_bounds(prefix, &bounds[..])?;
             }
-            ast::TyKind::ImplTrait(ref bounds) => {
+            ast::TyKind::ImplTrait(_, ref bounds) => {
                 self.print_type_bounds("impl", &bounds[..])?;
             }
             ast::TyKind::Array(ref ty, ref length) => {
index 41e3ad9d4f4b1c944d9e122b83f508c2c91b86e2..bb35bcee4380616d678abc98d397c630b1f4473a 100644 (file)
@@ -338,7 +338,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
             visitor.visit_anon_const(length)
         }
         TyKind::TraitObject(ref bounds, ..) |
-        TyKind::ImplTrait(ref bounds) => {
+        TyKind::ImplTrait(_, ref bounds) => {
             walk_list!(visitor, visit_param_bound, bounds);
         }
         TyKind::Typeof(ref expression) => {