diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index 518442efe7417..c2edcd22f953b 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -1509,6 +1509,20 @@ impl<I> DoubleEndedIterator for Skip<I> where I: DoubleEndedIterator + ExactSize } } + #[inline] + fn nth_back(&mut self, n: usize) -> Option<I::Item> { + let len = self.len(); + if n < len { + self.iter.nth_back(n) + } else { + if len > 0 { + // consume the original iterator + self.iter.nth_back(len-1); + } + None + } + } + fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc> { diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index af1b20a4c10cf..c6d44324ef5ee 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -3019,6 +3019,28 @@ macro_rules! iterator { {$( $mut_:tt )*}, {$($extra:tt)*} ) => { + // Returns the first element and moves the start of the iterator forwards by 1. + // Greatly improves performance compared to an inlined function. The iterator + // must not be empty. + macro_rules! next_unchecked { + ($self: ident) => {& $( $mut_ )* *$self.post_inc_start(1)} + } + + // Returns the last element and moves the end of the iterator backwards by 1. + // Greatly improves performance compared to an inlined function. The iterator + // must not be empty. + macro_rules! next_back_unchecked { + ($self: ident) => {& $( $mut_ )* *$self.pre_dec_end(1)} + } + + // Shrinks the iterator when T is a ZST, by moving the end of the iterator + // backwards by `n`. `n` must not exceed `self.len()`. + macro_rules! zst_shrink { + ($self: ident, $n: ident) => { + $self.end = ($self.end as * $raw_mut u8).wrapping_offset(-$n) as * $raw_mut T; + } + } + impl<'a, T> $name<'a, T> { // Helper function for creating a slice from the iterator. #[inline(always)] @@ -3028,12 +3050,11 @@ macro_rules! iterator { // Helper function for moving the start of the iterator forwards by `offset` elements, // returning the old start. - // Unsafe because the offset must be in-bounds or one-past-the-end. + // Unsafe because the offset must not exceed `self.len()`. #[inline(always)] unsafe fn post_inc_start(&mut self, offset: isize) -> * $raw_mut T { if mem::size_of::<T>() == 0 { - // This is *reducing* the length. `ptr` never changes with ZST. - self.end = (self.end as * $raw_mut u8).wrapping_offset(-offset) as * $raw_mut T; + zst_shrink!(self, offset); self.ptr } else { let old = self.ptr; @@ -3044,11 +3065,11 @@ macro_rules! iterator { // Helper function for moving the end of the iterator backwards by `offset` elements, // returning the new end. - // Unsafe because the offset must be in-bounds or one-past-the-end. + // Unsafe because the offset must not exceed `self.len()`. #[inline(always)] unsafe fn pre_dec_end(&mut self, offset: isize) -> * $raw_mut T { if mem::size_of::<T>() == 0 { - self.end = (self.end as * $raw_mut u8).wrapping_offset(-offset) as * $raw_mut T; + zst_shrink!(self, offset); self.ptr } else { self.end = self.end.offset(-offset); @@ -3085,7 +3106,7 @@ macro_rules! iterator { if is_empty!(self) { None } else { - Some(& $( $mut_ )* *self.post_inc_start(1)) + Some(next_unchecked!(self)) } } } @@ -3114,11 +3135,10 @@ macro_rules! iterator { } return None; } - // We are in bounds. `offset` does the right thing even for ZSTs. + // We are in bounds. `post_inc_start` does the right thing even for ZSTs. unsafe { - let elem = Some(& $( $mut_ )* *self.ptr.add(n)); - self.post_inc_start((n as isize).wrapping_add(1)); - elem + self.post_inc_start(n as isize); + Some(next_unchecked!(self)) } } @@ -3135,13 +3155,13 @@ macro_rules! iterator { let mut accum = init; unsafe { while len!(self) >= 4 { - accum = f(accum, & $( $mut_ )* *self.post_inc_start(1))?; - accum = f(accum, & $( $mut_ )* *self.post_inc_start(1))?; - accum = f(accum, & $( $mut_ )* *self.post_inc_start(1))?; - accum = f(accum, & $( $mut_ )* *self.post_inc_start(1))?; + accum = f(accum, next_unchecked!(self))?; + accum = f(accum, next_unchecked!(self))?; + accum = f(accum, next_unchecked!(self))?; + accum = f(accum, next_unchecked!(self))?; } while !is_empty!(self) { - accum = f(accum, & $( $mut_ )* *self.post_inc_start(1))?; + accum = f(accum, next_unchecked!(self))?; } } Try::from_ok(accum) @@ -3212,11 +3232,25 @@ macro_rules! iterator { if is_empty!(self) { None } else { - Some(& $( $mut_ )* *self.pre_dec_end(1)) + Some(next_back_unchecked!(self)) } } } + #[inline] + fn nth_back(&mut self, n: usize) -> Option<$elem> { + if n >= len!(self) { + // This iterator is now empty. + self.end = self.ptr; + return None; + } + // We are in bounds. `pre_dec_end` does the right thing even for ZSTs. + unsafe { + self.pre_dec_end(n as isize); + Some(next_back_unchecked!(self)) + } + } + #[inline] fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B> @@ -3225,14 +3259,14 @@ macro_rules! iterator { let mut accum = init; unsafe { while len!(self) >= 4 { - accum = f(accum, & $( $mut_ )* *self.pre_dec_end(1))?; - accum = f(accum, & $( $mut_ )* *self.pre_dec_end(1))?; - accum = f(accum, & $( $mut_ )* *self.pre_dec_end(1))?; - accum = f(accum, & $( $mut_ )* *self.pre_dec_end(1))?; + accum = f(accum, next_back_unchecked!(self))?; + accum = f(accum, next_back_unchecked!(self))?; + accum = f(accum, next_back_unchecked!(self))?; + accum = f(accum, next_back_unchecked!(self))?; } // inlining is_empty everywhere makes a huge performance difference while !is_empty!(self) { - accum = f(accum, & $( $mut_ )* *self.pre_dec_end(1))?; + accum = f(accum, next_back_unchecked!(self))?; } } Try::from_ok(accum) diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 020618ae7aeed..4d840ef24c8e6 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -2333,6 +2333,40 @@ fn test_skip_try_folds() { assert_eq!(iter.next_back(), Some(24)); } +#[test] +fn test_skip_nth_back() { + let xs = [0, 1, 2, 3, 4, 5]; + let mut it = xs.iter().skip(2); + assert_eq!(it.nth_back(0), Some(&5)); + assert_eq!(it.nth_back(1), Some(&3)); + assert_eq!(it.nth_back(0), Some(&2)); + assert_eq!(it.nth_back(0), None); + + let ys = [2, 3, 4, 5]; + let mut ity = ys.iter(); + let mut it = xs.iter().skip(2); + assert_eq!(it.nth_back(1), ity.nth_back(1)); + assert_eq!(it.clone().nth(0), ity.clone().nth(0)); + assert_eq!(it.nth_back(0), ity.nth_back(0)); + assert_eq!(it.clone().nth(0), ity.clone().nth(0)); + assert_eq!(it.nth_back(0), ity.nth_back(0)); + assert_eq!(it.clone().nth(0), ity.clone().nth(0)); + assert_eq!(it.nth_back(0), ity.nth_back(0)); + assert_eq!(it.clone().nth(0), ity.clone().nth(0)); + + let mut it = xs.iter().skip(2); + assert_eq!(it.nth_back(4), None); + assert_eq!(it.nth_back(0), None); + + let mut it = xs.iter(); + it.by_ref().skip(2).nth_back(3); + assert_eq!(it.next_back(), Some(&1)); + + let mut it = xs.iter(); + it.by_ref().skip(2).nth_back(10); + assert_eq!(it.next_back(), Some(&1)); +} + #[test] fn test_take_try_folds() { let f = &|acc, x| i32::checked_add(2*acc, x); diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index eaa799fa96ee2..03e65d2fe0b81 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -88,6 +88,19 @@ fn test_iterator_nth() { assert_eq!(iter.nth(1).unwrap(), &v[4]); } +#[test] +fn test_iterator_nth_back() { + let v: &[_] = &[0, 1, 2, 3, 4]; + for i in 0..v.len() { + assert_eq!(v.iter().nth_back(i).unwrap(), &v[v.len() - i - 1]); + } + assert_eq!(v.iter().nth_back(v.len()), None); + + let mut iter = v.iter(); + assert_eq!(iter.nth_back(2).unwrap(), &v[2]); + assert_eq!(iter.nth_back(1).unwrap(), &v[0]); +} + #[test] fn test_iterator_last() { let v: &[_] = &[0, 1, 2, 3, 4]; diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 996af3672e8bd..c87ab68693726 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -608,15 +608,7 @@ impl<'a> LoweringContext<'a> { }); if let Some(hir_id) = item_hir_id { - let item_generics = match self.lctx.items.get(&hir_id).unwrap().node { - hir::ItemKind::Impl(_, _, _, ref generics, ..) - | hir::ItemKind::Trait(_, _, ref generics, ..) => { - generics.params.clone() - } - _ => HirVec::new(), - }; - - self.lctx.with_parent_impl_lifetime_defs(&item_generics, |this| { + self.lctx.with_parent_item_lifetime_defs(hir_id, |this| { let this = &mut ItemLowerer { lctx: this }; if let ItemKind::Impl(.., ref opt_trait_ref, _, _) = item.node { this.with_trait_impl_ref(opt_trait_ref, |this| { @@ -1054,14 +1046,22 @@ impl<'a> LoweringContext<'a> { // This should only be used with generics that have already had their // in-band lifetimes added. In practice, this means that this function is // only used when lowering a child item of a trait or impl. - fn with_parent_impl_lifetime_defs<T, F>(&mut self, - params: &HirVec<hir::GenericParam>, + fn with_parent_item_lifetime_defs<T, F>(&mut self, + parent_hir_id: hir::HirId, f: F ) -> T where F: FnOnce(&mut LoweringContext<'_>) -> T, { let old_len = self.in_scope_lifetimes.len(); - let lt_def_names = params.iter().filter_map(|param| match param.kind { + + let parent_generics = match self.items.get(&parent_hir_id).unwrap().node { + hir::ItemKind::Impl(_, _, _, ref generics, ..) + | hir::ItemKind::Trait(_, _, ref generics, ..) => { + &generics.params[..] + } + _ => &[], + }; + let lt_def_names = parent_generics.iter().filter_map(|param| match param.kind { hir::GenericParamKind::Lifetime { .. } => Some(param.name.ident().modern()), _ => None, }); @@ -1113,8 +1113,7 @@ impl<'a> LoweringContext<'a> { lowered_generics.params = lowered_generics .params - .iter() - .cloned() + .into_iter() .chain(in_band_defs) .collect(); @@ -3114,8 +3113,8 @@ impl<'a> LoweringContext<'a> { &NodeMap::default(), itctx.reborrow(), ); - let trait_ref = self.with_parent_impl_lifetime_defs( - &bound_generic_params, + let trait_ref = self.with_in_scope_lifetime_defs( + &p.bound_generic_params, |this| this.lower_trait_ref(&p.trait_ref, itctx), ); @@ -3602,8 +3601,7 @@ impl<'a> LoweringContext<'a> { // Essentially a single `use` which imports two names is desugared into // two imports. for (res, &new_node_id) in resolutions.zip([id1, id2].iter()) { - let vis = vis.clone(); - let ident = ident.clone(); + let ident = *ident; let mut path = path.clone(); for seg in &mut path.segments { seg.id = self.sess.next_node_id(); @@ -3616,19 +3614,7 @@ impl<'a> LoweringContext<'a> { let path = this.lower_path_extra(res, &path, ParamMode::Explicit, None); let item = hir::ItemKind::Use(P(path), hir::UseKind::Single); - let vis_kind = match vis.node { - hir::VisibilityKind::Public => hir::VisibilityKind::Public, - hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar), - hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited, - hir::VisibilityKind::Restricted { ref path, hir_id: _ } => { - let path = this.renumber_segment_ids(path); - hir::VisibilityKind::Restricted { - path, - hir_id: this.next_id(), - } - } - }; - let vis = respan(vis.span, vis_kind); + let vis = this.rebuild_vis(&vis); this.insert_item( hir::Item { @@ -3692,8 +3678,6 @@ impl<'a> LoweringContext<'a> { for &(ref use_tree, id) in trees { let new_hir_id = self.lower_node_id(id); - let mut vis = vis.clone(); - let mut ident = ident.clone(); let mut prefix = prefix.clone(); // Give the segments new node-ids since they are being cloned. @@ -3707,6 +3691,9 @@ impl<'a> LoweringContext<'a> { // own its own names, we have to adjust the owner before // lowering the rest of the import. self.with_hir_id_owner(id, |this| { + let mut vis = this.rebuild_vis(&vis); + let mut ident = *ident; + let item = this.lower_use_tree(use_tree, &prefix, id, @@ -3714,20 +3701,6 @@ impl<'a> LoweringContext<'a> { &mut ident, attrs); - let vis_kind = match vis.node { - hir::VisibilityKind::Public => hir::VisibilityKind::Public, - hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar), - hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited, - hir::VisibilityKind::Restricted { ref path, hir_id: _ } => { - let path = this.renumber_segment_ids(path); - hir::VisibilityKind::Restricted { - path: path, - hir_id: this.next_id(), - } - } - }; - let vis = respan(vis.span, vis_kind); - this.insert_item( hir::Item { hir_id: new_hir_id, @@ -3773,15 +3746,35 @@ impl<'a> LoweringContext<'a> { /// Paths like the visibility path in `pub(super) use foo::{bar, baz}` are repeated /// many times in the HIR tree; for each occurrence, we need to assign distinct /// `NodeId`s. (See, e.g., #56128.) - fn renumber_segment_ids(&mut self, path: &P<hir::Path>) -> P<hir::Path> { - debug!("renumber_segment_ids(path = {:?})", path); - let mut path = path.clone(); - for seg in path.segments.iter_mut() { - if seg.hir_id.is_some() { - seg.hir_id = Some(self.next_id()); - } + fn rebuild_use_path(&mut self, path: &hir::Path) -> hir::Path { + debug!("rebuild_use_path(path = {:?})", path); + let segments = path.segments.iter().map(|seg| hir::PathSegment { + ident: seg.ident, + hir_id: seg.hir_id.map(|_| self.next_id()), + res: seg.res, + args: None, + infer_args: seg.infer_args, + }).collect(); + hir::Path { + span: path.span, + res: path.res, + segments, } - path + } + + fn rebuild_vis(&mut self, vis: &hir::Visibility) -> hir::Visibility { + let vis_kind = match vis.node { + hir::VisibilityKind::Public => hir::VisibilityKind::Public, + hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar), + hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited, + hir::VisibilityKind::Restricted { ref path, hir_id: _ } => { + hir::VisibilityKind::Restricted { + path: P(self.rebuild_use_path(path)), + hir_id: self.next_id(), + } + } + }; + respan(vis.span, vis_kind) } fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem { diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 85c86991f489a..87da3273bd220 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -51,11 +51,11 @@ impl<'hir> Entry<'hir> { } } - fn fn_decl(&self) -> Option<&FnDecl> { + fn fn_decl(&self) -> Option<&'hir FnDecl> { match self.node { Node::Item(ref item) => { match item.node { - ItemKind::Fn(ref fn_decl, _, _, _) => Some(&fn_decl), + ItemKind::Fn(ref fn_decl, _, _, _) => Some(fn_decl), _ => None, } } @@ -76,7 +76,7 @@ impl<'hir> Entry<'hir> { Node::Expr(ref expr) => { match expr.node { - ExprKind::Closure(_, ref fn_decl, ..) => Some(&fn_decl), + ExprKind::Closure(_, ref fn_decl, ..) => Some(fn_decl), _ => None, } } @@ -412,9 +412,9 @@ impl<'hir> Map<'hir> { self.forest.krate.body(id) } - pub fn fn_decl_by_hir_id(&self, hir_id: HirId) -> Option<FnDecl> { + pub fn fn_decl_by_hir_id(&self, hir_id: HirId) -> Option<&'hir FnDecl> { if let Some(entry) = self.find_entry(hir_id) { - entry.fn_decl().cloned() + entry.fn_decl() } else { bug!("no entry for hir_id `{}`", hir_id) } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 527f18f57dc2e..2b46170a6d232 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -155,7 +155,7 @@ pub const DUMMY_HIR_ID: HirId = HirId { pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId::MAX; -#[derive(Clone, RustcEncodable, RustcDecodable, Copy, HashStable)] +#[derive(Copy, Clone, RustcEncodable, RustcDecodable, HashStable)] pub struct Lifetime { pub hir_id: HirId, pub span: Span, @@ -295,7 +295,7 @@ impl Lifetime { /// A `Path` is essentially Rust's notion of a name; for instance, /// `std::cmp::PartialEq`. It's represented as a sequence of identifiers, /// along with a bunch of supporting information. -#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] +#[derive(RustcEncodable, RustcDecodable, HashStable)] pub struct Path { pub span: Span, /// The resolution for the path. @@ -324,7 +324,7 @@ impl fmt::Display for Path { /// A segment of a path: an identifier, an optional lifetime, and a set of /// types. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct PathSegment { /// The identifier portion of this path segment. #[stable_hasher(project(name))] @@ -383,27 +383,23 @@ impl PathSegment { } } - // FIXME: hack required because you can't create a static - // `GenericArgs`, so you can't just return a `&GenericArgs`. - pub fn with_generic_args<F, R>(&self, f: F) -> R - where F: FnOnce(&GenericArgs) -> R - { - let dummy = GenericArgs::none(); - f(if let Some(ref args) = self.args { - &args + pub fn generic_args(&self) -> &GenericArgs { + if let Some(ref args) = self.args { + args } else { - &dummy - }) + const DUMMY: &GenericArgs = &GenericArgs::none(); + DUMMY + } } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct ConstArg { pub value: AnonConst, pub span: Span, } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum GenericArg { Lifetime(Lifetime), Type(Ty), @@ -435,7 +431,7 @@ impl GenericArg { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct GenericArgs { /// The generic arguments for this path segment. pub args: HirVec<GenericArg>, @@ -449,7 +445,7 @@ pub struct GenericArgs { } impl GenericArgs { - pub fn none() -> Self { + pub const fn none() -> Self { Self { args: HirVec::new(), bindings: HirVec::new(), @@ -509,7 +505,7 @@ pub enum TraitBoundModifier { /// `typeck::collect::compute_bounds` matches these against /// the "special" built-in traits (see `middle::lang_items`) and /// detects `Copy`, `Send` and `Sync`. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum GenericBound { Trait(PolyTraitRef, TraitBoundModifier), Outlives(Lifetime), @@ -545,7 +541,7 @@ pub enum LifetimeParamKind { Error, } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum GenericParamKind { /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`). Lifetime { @@ -560,7 +556,7 @@ pub enum GenericParamKind { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct GenericParam { pub hir_id: HirId, pub name: ParamName, @@ -580,7 +576,7 @@ pub struct GenericParamCount { /// Represents lifetimes and type parameters attached to a declaration /// of a function, enum, trait, etc. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct Generics { pub params: HirVec<GenericParam>, pub where_clause: WhereClause, @@ -588,7 +584,7 @@ pub struct Generics { } impl Generics { - pub fn empty() -> Generics { + pub const fn empty() -> Generics { Generics { params: HirVec::new(), where_clause: WhereClause { @@ -642,7 +638,7 @@ pub enum SyntheticTyParamKind { } /// A where-clause in a definition. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct WhereClause { pub predicates: HirVec<WherePredicate>, // Only valid if predicates isn't empty. @@ -660,7 +656,7 @@ impl WhereClause { } /// A single predicate in a where-clause. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum WherePredicate { /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`). BoundPredicate(WhereBoundPredicate), @@ -681,7 +677,7 @@ impl WherePredicate { } /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`). -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct WhereBoundPredicate { pub span: Span, /// Any generics from a `for` binding. @@ -693,7 +689,7 @@ pub struct WhereBoundPredicate { } /// A lifetime predicate (e.g., `'a: 'b + 'c`). -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct WhereRegionPredicate { pub span: Span, pub lifetime: Lifetime, @@ -701,7 +697,7 @@ pub struct WhereRegionPredicate { } /// An equality predicate (e.g., `T = int`); currently unsupported. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct WhereEqPredicate { pub hir_id: HirId, pub span: Span, @@ -709,7 +705,7 @@ pub struct WhereEqPredicate { pub rhs_ty: P<Ty>, } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(RustcEncodable, RustcDecodable, Debug)] pub struct ModuleItems { // Use BTreeSets here so items are in the same order as in the // list of all items in Crate @@ -724,7 +720,7 @@ pub struct ModuleItems { /// For more details, see the [rustc guide]. /// /// [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(RustcEncodable, RustcDecodable, Debug)] pub struct Crate { pub module: Mod, pub attrs: HirVec<Attribute>, @@ -819,7 +815,7 @@ impl Crate { /// A macro definition, in this crate or imported from another. /// /// Not parsed directly, but created on macro import or `macro_rules!` expansion. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct MacroDef { pub name: Name, pub vis: Visibility, @@ -833,7 +829,7 @@ pub struct MacroDef { /// A block of statements `{ .. }`, which may have a label (in this case the /// `targeted_by_break` field will be `true`) and may be `unsafe` by means of /// the `rules` being anything but `DefaultBlock`. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct Block { /// Statements in a block. pub stmts: HirVec<Stmt>, @@ -851,7 +847,7 @@ pub struct Block { pub targeted_by_break: bool, } -#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] +#[derive(RustcEncodable, RustcDecodable, HashStable)] pub struct Pat { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -914,7 +910,7 @@ impl Pat { /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` /// are treated the same as` x: x, y: ref y, z: ref mut z`, /// except `is_shorthand` is true. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct FieldPat { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -929,7 +925,7 @@ pub struct FieldPat { /// Explicit binding annotations given in the HIR for a binding. Note /// that this is not the final binding *mode* that we infer after type /// inference. -#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)] +#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum BindingAnnotation { /// No binding annotation given: this means that the final binding mode /// will depend on whether we have skipped through a `&` reference @@ -956,7 +952,7 @@ pub enum RangeEnd { Excluded, } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum PatKind { /// Represents a wildcard pattern (i.e., `_`). Wild, @@ -1001,8 +997,8 @@ pub enum PatKind { Slice(HirVec<P<Pat>>, Option<P<Pat>>, HirVec<P<Pat>>), } -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, HashStable, - RustcEncodable, RustcDecodable, Hash, Debug, Copy)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, HashStable, + RustcEncodable, RustcDecodable, Hash, Debug)] pub enum Mutability { MutMutable, MutImmutable, @@ -1018,7 +1014,7 @@ impl Mutability { } } -#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, Hash, HashStable)] +#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Hash, HashStable)] pub enum BinOpKind { /// The `+` operator (addition). Add, @@ -1152,7 +1148,7 @@ impl Into<ast::BinOpKind> for BinOpKind { pub type BinOp = Spanned<BinOpKind>; -#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, Hash, HashStable)] +#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Hash, HashStable)] pub enum UnOp { /// The `*` operator (deferencing). UnDeref, @@ -1181,7 +1177,7 @@ impl UnOp { } /// A statement. -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(RustcEncodable, RustcDecodable)] pub struct Stmt { pub hir_id: HirId, pub node: StmtKind, @@ -1196,7 +1192,7 @@ impl fmt::Debug for Stmt { } /// The contents of a statement. -#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] +#[derive(RustcEncodable, RustcDecodable, HashStable)] pub enum StmtKind { /// A local (`let`) binding. Local(P<Local>), @@ -1223,7 +1219,7 @@ impl StmtKind { } /// Represents a `let` statement (i.e., `let <pat>:<ty> = <expr>;`). -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct Local { pub pat: P<Pat>, /// Type annotation, if any (otherwise the type will be inferred). @@ -1240,7 +1236,7 @@ pub struct Local { /// Represents a single arm of a `match` expression, e.g. /// `<pats> (if <guard>) => <body>`. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct Arm { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -1254,12 +1250,12 @@ pub struct Arm { pub body: P<Expr>, } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum Guard { If(P<Expr>), } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct Field { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -1269,7 +1265,7 @@ pub struct Field { pub is_shorthand: bool, } -#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)] +#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum BlockCheckMode { DefaultBlock, UnsafeBlock(UnsafeSource), @@ -1277,7 +1273,7 @@ pub enum BlockCheckMode { PopUnsafeBlock(UnsafeSource), } -#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)] +#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum UnsafeSource { CompilerGenerated, UserProvided, @@ -1309,7 +1305,7 @@ pub struct BodyId { /// /// All bodies have an **owner**, which can be accessed via the HIR /// map using `body_owner_def_id()`. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(RustcEncodable, RustcDecodable, Debug)] pub struct Body { pub arguments: HirVec<Arg>, pub value: Expr, @@ -1383,7 +1379,7 @@ pub struct AnonConst { } /// An expression -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(RustcEncodable, RustcDecodable)] pub struct Expr { pub span: Span, pub node: ExprKind, @@ -1494,7 +1490,7 @@ impl fmt::Debug for Expr { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum ExprKind { /// A `box x` expression. Box(P<Expr>), @@ -1602,7 +1598,7 @@ pub enum ExprKind { } /// Represents an optionally `Self`-qualified value/type path or associated extension. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum QPath { /// Path to a definition, optionally "fully-qualified" with a `Self` /// type, if the path points to an associated item in a trait. @@ -1622,7 +1618,7 @@ pub enum QPath { } /// Hints at the original code for a let statement. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)] +#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum LocalSource { /// A `match _ { .. }`. Normal, @@ -1644,7 +1640,7 @@ pub enum LocalSource { } /// Hints at the original code for a `match _ { .. }`. -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy, HashStable)] +#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)] pub enum MatchSource { /// A `match _ { .. }`. Normal, @@ -1668,7 +1664,7 @@ pub enum MatchSource { } /// The loop type that yielded an `ExprKind::Loop`. -#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)] +#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum LoopSource { /// A `loop { .. }` loop. Loop, @@ -1678,7 +1674,7 @@ pub enum LoopSource { ForLoop, } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)] +#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum LoopIdError { OutsideLoopScope, UnlabeledCfInWhileCondition, @@ -1696,7 +1692,7 @@ impl fmt::Display for LoopIdError { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)] +#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct Destination { // This is `Some(_)` iff there is an explicit user-specified `label pub label: Option<Label>, @@ -1707,8 +1703,8 @@ pub struct Destination { } /// Whether a generator contains self-references, causing it to be `!Unpin`. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, HashStable, - RustcEncodable, RustcDecodable, Hash, Debug, Copy)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, HashStable, + RustcEncodable, RustcDecodable, Hash, Debug)] pub enum GeneratorMovability { /// May contain self-references, `!Unpin`. Static, @@ -1717,7 +1713,7 @@ pub enum GeneratorMovability { } /// The yield kind that caused an `ExprKind::Yield`. -#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)] +#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)] pub enum YieldSource { /// An `<expr>.await`. Await, @@ -1734,7 +1730,7 @@ impl fmt::Display for YieldSource { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)] +#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum CaptureClause { CaptureByValue, CaptureByRef, @@ -1742,14 +1738,14 @@ pub enum CaptureClause { // N.B., if you change this, you'll probably want to change the corresponding // type structure in middle/ty.rs as well. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct MutTy { pub ty: P<Ty>, pub mutbl: Mutability, } /// Represents a method's signature in a trait declaration or implementation. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct MethodSig { pub header: FnHeader, pub decl: P<FnDecl>, @@ -1767,7 +1763,7 @@ pub struct TraitItemId { /// possibly including a default implementation. A trait item is /// either required (meaning it doesn't have an implementation, just a /// signature) or provided (meaning it has a default implementation). -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(RustcEncodable, RustcDecodable, Debug)] pub struct TraitItem { pub ident: Ident, pub hir_id: HirId, @@ -1778,7 +1774,7 @@ pub struct TraitItem { } /// Represents a trait method's body (or just argument names). -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum TraitMethod { /// No default body in the trait, just a signature. Required(HirVec<Ident>), @@ -1788,7 +1784,7 @@ pub enum TraitMethod { } /// Represents a trait method or associated constant or type -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum TraitItemKind { /// An associated constant with an optional value (otherwise `impl`s must contain a value). Const(P<Ty>, Option<BodyId>), @@ -1808,7 +1804,7 @@ pub struct ImplItemId { } /// Represents anything within an `impl` block -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(RustcEncodable, RustcDecodable, Debug)] pub struct ImplItem { pub ident: Ident, pub hir_id: HirId, @@ -1821,7 +1817,7 @@ pub struct ImplItem { } /// Represents various kinds of content within an `impl`. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum ImplItemKind { /// An associated constant of the given type, set to the constant result /// of the expression @@ -1848,7 +1844,7 @@ pub enum ImplItemKind { /// Binding(...), /// } /// ``` -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct TypeBinding { pub hir_id: HirId, #[stable_hasher(project(name))] @@ -1858,7 +1854,7 @@ pub struct TypeBinding { } // Represents the two kinds of type bindings. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum TypeBindingKind { /// E.g., `Foo<Bar: Send>`. Constraint { @@ -1879,7 +1875,7 @@ impl TypeBinding { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(RustcEncodable, RustcDecodable)] pub struct Ty { pub hir_id: HirId, pub node: TyKind, @@ -1894,7 +1890,7 @@ impl fmt::Debug for Ty { } /// Not represented directly in the AST; referred to by name through a `ty_path`. -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy, HashStable)] +#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)] pub enum PrimTy { Int(IntTy), Uint(UintTy), @@ -1904,7 +1900,7 @@ pub enum PrimTy { Char, } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct BareFnTy { pub unsafety: Unsafety, pub abi: Abi, @@ -1913,7 +1909,7 @@ pub struct BareFnTy { pub arg_names: HirVec<Ident>, } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct ExistTy { pub generics: Generics, pub bounds: GenericBounds, @@ -1933,7 +1929,7 @@ pub enum ExistTyOrigin { } /// The various kinds of types recognized by the compiler. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum TyKind { /// A variable length slice (i.e., `[T]`). Slice(P<Ty>), @@ -1975,7 +1971,7 @@ pub enum TyKind { CVarArgs(Lifetime), } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct InlineAsmOutput { pub constraint: Symbol, pub is_rw: bool, @@ -1998,14 +1994,14 @@ pub struct InlineAsm { } /// Represents an argument in a function header. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct Arg { pub pat: P<Pat>, pub hir_id: HirId, } /// Represents the header (not the body) of a function declaration. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct FnDecl { /// The types of the function's arguments. /// @@ -2018,7 +2014,7 @@ pub struct FnDecl { } /// Represents what type of implicit self a function has, if any. -#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum ImplicitSelfKind { /// Represents a `fn x(self);`. Imm, @@ -2123,7 +2119,7 @@ impl fmt::Debug for ImplPolarity { } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum FunctionRetTy { /// Return type is not specified. /// @@ -2153,7 +2149,7 @@ impl FunctionRetTy { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(RustcEncodable, RustcDecodable, Debug)] pub struct Mod { /// A span from the first token past `{` to the last token until `}`. /// For `mod foo;`, the inner span ranges from the first token @@ -2162,25 +2158,25 @@ pub struct Mod { pub item_ids: HirVec<ItemId>, } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct ForeignMod { pub abi: Abi, pub items: HirVec<ForeignItem>, } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct GlobalAsm { pub asm: Symbol, #[stable_hasher(ignore)] // This is used for error reporting pub ctxt: SyntaxContext, } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct EnumDef { pub variants: HirVec<Variant>, } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct VariantKind { /// Name of the variant. #[stable_hasher(project(name))] @@ -2219,7 +2215,7 @@ pub enum UseKind { /// that the `ref_id` is for. Note that `ref_id`'s value is not the `HirId` of the /// trait being referred to but just a unique `HirId` that serves as a key /// within the resolution map. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct TraitRef { pub path: Path, // Don't hash the ref_id. It is tracked via the thing it is used to access @@ -2241,7 +2237,7 @@ impl TraitRef { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct PolyTraitRef { /// The `'a` in `<'a> Foo<&'a T>`. pub bound_generic_params: HirVec<GenericParam>, @@ -2254,7 +2250,7 @@ pub struct PolyTraitRef { pub type Visibility = Spanned<VisibilityKind>; -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(RustcEncodable, RustcDecodable, Debug)] pub enum VisibilityKind { Public, Crate(CrateSugar), @@ -2289,7 +2285,7 @@ impl VisibilityKind { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct StructField { pub span: Span, #[stable_hasher(project(name))] @@ -2309,7 +2305,7 @@ impl StructField { } /// Fields and constructor IDs of enum variants and structs. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum VariantData { /// A struct variant. /// @@ -2354,7 +2350,7 @@ pub struct ItemId { /// An item /// /// The name might be a dummy name in case of anonymous items -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(RustcEncodable, RustcDecodable, Debug)] pub struct Item { pub ident: Ident, pub hir_id: HirId, @@ -2364,7 +2360,7 @@ pub struct Item { pub span: Span, } -#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct FnHeader { pub unsafety: Unsafety, pub constness: Constness, @@ -2381,7 +2377,7 @@ impl FnHeader { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum ItemKind { /// An `extern crate` item, with optional *original* crate name if the crate was renamed. /// @@ -2484,7 +2480,7 @@ impl ItemKind { /// type or method, and whether it is public). This allows other /// passes to find the impl they want without loading the ID (which /// means fewer edges in the incremental compilation graph). -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct TraitItemRef { pub id: TraitItemId, #[stable_hasher(project(name))] @@ -2500,7 +2496,7 @@ pub struct TraitItemRef { /// type or method, and whether it is public). This allows other /// passes to find the impl they want without loading the ID (which /// means fewer edges in the incremental compilation graph). -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct ImplItemRef { pub id: ImplItemId, #[stable_hasher(project(name))] @@ -2519,7 +2515,7 @@ pub enum AssocItemKind { Existential, } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct ForeignItem { #[stable_hasher(project(name))] pub ident: Ident, @@ -2531,7 +2527,7 @@ pub struct ForeignItem { } /// An item within an `extern` block. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum ForeignItemKind { /// A foreign function. Fn(P<FnDecl>, HirVec<Ident>, Generics), diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index e1c713b537c2a..8b1984e04f55b 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -625,10 +625,10 @@ impl<'a> State<'a> { self.word_space("for ?")?; self.print_trait_ref(&ptr.trait_ref)?; } else { - real_bounds.push(b.clone()); + real_bounds.push(b); } } - self.print_bounds(":", &real_bounds[..])?; + self.print_bounds(":", real_bounds)?; self.s.word(";")?; self.end()?; // end the outer ibox } @@ -698,10 +698,10 @@ impl<'a> State<'a> { self.word_space("for ?")?; self.print_trait_ref(&ptr.trait_ref)?; } else { - real_bounds.push(b.clone()); + real_bounds.push(b); } } - self.print_bounds(":", &real_bounds[..])?; + self.print_bounds(":", real_bounds)?; self.print_where_clause(&generics.where_clause)?; self.s.word(" ")?; self.bopen()?; @@ -724,11 +724,11 @@ impl<'a> State<'a> { self.word_space("for ?")?; self.print_trait_ref(&ptr.trait_ref)?; } else { - real_bounds.push(b.clone()); + real_bounds.push(b); } } self.nbsp()?; - self.print_bounds("=", &real_bounds[..])?; + self.print_bounds("=", real_bounds)?; self.print_where_clause(&generics.where_clause)?; self.s.word(";")?; } @@ -1194,12 +1194,11 @@ impl<'a> State<'a> { self.s.word(".")?; self.print_ident(segment.ident)?; - segment.with_generic_args(|generic_args| { - if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() { - return self.print_generic_args(&generic_args, segment.infer_args, true); - } - Ok(()) - })?; + let generic_args = segment.generic_args(); + if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() { + self.print_generic_args(generic_args, segment.infer_args, true)?; + } + self.print_call_post(base_args) } @@ -1559,11 +1558,9 @@ impl<'a> State<'a> { self.s.word("::")? } if segment.ident.name != kw::PathRoot { - self.print_ident(segment.ident)?; - segment.with_generic_args(|generic_args| { - self.print_generic_args(generic_args, segment.infer_args, - colons_before_params) - })?; + self.print_ident(segment.ident)?; + self.print_generic_args(segment.generic_args(), segment.infer_args, + colons_before_params)?; } } @@ -1572,10 +1569,8 @@ impl<'a> State<'a> { pub fn print_path_segment(&mut self, segment: &hir::PathSegment) -> io::Result<()> { if segment.ident.name != kw::PathRoot { - self.print_ident(segment.ident)?; - segment.with_generic_args(|generic_args| { - self.print_generic_args(generic_args, segment.infer_args, false) - })?; + self.print_ident(segment.ident)?; + self.print_generic_args(segment.generic_args(), segment.infer_args, false)?; } Ok(()) } @@ -1600,11 +1595,9 @@ impl<'a> State<'a> { } if segment.ident.name != kw::PathRoot { self.print_ident(segment.ident)?; - segment.with_generic_args(|generic_args| { - self.print_generic_args(generic_args, - segment.infer_args, - colons_before_params) - })?; + self.print_generic_args(segment.generic_args(), + segment.infer_args, + colons_before_params)?; } } @@ -1612,11 +1605,9 @@ impl<'a> State<'a> { self.s.word("::")?; let item_segment = path.segments.last().unwrap(); self.print_ident(item_segment.ident)?; - item_segment.with_generic_args(|generic_args| { - self.print_generic_args(generic_args, - item_segment.infer_args, - colons_before_params) - }) + self.print_generic_args(item_segment.generic_args(), + item_segment.infer_args, + colons_before_params) } hir::QPath::TypeRelative(ref qself, ref item_segment) => { self.s.word("<")?; @@ -1624,11 +1615,9 @@ impl<'a> State<'a> { self.s.word(">")?; self.s.word("::")?; self.print_ident(item_segment.ident)?; - item_segment.with_generic_args(|generic_args| { - self.print_generic_args(generic_args, - item_segment.infer_args, - colons_before_params) - }) + self.print_generic_args(item_segment.generic_args(), + item_segment.infer_args, + colons_before_params) } } } @@ -2009,31 +1998,34 @@ impl<'a> State<'a> { } } - pub fn print_bounds(&mut self, prefix: &'static str, bounds: &[hir::GenericBound]) - -> io::Result<()> { - if !bounds.is_empty() { - self.s.word(prefix)?; - let mut first = true; - for bound in bounds { - if !(first && prefix.is_empty()) { - self.nbsp()?; - } - if first { - first = false; - } else { - self.word_space("+")?; - } + pub fn print_bounds<'b>( + &mut self, + prefix: &'static str, + bounds: impl IntoIterator<Item = &'b hir::GenericBound>, + ) -> io::Result<()> { + let mut first = true; + for bound in bounds { + if first { + self.s.word(prefix)?; + } + if !(first && prefix.is_empty()) { + self.nbsp()?; + } + if first { + first = false; + } else { + self.word_space("+")?; + } - match bound { - GenericBound::Trait(tref, modifier) => { - if modifier == &TraitBoundModifier::Maybe { - self.s.word("?")?; - } - self.print_poly_trait_ref(tref)?; - } - GenericBound::Outlives(lt) => { - self.print_lifetime(lt)?; + match bound { + GenericBound::Trait(tref, modifier) => { + if modifier == &TraitBoundModifier::Maybe { + self.s.word("?")?; } + self.print_poly_trait_ref(tref)?; + } + GenericBound::Outlives(lt) => { + self.print_lifetime(lt)?; } } } diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 4b65d3b9d8e3a..2555833cd77e3 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1050,10 +1050,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { (self.tcx.sess.source_map().def_span(span), self.tcx.hir().body(id).arguments.iter() .map(|arg| { if let hir::Pat { - node: hir::PatKind::Tuple(args, _), + node: hir::PatKind::Tuple(ref args, _), span, .. - } = arg.pat.clone().into_inner() { + } = *arg.pat { ArgKind::Tuple( Some(span), args.iter().map(|pat| { diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs index 6a70a23729c26..dfaad95fa3cb9 100644 --- a/src/librustc_mir/borrow_check/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/conflict_errors.rs @@ -1815,8 +1815,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // as the HIR doesn't have full types for closure arguments. let return_ty = *sig.output().skip_binder(); let mut return_span = fn_decl.output.span(); - if let hir::FunctionRetTy::Return(ty) = fn_decl.output { - if let hir::TyKind::Rptr(lifetime, _) = ty.into_inner().node { + if let hir::FunctionRetTy::Return(ty) = &fn_decl.output { + if let hir::TyKind::Rptr(lifetime, _) = ty.node { return_span = lifetime.span; } } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 8236cd1f73857..267f3798bd1e3 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -97,15 +97,15 @@ pub enum SizedByDefault { No, } -struct ConvertedBinding<'tcx> { +struct ConvertedBinding<'a, 'tcx> { item_name: ast::Ident, - kind: ConvertedBindingKind<'tcx>, + kind: ConvertedBindingKind<'a, 'tcx>, span: Span, } -enum ConvertedBindingKind<'tcx> { +enum ConvertedBindingKind<'a, 'tcx> { Equality(Ty<'tcx>), - Constraint(P<[hir::GenericBound]>), + Constraint(&'a [hir::GenericBound]), } #[derive(PartialEq)] @@ -191,15 +191,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { item_segment: &hir::PathSegment) -> SubstsRef<'tcx> { - let (substs, assoc_bindings, _) = item_segment.with_generic_args(|generic_args| { - self.create_substs_for_ast_path( - span, - def_id, - generic_args, - item_segment.infer_args, - None, - ) - }); + let (substs, assoc_bindings, _) = self.create_substs_for_ast_path( + span, + def_id, + item_segment.generic_args(), + item_segment.infer_args, + None, + ); assoc_bindings.first().map(|b| Self::prohibit_assoc_ty_binding(self.tcx(), b.span)); @@ -598,7 +596,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { generic_args: &'a hir::GenericArgs, infer_args: bool, self_ty: Option<Ty<'tcx>>) - -> (SubstsRef<'tcx>, Vec<ConvertedBinding<'tcx>>, Option<Vec<Span>>) + -> (SubstsRef<'tcx>, Vec<ConvertedBinding<'a, 'tcx>>, Option<Vec<Span>>) { // If the type is parameterized by this region, then replace this // region with the current anon region binding (in other words, @@ -740,7 +738,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { hir::TypeBindingKind::Equality { ref ty } => ConvertedBindingKind::Equality(self.ast_ty_to_ty(ty)), hir::TypeBindingKind::Constraint { ref bounds } => - ConvertedBindingKind::Constraint(bounds.clone()), + ConvertedBindingKind::Constraint(bounds), }; ConvertedBinding { item_name: binding.ident, @@ -861,21 +859,21 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ty::TraitRef::new(trait_def_id, substs) } - fn create_substs_for_ast_trait_ref( + fn create_substs_for_ast_trait_ref<'a>( &self, span: Span, trait_def_id: DefId, self_ty: Ty<'tcx>, - trait_segment: &hir::PathSegment, - ) -> (SubstsRef<'tcx>, Vec<ConvertedBinding<'tcx>>, Option<Vec<Span>>) { + trait_segment: &'a hir::PathSegment, + ) -> (SubstsRef<'tcx>, Vec<ConvertedBinding<'a, 'tcx>>, Option<Vec<Span>>) { debug!("create_substs_for_ast_trait_ref(trait_segment={:?})", trait_segment); let trait_def = self.tcx().trait_def(trait_def_id); if !self.tcx().features().unboxed_closures && - trait_segment.with_generic_args(|generic_args| generic_args.parenthesized) - != trait_def.paren_sugar { + trait_segment.generic_args().parenthesized != trait_def.paren_sugar + { // For now, require that parenthetical notation be used only with `Fn()` etc. let msg = if trait_def.paren_sugar { "the precise format of `Fn`-family traits' type parameters is subject to change. \ @@ -887,13 +885,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { span, GateIssue::Language, msg); } - trait_segment.with_generic_args(|generic_args| { - self.create_substs_for_ast_path(span, - trait_def_id, - generic_args, - trait_segment.infer_args, - Some(self_ty)) - }) + self.create_substs_for_ast_path(span, + trait_def_id, + trait_segment.generic_args(), + trait_segment.infer_args, + Some(self_ty)) } fn trait_defines_associated_type_named(&self, @@ -916,7 +912,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { for ab in ast_bounds { if let &hir::GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = ab { if unbound.is_none() { - unbound = Some(ptr.trait_ref.clone()); + unbound = Some(&ptr.trait_ref); } else { span_err!( tcx.sess, @@ -931,7 +927,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let kind_id = tcx.lang_items().require(SizedTraitLangItem); match unbound { - Some(ref tpb) => { + Some(tpb) => { // FIXME(#8559) currently requires the unbound to be built-in. if let Ok(kind_id) = kind_id { if tpb.path.res != Res::Def(DefKind::Trait, kind_id) { @@ -1052,7 +1048,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &self, hir_ref_id: hir::HirId, trait_ref: ty::PolyTraitRef<'tcx>, - binding: &ConvertedBinding<'tcx>, + binding: &ConvertedBinding<'_, 'tcx>, bounds: &mut Bounds<'tcx>, speculative: bool, dup_bindings: &mut FxHashMap<DefId, Span>, @@ -1169,7 +1165,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } }), binding.span)); } - ConvertedBindingKind::Constraint(ref ast_bounds) => { + ConvertedBindingKind::Constraint(ast_bounds) => { // "Desugar" a constraint like `T: Iterator<Item: Debug>` to // // `<T as Iterator>::Item: Debug` @@ -1765,47 +1761,45 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &self, segments: T) -> bool { let mut has_err = false; for segment in segments { - segment.with_generic_args(|generic_args| { - let (mut err_for_lt, mut err_for_ty, mut err_for_ct) = (false, false, false); - for arg in &generic_args.args { - let (span, kind) = match arg { - hir::GenericArg::Lifetime(lt) => { - if err_for_lt { continue } - err_for_lt = true; - has_err = true; - (lt.span, "lifetime") - } - hir::GenericArg::Type(ty) => { - if err_for_ty { continue } - err_for_ty = true; - has_err = true; - (ty.span, "type") - } - hir::GenericArg::Const(ct) => { - if err_for_ct { continue } - err_for_ct = true; - (ct.span, "const") - } - }; - let mut err = struct_span_err!( - self.tcx().sess, - span, - E0109, - "{} arguments are not allowed for this type", - kind, - ); - err.span_label(span, format!("{} argument not allowed", kind)); - err.emit(); - if err_for_lt && err_for_ty && err_for_ct { - break; + let (mut err_for_lt, mut err_for_ty, mut err_for_ct) = (false, false, false); + for arg in &segment.generic_args().args { + let (span, kind) = match arg { + hir::GenericArg::Lifetime(lt) => { + if err_for_lt { continue } + err_for_lt = true; + has_err = true; + (lt.span, "lifetime") } - } - for binding in &generic_args.bindings { - has_err = true; - Self::prohibit_assoc_ty_binding(self.tcx(), binding.span); + hir::GenericArg::Type(ty) => { + if err_for_ty { continue } + err_for_ty = true; + has_err = true; + (ty.span, "type") + } + hir::GenericArg::Const(ct) => { + if err_for_ct { continue } + err_for_ct = true; + (ct.span, "const") + } + }; + let mut err = struct_span_err!( + self.tcx().sess, + span, + E0109, + "{} arguments are not allowed for this type", + kind, + ); + err.span_label(span, format!("{} argument not allowed", kind)); + err.emit(); + if err_for_lt && err_for_ty && err_for_ct { break; } - }) + } + for binding in &segment.generic_args().bindings { + has_err = true; + Self::prohibit_assoc_ty_binding(self.tcx(), binding.span); + break; + } } has_err } diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 563bb5760a94e..8ca1b85ad9aee 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -1125,7 +1125,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.emit(); } else { - self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name); + self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name, span); } tcx.types.err @@ -1196,6 +1196,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { field: &hir::Field, skip_fields: &[hir::Field], kind_name: &str, + ty_span: Span ) { if variant.recovered { return; @@ -1215,37 +1216,57 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }, ty); - // prevent all specified fields from being suggested - let skip_fields = skip_fields.iter().map(|ref x| x.ident.as_str()); - if let Some(field_name) = Self::suggest_field_name(variant, - &field.ident.as_str(), - skip_fields.collect()) { - err.span_suggestion( - field.ident.span, - "a field with a similar name exists", - field_name.to_string(), - Applicability::MaybeIncorrect, - ); - } else { - match ty.sty { - ty::Adt(adt, ..) => { - if adt.is_enum() { - err.span_label(field.ident.span, - format!("`{}::{}` does not have this field", - ty, variant.ident)); - } else { - err.span_label(field.ident.span, - format!("`{}` does not have this field", ty)); - } - let available_field_names = self.available_field_names(variant); - if !available_field_names.is_empty() { - err.note(&format!("available fields are: {}", - self.name_series_display(available_field_names))); + match variant.ctor_kind { + CtorKind::Fn => { + err.span_label(variant.ident.span, format!("`{adt}` defined here", adt=ty)); + err.span_label(field.ident.span, "field does not exist"); + err.span_label(ty_span, format!( + "`{adt}` is a tuple {kind_name}, \ + use the appropriate syntax: `{adt}(/* fields */)`", + adt=ty, + kind_name=kind_name + )); + } + _ => { + // prevent all specified fields from being suggested + let skip_fields = skip_fields.iter().map(|ref x| x.ident.as_str()); + if let Some(field_name) = Self::suggest_field_name( + variant, + &field.ident.as_str(), + skip_fields.collect() + ) { + err.span_suggestion( + field.ident.span, + "a field with a similar name exists", + field_name.to_string(), + Applicability::MaybeIncorrect, + ); + } else { + match ty.sty { + ty::Adt(adt, ..) => { + if adt.is_enum() { + err.span_label(field.ident.span, format!( + "`{}::{}` does not have this field", + ty, + variant.ident + )); + } else { + err.span_label(field.ident.span, format!( + "`{}` does not have this field", + ty + )); + } + let available_field_names = self.available_field_names(variant); + if !available_field_names.is_empty() { + err.note(&format!("available fields are: {}", + self.name_series_display(available_field_names))); + } + } + _ => bug!("non-ADT passed to report_unknown_field") } - } - _ => bug!("non-ADT passed to report_unknown_field") + }; } - }; + } err.emit(); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index fe742a74fffec..0e83db48284a8 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3696,39 +3696,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise. - fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(hir::FnDecl, ast::Ident)> { + fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl, ast::Ident)> { let parent = self.tcx.hir().get_by_hir_id(self.tcx.hir().get_parent_item(blk_id)); self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident)) } /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise. - fn get_node_fn_decl(&self, node: Node<'_>) -> Option<(hir::FnDecl, ast::Ident, bool)> { + fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl, ast::Ident, bool)> { match node { Node::Item(&hir::Item { ident, node: hir::ItemKind::Fn(ref decl, ..), .. - }) => decl.clone().and_then(|decl| { + }) => { // This is less than ideal, it will not suggest a return type span on any // method called `main`, regardless of whether it is actually the entry point, // but it will still present it as the reason for the expected type. Some((decl, ident, ident.name != sym::main)) - }), + } Node::TraitItem(&hir::TraitItem { ident, node: hir::TraitItemKind::Method(hir::MethodSig { ref decl, .. }, ..), .. - }) => decl.clone().and_then(|decl| Some((decl, ident, true))), + }) => Some((decl, ident, true)), Node::ImplItem(&hir::ImplItem { ident, node: hir::ImplItemKind::Method(hir::MethodSig { ref decl, .. }, ..), .. - }) => decl.clone().and_then(|decl| Some((decl, ident, false))), + }) => Some((decl, ident, false)), _ => None, } } /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a /// suggestion can be made, `None` otherwise. - pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(hir::FnDecl, bool)> { + pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl, bool)> { // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or // `while` before reaching it, as block tail returns are not available in them. self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 5606d9c0ce815..52cda4ac3c628 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -165,7 +165,7 @@ impl ItemCtxt<'tcx> { ItemCtxt { tcx, item_def_id } } - pub fn to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> { + pub fn to_ty(&self, ast_ty: &'tcx hir::Ty) -> Ty<'tcx> { AstConv::ast_ty_to_ty(self, ast_ty) } } @@ -338,7 +338,7 @@ impl ItemCtxt<'tcx> { /// bounds for a type parameter `X` if `X::Foo` is used. fn type_parameter_bounds_in_generics( &self, - ast_generics: &hir::Generics, + ast_generics: &'tcx hir::Generics, param_id: hir::HirId, ty: Ty<'tcx>, only_self_bounds: OnlySelfBounds, @@ -1909,7 +1909,9 @@ fn explicit_predicates_of<'tcx>( let mut is_default_impl_trait = None; let icx = ItemCtxt::new(tcx, def_id); - let no_generics = hir::Generics::empty(); + + const NO_GENERICS: &hir::Generics = &hir::Generics::empty(); + let empty_trait_items = HirVec::new(); let mut predicates = UniquePredicates::new(); @@ -1991,17 +1993,17 @@ fn explicit_predicates_of<'tcx>( } } - _ => &no_generics, + _ => NO_GENERICS, } } Node::ForeignItem(item) => match item.node { - ForeignItemKind::Static(..) => &no_generics, + ForeignItemKind::Static(..) => NO_GENERICS, ForeignItemKind::Fn(_, _, ref generics) => generics, - ForeignItemKind::Type => &no_generics, + ForeignItemKind::Type => NO_GENERICS, }, - _ => &no_generics, + _ => NO_GENERICS, }; let generics = tcx.generics_of(def_id); @@ -2205,7 +2207,7 @@ fn explicit_predicates_of<'tcx>( fn predicates_from_bound<'tcx>( astconv: &dyn AstConv<'tcx>, param_ty: Ty<'tcx>, - bound: &hir::GenericBound, + bound: &'tcx hir::GenericBound, ) -> Vec<(ty::Predicate<'tcx>, Span)> { match *bound { hir::GenericBound::Trait(ref tr, hir::TraitBoundModifier::None) => { @@ -2227,7 +2229,7 @@ fn predicates_from_bound<'tcx>( fn compute_sig_of_foreign_fn_decl<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, - decl: &hir::FnDecl, + decl: &'tcx hir::FnDecl, abi: abi::Abi, ) -> ty::PolyFnSig<'tcx> { let unsafety = if abi == abi::Abi::RustIntrinsic { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 4becb42d30551..b489ccf179c0e 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -159,7 +159,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> { // Clean the crate, translating the entire libsyntax AST to one that is // understood by rustdoc. - let mut module = self.module.clean(cx); + let mut module = self.module.as_ref().unwrap().clean(cx); let mut masked_crates = FxHashSet::default(); match module.inner { @@ -600,7 +600,7 @@ pub struct Module { pub is_crate: bool, } -impl Clean<Item> for doctree::Module { +impl Clean<Item> for doctree::Module<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { let name = if self.name.is_some() { self.name.expect("No name provided").clean(cx) @@ -620,7 +620,7 @@ impl Clean<Item> for doctree::Module { items.extend(self.unions.iter().map(|x| x.clean(cx))); items.extend(self.enums.iter().map(|x| x.clean(cx))); items.extend(self.fns.iter().map(|x| x.clean(cx))); - items.extend(self.foreigns.iter().flat_map(|x| x.clean(cx))); + items.extend(self.foreigns.iter().map(|x| x.clean(cx))); items.extend(self.mods.iter().map(|x| x.clean(cx))); items.extend(self.typedefs.iter().map(|x| x.clean(cx))); items.extend(self.existentials.iter().map(|x| x.clean(cx))); @@ -1920,10 +1920,10 @@ pub struct Function { pub ret_types: Vec<Type>, } -impl Clean<Item> for doctree::Function { +impl Clean<Item> for doctree::Function<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { let (generics, decl) = enter_impl_trait(cx, || { - (self.generics.clean(cx), (&self.decl, self.body).clean(cx)) + (self.generics.clean(cx), (self.decl, self.body).clean(cx)) }); let did = cx.tcx.hir().local_def_id_from_hir_id(self.id); @@ -2128,7 +2128,7 @@ pub struct Trait { pub is_auto: bool, } -impl Clean<Item> for doctree::Trait { +impl Clean<Item> for doctree::Trait<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { let attrs = self.attrs.clean(cx); let is_spotlight = attrs.has_doc_flag(sym::spotlight); @@ -2143,7 +2143,7 @@ impl Clean<Item> for doctree::Trait { inner: TraitItem(Trait { auto: self.is_auto.clean(cx), unsafety: self.unsafety, - items: self.items.clean(cx), + items: self.items.iter().map(|ti| ti.clean(cx)).collect(), generics: self.generics.clean(cx), bounds: self.bounds.clean(cx), is_spotlight, @@ -2159,7 +2159,7 @@ pub struct TraitAlias { pub bounds: Vec<GenericBound>, } -impl Clean<Item> for doctree::TraitAlias { +impl Clean<Item> for doctree::TraitAlias<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { let attrs = self.attrs.clean(cx); Item { @@ -2809,7 +2809,8 @@ impl Clean<Type> for hir::Ty { let mut ty_substs = FxHashMap::default(); let mut lt_substs = FxHashMap::default(); let mut ct_substs = FxHashMap::default(); - provided_params.with_generic_args(|generic_args| { + let generic_args = provided_params.generic_args(); + { let mut indices: GenericParamCount = Default::default(); for param in generics.params.iter() { match param.kind { @@ -2852,11 +2853,11 @@ impl Clean<Type> for hir::Ty { _ => None, } }); - if let Some(ty) = type_.cloned() { + if let Some(ty) = type_ { ty_substs.insert(ty_param_def_id, ty.clean(cx)); } else if let Some(default) = default.clone() { ty_substs.insert(ty_param_def_id, - default.into_inner().clean(cx)); + default.clean(cx)); } indices.types += 1; } @@ -2876,7 +2877,7 @@ impl Clean<Type> for hir::Ty { _ => None, } }); - if let Some(ct) = const_.cloned() { + if let Some(ct) = const_ { ct_substs.insert(const_param_def_id, ct.clean(cx)); } // FIXME(const_generics:defaults) @@ -2884,26 +2885,26 @@ impl Clean<Type> for hir::Ty { } } } - }); + } return cx.enter_alias(ty_substs, lt_substs, ct_substs, || ty.clean(cx)); } resolve_type(cx, path.clean(cx), self.hir_id) } TyKind::Path(hir::QPath::Resolved(Some(ref qself), ref p)) => { - let mut segments: Vec<_> = p.segments.clone().into(); - segments.pop(); - let trait_path = hir::Path { - span: p.span, + let segments = if p.is_global() { &p.segments[1..] } else { &p.segments }; + let trait_segments = &segments[..segments.len() - 1]; + let trait_path = self::Path { + global: p.is_global(), res: Res::Def( DefKind::Trait, cx.tcx.associated_item(p.res.def_id()).container.id(), ), - segments: segments.into(), + segments: trait_segments.clean(cx), }; Type::QPath { name: p.segments.last().expect("segments were empty").ident.name.clean(cx), self_type: box qself.clean(cx), - trait_: box resolve_type(cx, trait_path.clean(cx), self.hir_id) + trait_: box resolve_type(cx, trait_path, self.hir_id) } } TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => { @@ -3234,7 +3235,7 @@ pub struct Union { pub fields_stripped: bool, } -impl Clean<Item> for doctree::Struct { +impl Clean<Item> for doctree::Struct<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { Item { name: Some(self.name.clean(cx)), @@ -3254,7 +3255,7 @@ impl Clean<Item> for doctree::Struct { } } -impl Clean<Item> for doctree::Union { +impl Clean<Item> for doctree::Union<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { Item { name: Some(self.name.clean(cx)), @@ -3301,7 +3302,7 @@ pub struct Enum { pub variants_stripped: bool, } -impl Clean<Item> for doctree::Enum { +impl Clean<Item> for doctree::Enum<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { Item { name: Some(self.name.clean(cx)), @@ -3325,7 +3326,7 @@ pub struct Variant { pub kind: VariantKind, } -impl Clean<Item> for doctree::Variant { +impl Clean<Item> for doctree::Variant<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { Item { name: Some(self.name.clean(cx)), @@ -3537,7 +3538,7 @@ impl Clean<PathSegment> for hir::PathSegment { fn clean(&self, cx: &DocContext<'_>) -> PathSegment { PathSegment { name: self.ident.name.clean(cx), - args: self.with_generic_args(|generic_args| generic_args.clean(cx)) + args: self.generic_args().clean(cx), } } } @@ -3630,7 +3631,7 @@ pub struct Typedef { pub generics: Generics, } -impl Clean<Item> for doctree::Typedef { +impl Clean<Item> for doctree::Typedef<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { Item { name: Some(self.name.clean(cx)), @@ -3654,7 +3655,7 @@ pub struct Existential { pub generics: Generics, } -impl Clean<Item> for doctree::Existential { +impl Clean<Item> for doctree::Existential<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { Item { name: Some(self.name.clean(cx)), @@ -3704,7 +3705,7 @@ pub struct Static { pub expr: String, } -impl Clean<Item> for doctree::Static { +impl Clean<Item> for doctree::Static<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { debug!("cleaning static {}: {:?}", self.name.clean(cx), self); Item { @@ -3730,7 +3731,7 @@ pub struct Constant { pub expr: String, } -impl Clean<Item> for doctree::Constant { +impl Clean<Item> for doctree::Constant<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { Item { name: Some(self.name.clean(cx)), @@ -3800,11 +3801,11 @@ pub fn get_auto_trait_and_blanket_impls( .chain(BlanketImplFinder::new(cx).get_blanket_impls(ty, param_env_def_id)) } -impl Clean<Vec<Item>> for doctree::Impl { +impl Clean<Vec<Item>> for doctree::Impl<'_> { fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> { let mut ret = Vec::new(); let trait_ = self.trait_.clean(cx); - let items = self.items.clean(cx); + let items = self.items.iter().map(|ii| ii.clean(cx)).collect::<Vec<_>>(); // If this impl block is an implementation of the Deref trait, then we // need to try inlining the target's inherent impl blocks as well. @@ -3901,7 +3902,7 @@ fn build_deref_target_impls(cx: &DocContext<'_>, } } -impl Clean<Vec<Item>> for doctree::ExternCrate { +impl Clean<Vec<Item>> for doctree::ExternCrate<'_> { fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> { let please_inline = self.vis.node.is_pub() && self.attrs.iter().any(|a| { @@ -3940,7 +3941,7 @@ impl Clean<Vec<Item>> for doctree::ExternCrate { } } -impl Clean<Vec<Item>> for doctree::Import { +impl Clean<Vec<Item>> for doctree::Import<'_> { fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> { // We consider inlining the documentation of `pub use` statements, but we // forcefully don't inline if this is not public or if the @@ -4016,22 +4017,11 @@ pub struct ImportSource { pub did: Option<DefId>, } -impl Clean<Vec<Item>> for hir::ForeignMod { - fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> { - let mut items = self.items.clean(cx); - for item in &mut items { - if let ForeignFunctionItem(ref mut f) = item.inner { - f.header.abi = self.abi; - } - } - items - } -} - -impl Clean<Item> for hir::ForeignItem { +impl Clean<Item> for doctree::ForeignItem<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { - let inner = match self.node { + let inner = match self.kind { hir::ForeignItemKind::Fn(ref decl, ref names, ref generics) => { + let abi = cx.tcx.hir().get_foreign_abi(self.id); let (generics, decl) = enter_impl_trait(cx, || { (generics.clean(cx), (&**decl, &names[..]).clean(cx)) }); @@ -4041,7 +4031,7 @@ impl Clean<Item> for hir::ForeignItem { generics, header: hir::FnHeader { unsafety: hir::Unsafety::Unsafe, - abi: Abi::Rust, + abi, constness: hir::Constness::NotConst, asyncness: hir::IsAsync::NotAsync, }, @@ -4061,16 +4051,14 @@ impl Clean<Item> for hir::ForeignItem { } }; - let local_did = cx.tcx.hir().local_def_id_from_hir_id(self.hir_id); - Item { - name: Some(self.ident.clean(cx)), + name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), - source: self.span.clean(cx), - def_id: local_did, + source: self.whence.clean(cx), + def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id), visibility: self.vis.clean(cx), - stability: get_stability(cx, local_did), - deprecation: get_deprecation(cx, local_did), + stability: self.stab.clean(cx), + deprecation: self.depr.clean(cx), inner, } } @@ -4245,7 +4233,7 @@ pub struct Macro { pub imported_from: Option<String>, } -impl Clean<Item> for doctree::Macro { +impl Clean<Item> for doctree::Macro<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { let name = self.name.clean(cx); Item { @@ -4274,7 +4262,7 @@ pub struct ProcMacro { pub helpers: Vec<String>, } -impl Clean<Item> for doctree::ProcMacro { +impl Clean<Item> for doctree::ProcMacro<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { Item { name: Some(self.name.clean(cx)), diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 7a528e50e9c3f..51deb4e9b9747 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -7,52 +7,55 @@ use syntax::ast::{Name, NodeId}; use syntax::attr; use syntax::ext::base::MacroKind; use syntax::ptr::P; -use syntax::source_map::Spanned; use syntax_pos::{self, Span}; use rustc::hir; use rustc::hir::def_id::CrateNum; -pub struct Module { +pub struct Module<'hir> { pub name: Option<Name>, - pub attrs: hir::HirVec<ast::Attribute>, + pub attrs: &'hir hir::HirVec<ast::Attribute>, pub where_outer: Span, pub where_inner: Span, - pub extern_crates: Vec<ExternCrate>, - pub imports: Vec<Import>, - pub structs: Vec<Struct>, - pub unions: Vec<Union>, - pub enums: Vec<Enum>, - pub fns: Vec<Function>, - pub mods: Vec<Module>, + pub extern_crates: Vec<ExternCrate<'hir>>, + pub imports: Vec<Import<'hir>>, + pub structs: Vec<Struct<'hir>>, + pub unions: Vec<Union<'hir>>, + pub enums: Vec<Enum<'hir>>, + pub fns: Vec<Function<'hir>>, + pub mods: Vec<Module<'hir>>, pub id: NodeId, - pub typedefs: Vec<Typedef>, - pub existentials: Vec<Existential>, - pub statics: Vec<Static>, - pub constants: Vec<Constant>, - pub traits: Vec<Trait>, - pub vis: hir::Visibility, + pub typedefs: Vec<Typedef<'hir>>, + pub existentials: Vec<Existential<'hir>>, + pub statics: Vec<Static<'hir>>, + pub constants: Vec<Constant<'hir>>, + pub traits: Vec<Trait<'hir>>, + pub vis: &'hir hir::Visibility, pub stab: Option<attr::Stability>, pub depr: Option<attr::Deprecation>, - pub impls: Vec<Impl>, - pub foreigns: Vec<hir::ForeignMod>, - pub macros: Vec<Macro>, - pub proc_macros: Vec<ProcMacro>, - pub trait_aliases: Vec<TraitAlias>, + pub impls: Vec<Impl<'hir>>, + pub foreigns: Vec<ForeignItem<'hir>>, + pub macros: Vec<Macro<'hir>>, + pub proc_macros: Vec<ProcMacro<'hir>>, + pub trait_aliases: Vec<TraitAlias<'hir>>, pub is_crate: bool, } -impl Module { - pub fn new(name: Option<Name>) -> Module { +impl Module<'hir> { + pub fn new( + name: Option<Name>, + attrs: &'hir hir::HirVec<ast::Attribute>, + vis: &'hir hir::Visibility, + ) -> Module<'hir> { Module { name : name, id: ast::CRATE_NODE_ID, - vis: Spanned { span: syntax_pos::DUMMY_SP, node: hir::VisibilityKind::Inherited }, + vis, stab: None, depr: None, where_outer: syntax_pos::DUMMY_SP, where_inner: syntax_pos::DUMMY_SP, - attrs : hir::HirVec::new(), + attrs, extern_crates: Vec::new(), imports : Vec::new(), structs : Vec::new(), @@ -85,167 +88,178 @@ pub enum StructType { Unit, } -pub struct Struct { - pub vis: hir::Visibility, +pub struct Struct<'hir> { + pub vis: &'hir hir::Visibility, pub stab: Option<attr::Stability>, pub depr: Option<attr::Deprecation>, pub id: hir::HirId, pub struct_type: StructType, pub name: Name, - pub generics: hir::Generics, - pub attrs: hir::HirVec<ast::Attribute>, - pub fields: hir::HirVec<hir::StructField>, + pub generics: &'hir hir::Generics, + pub attrs: &'hir hir::HirVec<ast::Attribute>, + pub fields: &'hir [hir::StructField], pub whence: Span, } -pub struct Union { - pub vis: hir::Visibility, +pub struct Union<'hir> { + pub vis: &'hir hir::Visibility, pub stab: Option<attr::Stability>, pub depr: Option<attr::Deprecation>, pub id: hir::HirId, pub struct_type: StructType, pub name: Name, - pub generics: hir::Generics, - pub attrs: hir::HirVec<ast::Attribute>, - pub fields: hir::HirVec<hir::StructField>, + pub generics: &'hir hir::Generics, + pub attrs: &'hir hir::HirVec<ast::Attribute>, + pub fields: &'hir [hir::StructField], pub whence: Span, } -pub struct Enum { - pub vis: hir::Visibility, +pub struct Enum<'hir> { + pub vis: &'hir hir::Visibility, pub stab: Option<attr::Stability>, pub depr: Option<attr::Deprecation>, - pub variants: hir::HirVec<Variant>, - pub generics: hir::Generics, - pub attrs: hir::HirVec<ast::Attribute>, + pub variants: Vec<Variant<'hir>>, + pub generics: &'hir hir::Generics, + pub attrs: &'hir hir::HirVec<ast::Attribute>, pub id: hir::HirId, pub whence: Span, pub name: Name, } -pub struct Variant { +pub struct Variant<'hir> { pub name: Name, pub id: hir::HirId, - pub attrs: hir::HirVec<ast::Attribute>, - pub def: hir::VariantData, + pub attrs: &'hir hir::HirVec<ast::Attribute>, + pub def: &'hir hir::VariantData, pub stab: Option<attr::Stability>, pub depr: Option<attr::Deprecation>, pub whence: Span, } -pub struct Function { - pub decl: hir::FnDecl, - pub attrs: hir::HirVec<ast::Attribute>, +pub struct Function<'hir> { + pub decl: &'hir hir::FnDecl, + pub attrs: &'hir hir::HirVec<ast::Attribute>, pub id: hir::HirId, pub name: Name, - pub vis: hir::Visibility, + pub vis: &'hir hir::Visibility, pub stab: Option<attr::Stability>, pub depr: Option<attr::Deprecation>, pub header: hir::FnHeader, pub whence: Span, - pub generics: hir::Generics, + pub generics: &'hir hir::Generics, pub body: hir::BodyId, } -pub struct Typedef { - pub ty: P<hir::Ty>, - pub gen: hir::Generics, +pub struct Typedef<'hir> { + pub ty: &'hir P<hir::Ty>, + pub gen: &'hir hir::Generics, pub name: Name, pub id: hir::HirId, - pub attrs: hir::HirVec<ast::Attribute>, + pub attrs: &'hir hir::HirVec<ast::Attribute>, pub whence: Span, - pub vis: hir::Visibility, + pub vis: &'hir hir::Visibility, pub stab: Option<attr::Stability>, pub depr: Option<attr::Deprecation>, } -pub struct Existential { - pub exist_ty: hir::ExistTy, +pub struct Existential<'hir> { + pub exist_ty: &'hir hir::ExistTy, pub name: Name, pub id: hir::HirId, - pub attrs: hir::HirVec<ast::Attribute>, + pub attrs: &'hir hir::HirVec<ast::Attribute>, pub whence: Span, - pub vis: hir::Visibility, + pub vis: &'hir hir::Visibility, pub stab: Option<attr::Stability>, pub depr: Option<attr::Deprecation>, } #[derive(Debug)] -pub struct Static { - pub type_: P<hir::Ty>, +pub struct Static<'hir> { + pub type_: &'hir P<hir::Ty>, pub mutability: hir::Mutability, pub expr: hir::BodyId, pub name: Name, - pub attrs: hir::HirVec<ast::Attribute>, - pub vis: hir::Visibility, + pub attrs: &'hir hir::HirVec<ast::Attribute>, + pub vis: &'hir hir::Visibility, pub stab: Option<attr::Stability>, pub depr: Option<attr::Deprecation>, pub id: hir::HirId, pub whence: Span, } -pub struct Constant { - pub type_: P<hir::Ty>, +pub struct Constant<'hir> { + pub type_: &'hir P<hir::Ty>, pub expr: hir::BodyId, pub name: Name, - pub attrs: hir::HirVec<ast::Attribute>, - pub vis: hir::Visibility, + pub attrs: &'hir hir::HirVec<ast::Attribute>, + pub vis: &'hir hir::Visibility, pub stab: Option<attr::Stability>, pub depr: Option<attr::Deprecation>, pub id: hir::HirId, pub whence: Span, } -pub struct Trait { +pub struct Trait<'hir> { pub is_auto: hir::IsAuto, pub unsafety: hir::Unsafety, pub name: Name, - pub items: hir::HirVec<hir::TraitItem>, - pub generics: hir::Generics, - pub bounds: hir::HirVec<hir::GenericBound>, - pub attrs: hir::HirVec<ast::Attribute>, + pub items: Vec<&'hir hir::TraitItem>, + pub generics: &'hir hir::Generics, + pub bounds: &'hir hir::HirVec<hir::GenericBound>, + pub attrs: &'hir hir::HirVec<ast::Attribute>, pub id: hir::HirId, pub whence: Span, - pub vis: hir::Visibility, + pub vis: &'hir hir::Visibility, pub stab: Option<attr::Stability>, pub depr: Option<attr::Deprecation>, } -pub struct TraitAlias { +pub struct TraitAlias<'hir> { pub name: Name, - pub generics: hir::Generics, - pub bounds: hir::HirVec<hir::GenericBound>, - pub attrs: hir::HirVec<ast::Attribute>, + pub generics: &'hir hir::Generics, + pub bounds: &'hir hir::HirVec<hir::GenericBound>, + pub attrs: &'hir hir::HirVec<ast::Attribute>, pub id: hir::HirId, pub whence: Span, - pub vis: hir::Visibility, + pub vis: &'hir hir::Visibility, pub stab: Option<attr::Stability>, pub depr: Option<attr::Deprecation>, } #[derive(Debug)] -pub struct Impl { +pub struct Impl<'hir> { pub unsafety: hir::Unsafety, pub polarity: hir::ImplPolarity, pub defaultness: hir::Defaultness, - pub generics: hir::Generics, - pub trait_: Option<hir::TraitRef>, - pub for_: P<hir::Ty>, - pub items: hir::HirVec<hir::ImplItem>, - pub attrs: hir::HirVec<ast::Attribute>, + pub generics: &'hir hir::Generics, + pub trait_: &'hir Option<hir::TraitRef>, + pub for_: &'hir P<hir::Ty>, + pub items: Vec<&'hir hir::ImplItem>, + pub attrs: &'hir hir::HirVec<ast::Attribute>, pub whence: Span, - pub vis: hir::Visibility, + pub vis: &'hir hir::Visibility, pub stab: Option<attr::Stability>, pub depr: Option<attr::Deprecation>, pub id: hir::HirId, } +pub struct ForeignItem<'hir> { + pub vis: &'hir hir::Visibility, + pub stab: Option<attr::Stability>, + pub depr: Option<attr::Deprecation>, + pub id: hir::HirId, + pub name: Name, + pub kind: &'hir hir::ForeignItemKind, + pub attrs: &'hir hir::HirVec<ast::Attribute>, + pub whence: Span, +} + // For Macro we store the DefId instead of the NodeId, since we also create // these imported macro_rules (which only have a DUMMY_NODE_ID). -pub struct Macro { +pub struct Macro<'hir> { pub name: Name, pub def_id: hir::def_id::DefId, - pub attrs: hir::HirVec<ast::Attribute>, + pub attrs: &'hir hir::HirVec<ast::Attribute>, pub whence: Span, pub matchers: hir::HirVec<Span>, pub stab: Option<attr::Stability>, @@ -253,31 +267,31 @@ pub struct Macro { pub imported_from: Option<Name>, } -pub struct ExternCrate { +pub struct ExternCrate<'hir> { pub name: Name, pub cnum: CrateNum, pub path: Option<String>, - pub vis: hir::Visibility, - pub attrs: hir::HirVec<ast::Attribute>, + pub vis: &'hir hir::Visibility, + pub attrs: &'hir hir::HirVec<ast::Attribute>, pub whence: Span, } -pub struct Import { +pub struct Import<'hir> { pub name: Name, pub id: hir::HirId, - pub vis: hir::Visibility, - pub attrs: hir::HirVec<ast::Attribute>, - pub path: hir::Path, + pub vis: &'hir hir::Visibility, + pub attrs: &'hir hir::HirVec<ast::Attribute>, + pub path: &'hir hir::Path, pub glob: bool, pub whence: Span, } -pub struct ProcMacro { +pub struct ProcMacro<'hir> { pub name: Name, pub id: hir::HirId, pub kind: MacroKind, pub helpers: Vec<Name>, - pub attrs: hir::HirVec<ast::Attribute>, + pub attrs: &'hir hir::HirVec<ast::Attribute>, pub whence: Span, pub stab: Option<attr::Stability>, pub depr: Option<attr::Deprecation>, diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index ff76579d67d21..c94149d31020a 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -29,8 +29,7 @@ use crate::doctree::*; // framework from syntax?. pub struct RustdocVisitor<'a, 'tcx> { - pub module: Module, - pub attrs: hir::HirVec<ast::Attribute>, + pub module: Option<Module<'tcx>>, pub cx: &'a core::DocContext<'tcx>, view_item_stack: FxHashSet<hir::HirId>, inlining: bool, @@ -47,8 +46,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { let mut stack = FxHashSet::default(); stack.insert(hir::CRATE_HIR_ID); RustdocVisitor { - module: Module::new(None), - attrs: hir::HirVec::new(), + module: None, cx, view_item_stack: stack, inlining: false, @@ -77,92 +75,91 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { .and_then(|def_id| self.cx.tcx.lookup_deprecation(def_id)) } - pub fn visit(&mut self, krate: &hir::Crate) { - self.attrs = krate.attrs.clone(); - - self.module = self.visit_mod_contents(krate.span, - krate.attrs.clone(), - Spanned { span: syntax_pos::DUMMY_SP, + pub fn visit(&mut self, krate: &'tcx hir::Crate) { + let mut module = self.visit_mod_contents(krate.span, + &krate.attrs, + &Spanned { span: syntax_pos::DUMMY_SP, node: hir::VisibilityKind::Public }, hir::CRATE_HIR_ID, &krate.module, None); // Attach the crate's exported macros to the top-level module: - let macro_exports: Vec<_> = - krate.exported_macros.iter().map(|def| self.visit_local_macro(def, None)).collect(); - self.module.macros.extend(macro_exports); - self.module.is_crate = true; + module.macros.extend( + krate.exported_macros.iter().map(|def| self.visit_local_macro(def, None)), + ); + module.is_crate = true; + self.module = Some(module); self.cx.renderinfo.borrow_mut().exact_paths = self.exact_paths.take().unwrap(); } - pub fn visit_variant_data(&mut self, item: &hir::Item, - name: ast::Name, sd: &hir::VariantData, - generics: &hir::Generics) -> Struct { + pub fn visit_variant_data(&mut self, item: &'tcx hir::Item, + name: ast::Name, sd: &'tcx hir::VariantData, + generics: &'tcx hir::Generics) -> Struct<'tcx> { debug!("Visiting struct"); let struct_type = struct_type_from_def(&*sd); Struct { id: item.hir_id, struct_type, name, - vis: item.vis.clone(), + vis: &item.vis, stab: self.stability(item.hir_id), depr: self.deprecation(item.hir_id), - attrs: item.attrs.clone(), - generics: generics.clone(), - fields: sd.fields().iter().cloned().collect(), + attrs: &item.attrs, + generics, + fields: sd.fields(), whence: item.span } } - pub fn visit_union_data(&mut self, item: &hir::Item, - name: ast::Name, sd: &hir::VariantData, - generics: &hir::Generics) -> Union { + pub fn visit_union_data(&mut self, item: &'tcx hir::Item, + name: ast::Name, sd: &'tcx hir::VariantData, + generics: &'tcx hir::Generics) -> Union<'tcx> { debug!("Visiting union"); let struct_type = struct_type_from_def(&*sd); Union { id: item.hir_id, struct_type, name, - vis: item.vis.clone(), + vis: &item.vis, stab: self.stability(item.hir_id), depr: self.deprecation(item.hir_id), - attrs: item.attrs.clone(), - generics: generics.clone(), - fields: sd.fields().iter().cloned().collect(), + attrs: &item.attrs, + generics, + fields: sd.fields(), whence: item.span } } - pub fn visit_enum_def(&mut self, it: &hir::Item, - name: ast::Name, def: &hir::EnumDef, - params: &hir::Generics) -> Enum { + pub fn visit_enum_def(&mut self, it: &'tcx hir::Item, + name: ast::Name, def: &'tcx hir::EnumDef, + generics: &'tcx hir::Generics) -> Enum<'tcx> { debug!("Visiting enum"); Enum { name, variants: def.variants.iter().map(|v| Variant { name: v.node.ident.name, id: v.node.id, - attrs: v.node.attrs.clone(), + attrs: &v.node.attrs, stab: self.stability(v.node.id), depr: self.deprecation(v.node.id), - def: v.node.data.clone(), + def: &v.node.data, whence: v.span, }).collect(), - vis: it.vis.clone(), + vis: &it.vis, stab: self.stability(it.hir_id), depr: self.deprecation(it.hir_id), - generics: params.clone(), - attrs: it.attrs.clone(), + generics, + attrs: &it.attrs, id: it.hir_id, whence: it.span, } } - pub fn visit_fn(&mut self, om: &mut Module, item: &hir::Item, - name: ast::Name, fd: &hir::FnDecl, + pub fn visit_fn(&mut self, om: &mut Module<'tcx>, item: &'tcx hir::Item, + name: ast::Name, decl: &'tcx hir::FnDecl, header: hir::FnHeader, - gen: &hir::Generics, + generics: &'tcx hir::Generics, body: hir::BodyId) { debug!("Visiting fn"); let macro_kind = item.attrs.iter().filter_map(|a| { @@ -208,7 +205,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { id: item.hir_id, kind, helpers, - attrs: item.attrs.clone(), + attrs: &item.attrs, whence: item.span, stab: self.stability(item.hir_id), depr: self.deprecation(item.hir_id), @@ -217,14 +214,14 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { None => { om.fns.push(Function { id: item.hir_id, - vis: item.vis.clone(), + vis: &item.vis, stab: self.stability(item.hir_id), depr: self.deprecation(item.hir_id), - attrs: item.attrs.clone(), - decl: fd.clone(), + attrs: &item.attrs, + decl, name, whence: item.span, - generics: gen.clone(), + generics, header, body, }); @@ -232,15 +229,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } } - pub fn visit_mod_contents(&mut self, span: Span, attrs: hir::HirVec<ast::Attribute>, - vis: hir::Visibility, id: hir::HirId, - m: &hir::Mod, - name: Option<ast::Name>) -> Module { - let mut om = Module::new(name); + pub fn visit_mod_contents(&mut self, span: Span, attrs: &'tcx hir::HirVec<ast::Attribute>, + vis: &'tcx hir::Visibility, id: hir::HirId, + m: &'tcx hir::Mod, + name: Option<ast::Name>) -> Module<'tcx> { + let mut om = Module::new(name, attrs, vis); om.where_outer = span; om.where_inner = m.inner; - om.attrs = attrs; - om.vis = vis.clone(); om.stab = self.stability(id); om.depr = self.deprecation(id); om.id = self.cx.tcx.hir().hir_to_node_id(id); @@ -269,7 +264,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { res: Res, renamed: Option<ast::Ident>, glob: bool, - om: &mut Module, + om: &mut Module<'tcx>, please_inline: bool) -> bool { fn inherits_doc_hidden(cx: &core::DocContext<'_>, mut node: hir::HirId) -> bool { @@ -359,14 +354,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { true } Node::ForeignItem(it) if !glob => { - // Generate a fresh `extern {}` block if we want to inline a foreign item. - om.foreigns.push(hir::ForeignMod { - abi: tcx.hir().get_foreign_abi(it.hir_id), - items: vec![hir::ForeignItem { - ident: renamed.unwrap_or(it.ident), - .. it.clone() - }].into(), - }); + let prev = mem::replace(&mut self.inlining, true); + self.visit_foreign_item(it, renamed, om); + self.inlining = prev; true } Node::MacroDef(def) if !glob => { @@ -379,8 +369,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { ret } - pub fn visit_item(&mut self, item: &hir::Item, - renamed: Option<ast::Ident>, om: &mut Module) { + pub fn visit_item(&mut self, item: &'tcx hir::Item, + renamed: Option<ast::Ident>, om: &mut Module<'tcx>) { debug!("Visiting item {:?}", item); let ident = renamed.unwrap_or(item.ident); @@ -391,15 +381,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { match item.node { hir::ItemKind::ForeignMod(ref fm) => { - // If inlining we only want to include public functions. - om.foreigns.push(if self.inlining { - hir::ForeignMod { - abi: fm.abi, - items: fm.items.iter().filter(|i| i.vis.node.is_pub()).cloned().collect(), - } - } else { - fm.clone() - }); + for item in &fm.items { + self.visit_foreign_item(item, None, om); + } } // If we're inlining, skip private items. _ if self.inlining && !item.vis.node.is_pub() => {} @@ -411,8 +395,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { .unwrap_or(LOCAL_CRATE), name: ident.name, path: orig_name.map(|x|x.to_string()), - vis: item.vis.clone(), - attrs: item.attrs.clone(), + vis: &item.vis, + attrs: &item.attrs, whence: item.span, }) } @@ -454,17 +438,17 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { om.imports.push(Import { name: ident.name, id: item.hir_id, - vis: item.vis.clone(), - attrs: item.attrs.clone(), - path: (**path).clone(), + vis: &item.vis, + attrs: &item.attrs, + path, glob: is_glob, whence: item.span, }); } hir::ItemKind::Mod(ref m) => { om.mods.push(self.visit_mod_contents(item.span, - item.attrs.clone(), - item.vis.clone(), + &item.attrs, + &item.vis, item.hir_id, m, Some(ident.name))); @@ -479,13 +463,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { self.visit_fn(om, item, ident.name, &**fd, header, gen, body), hir::ItemKind::Ty(ref ty, ref gen) => { let t = Typedef { - ty: ty.clone(), - gen: gen.clone(), + ty, + gen, name: ident.name, id: item.hir_id, - attrs: item.attrs.clone(), + attrs: &item.attrs, whence: item.span, - vis: item.vis.clone(), + vis: &item.vis, stab: self.stability(item.hir_id), depr: self.deprecation(item.hir_id), }; @@ -493,75 +477,75 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { }, hir::ItemKind::Existential(ref exist_ty) => { let t = Existential { - exist_ty: exist_ty.clone(), + exist_ty, name: ident.name, id: item.hir_id, - attrs: item.attrs.clone(), + attrs: &item.attrs, whence: item.span, - vis: item.vis.clone(), + vis: &item.vis, stab: self.stability(item.hir_id), depr: self.deprecation(item.hir_id), }; om.existentials.push(t); }, - hir::ItemKind::Static(ref ty, ref mut_, ref exp) => { + hir::ItemKind::Static(ref type_, mutability, expr) => { let s = Static { - type_: ty.clone(), - mutability: mut_.clone(), - expr: exp.clone(), + type_, + mutability, + expr, id: item.hir_id, name: ident.name, - attrs: item.attrs.clone(), + attrs: &item.attrs, whence: item.span, - vis: item.vis.clone(), + vis: &item.vis, stab: self.stability(item.hir_id), depr: self.deprecation(item.hir_id), }; om.statics.push(s); }, - hir::ItemKind::Const(ref ty, ref exp) => { + hir::ItemKind::Const(ref type_, expr) => { let s = Constant { - type_: ty.clone(), - expr: exp.clone(), + type_, + expr, id: item.hir_id, name: ident.name, - attrs: item.attrs.clone(), + attrs: &item.attrs, whence: item.span, - vis: item.vis.clone(), + vis: &item.vis, stab: self.stability(item.hir_id), depr: self.deprecation(item.hir_id), }; om.constants.push(s); }, - hir::ItemKind::Trait(is_auto, unsafety, ref gen, ref b, ref item_ids) => { + hir::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref item_ids) => { let items = item_ids.iter() - .map(|ti| self.cx.tcx.hir().trait_item(ti.id).clone()) + .map(|ti| self.cx.tcx.hir().trait_item(ti.id)) .collect(); let t = Trait { is_auto, unsafety, name: ident.name, items, - generics: gen.clone(), - bounds: b.iter().cloned().collect(), + generics, + bounds, id: item.hir_id, - attrs: item.attrs.clone(), + attrs: &item.attrs, whence: item.span, - vis: item.vis.clone(), + vis: &item.vis, stab: self.stability(item.hir_id), depr: self.deprecation(item.hir_id), }; om.traits.push(t); }, - hir::ItemKind::TraitAlias(ref gen, ref b) => { + hir::ItemKind::TraitAlias(ref generics, ref bounds) => { let t = TraitAlias { name: ident.name, - generics: gen.clone(), - bounds: b.iter().cloned().collect(), + generics, + bounds, id: item.hir_id, - attrs: item.attrs.clone(), + attrs: &item.attrs, whence: item.span, - vis: item.vis.clone(), + vis: &item.vis, stab: self.stability(item.hir_id), depr: self.deprecation(item.hir_id), }; @@ -571,28 +555,28 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { hir::ItemKind::Impl(unsafety, polarity, defaultness, - ref gen, - ref tr, - ref ty, + ref generics, + ref trait_, + ref for_, ref item_ids) => { // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick // them up regardless of where they're located. - if !self.inlining && tr.is_none() { + if !self.inlining && trait_.is_none() { let items = item_ids.iter() - .map(|ii| self.cx.tcx.hir().impl_item(ii.id).clone()) + .map(|ii| self.cx.tcx.hir().impl_item(ii.id)) .collect(); let i = Impl { unsafety, polarity, defaultness, - generics: gen.clone(), - trait_: tr.clone(), - for_: ty.clone(), + generics, + trait_, + for_, items, - attrs: item.attrs.clone(), + attrs: &item.attrs, id: item.hir_id, whence: item.span, - vis: item.vis.clone(), + vis: &item.vis, stab: self.stability(item.hir_id), depr: self.deprecation(item.hir_id), }; @@ -602,12 +586,31 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } } + fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem, + renamed: Option<ast::Ident>, om: &mut Module<'tcx>) { + // If inlining we only want to include public functions. + if self.inlining && !item.vis.node.is_pub() { + return; + } + + om.foreigns.push(ForeignItem { + id: item.hir_id, + name: renamed.unwrap_or(item.ident).name, + kind: &item.node, + vis: &item.vis, + stab: self.stability(item.hir_id), + depr: self.deprecation(item.hir_id), + attrs: &item.attrs, + whence: item.span + }); + } + // Convert each `exported_macro` into a doc item. fn visit_local_macro( &self, - def: &hir::MacroDef, + def: &'tcx hir::MacroDef, renamed: Option<ast::Name> - ) -> Macro { + ) -> Macro<'tcx> { debug!("visit_local_macro: {}", def.name); let tts = def.body.trees().collect::<Vec<_>>(); // Extract the spans of all matchers. They represent the "interface" of the macro. @@ -616,7 +619,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { Macro { def_id: self.cx.tcx.hir().local_def_id_from_hir_id(def.hir_id), - attrs: def.attrs.clone(), + attrs: &def.attrs, name: renamed.unwrap_or(def.name), whence: def.span, matchers, diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 55db8da327673..337b84247361d 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -12,6 +12,8 @@ #![deny(unused_lifetimes)] #![feature(bind_by_move_pattern_guards)] +#![feature(const_fn)] +#![feature(const_transmute)] #![feature(crate_visibility_modifier)] #![feature(label_break_value)] #![feature(nll)] diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs index d577243fb3dcd..f0cfa5a84a827 100644 --- a/src/libsyntax/ptr.rs +++ b/src/libsyntax/ptr.rs @@ -133,8 +133,15 @@ impl<T: Encodable> Encodable for P<T> { } impl<T> P<[T]> { - pub fn new() -> P<[T]> { - P { ptr: Default::default() } + pub const fn new() -> P<[T]> { + // HACK(eddyb) bypass the lack of a `const fn` to create an empty `Box<[T]>` + // (as trait methods, `default` in this case, can't be `const fn` yet). + P { + ptr: unsafe { + use std::ptr::NonNull; + std::mem::transmute(NonNull::<[T; 0]>::dangling() as NonNull<[T]>) + }, + } } #[inline(never)] diff --git a/src/test/ui/issues/issue-4736.stderr b/src/test/ui/issues/issue-4736.stderr index b4ac12643bcac..257ec914a61ca 100644 --- a/src/test/ui/issues/issue-4736.stderr +++ b/src/test/ui/issues/issue-4736.stderr @@ -1,8 +1,13 @@ error[E0560]: struct `NonCopyable` has no field named `p` --> $DIR/issue-4736.rs:4:26 | +LL | struct NonCopyable(()); + | ----------- `NonCopyable` defined here +... LL | let z = NonCopyable{ p: () }; - | ^ help: a field with a similar name exists: `0` + | ----------- ^ field does not exist + | | + | `NonCopyable` is a tuple struct, use the appropriate syntax: `NonCopyable(/* fields */)` error: aborting due to previous error diff --git a/src/test/ui/numeric/numeric-fields.stderr b/src/test/ui/numeric/numeric-fields.stderr index 13c18d740fc1c..5202393f559c9 100644 --- a/src/test/ui/numeric/numeric-fields.stderr +++ b/src/test/ui/numeric/numeric-fields.stderr @@ -1,10 +1,13 @@ error[E0560]: struct `S` has no field named `0b1` --> $DIR/numeric-fields.rs:4:15 | +LL | struct S(u8, u16); + | - `S` defined here +... LL | let s = S{0b1: 10, 0: 11}; - | ^^^ `S` does not have this field - | - = note: available fields are: `0`, `1` + | - ^^^ field does not exist + | | + | `S` is a tuple struct, use the appropriate syntax: `S(/* fields */)` error[E0026]: struct `S` does not have a field named `0x1` --> $DIR/numeric-fields.rs:7:17