about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/hir/lowering.rs54
-rw-r--r--src/librustc_driver/pretty.rs2
-rw-r--r--src/librustc_passes/ast_validation.rs6
-rw-r--r--src/librustc_save_analysis/sig.rs2
-rw-r--r--src/libsyntax/ast.rs6
-rw-r--r--src/libsyntax/fold.rs4
-rw-r--r--src/libsyntax/parse/parser.rs2
-rw-r--r--src/libsyntax/print/pprust.rs2
-rw-r--r--src/libsyntax/visit.rs2
9 files changed, 49 insertions, 31 deletions
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 3350b046c97..d8d222b9a39 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -1167,12 +1167,14 @@ impl<'a> LoweringContext<'a> {
                 }
                 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 @@ impl<'a> LoweringContext<'a> {
         &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 @@ impl<'a> LoweringContext<'a> {
 
             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 @@ impl<'a> LoweringContext<'a> {
             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,
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 38ecbf5ca8a..711bcfbde2c 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -669,7 +669,7 @@ impl<'a> ReplaceBodyWithLoop<'a> {
         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, .. }) |
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index 25187032fb4..97140d18c08 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -208,7 +208,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 }
                 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 @@ impl<'a> NestedImplTraitVisitor<'a> {
 
 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 @@ impl<'a> ImplTraitProjectionVisitor<'a> {
 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")
diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs
index 9f2ca20276c..70feba1eff8 100644
--- a/src/librustc_save_analysis/sig.rs
+++ b/src/librustc_save_analysis/sig.rs
@@ -306,7 +306,7 @@ impl Sig for ast::Ty {
                 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)))
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 53465c071f3..ca07ac7988d 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -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
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 712d00fde32..1035be3a159 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -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))
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 21bd6c08324..8690918c805 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1537,7 +1537,7 @@ impl<'a> Parser<'a> {
             // 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)) {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 3359225e159..74edf538842 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1078,7 +1078,7 @@ impl<'a> State<'a> {
                 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) => {
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 41e3ad9d4f4..bb35bcee438 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -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) => {