diff options
| -rw-r--r-- | src/librustc/hir/lowering.rs | 54 | ||||
| -rw-r--r-- | src/librustc_driver/pretty.rs | 2 | ||||
| -rw-r--r-- | src/librustc_passes/ast_validation.rs | 6 | ||||
| -rw-r--r-- | src/librustc_save_analysis/sig.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ast.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 2 |
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) => { |
