}
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;
&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.
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),
}
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,
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, .. }) |
}
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");
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")
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")
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)))
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
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))
// 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)) {
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) => {
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) => {