From 887feeeaf7d40c25caa9532f2d9121cb79fca899 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 12 Jun 2019 11:42:58 +0300 Subject: [PATCH 1/2] rustc: replace `GenericArgs::with_generic_args` hack with a plain getter. --- src/librustc/hir/mod.rs | 18 +++--- src/librustc/hir/print.rs | 49 ++++++--------- src/librustc_typeck/astconv.rs | 106 ++++++++++++++++----------------- src/librustdoc/clean/mod.rs | 7 ++- src/libsyntax/lib.rs | 2 + src/libsyntax/ptr.rs | 11 +++- 6 files changed, 91 insertions(+), 102 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 527f18f57dc2e..de8c75345fee4 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -383,17 +383,13 @@ 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(&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 + } } } @@ -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(), diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index e1c713b537c2a..8111ac44a87ee 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -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) } } } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 8236cd1f73857..b6d123c72acd8 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -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)); @@ -874,8 +872,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { 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, @@ -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/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 4becb42d30551..9968118d2ece1 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2809,7 +2809,8 @@ impl Clean 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 { @@ -2884,7 +2885,7 @@ impl Clean 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) @@ -3537,7 +3538,7 @@ impl Clean 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), } } } 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 Encodable for P { } impl 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)] From 673c3fc23ad0c78fe26420b641957e4fdfea553b Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 12 Jun 2019 11:43:15 +0300 Subject: [PATCH 2/2] rustc: disallow cloning HIR nodes. --- src/librustc/hir/lowering.rs | 103 ++++---- src/librustc/hir/map/mod.rs | 10 +- src/librustc/hir/mod.rs | 170 ++++++------ src/librustc/hir/print.rs | 61 ++--- src/librustc/traits/error_reporting.rs | 4 +- .../borrow_check/conflict_errors.rs | 4 +- src/librustc_typeck/astconv.rs | 26 +- src/librustc_typeck/check/mod.rs | 14 +- src/librustc_typeck/collect.rs | 20 +- src/librustdoc/clean/mod.rs | 93 +++---- src/librustdoc/doctree.rs | 202 ++++++++------- src/librustdoc/visit_ast.rs | 243 +++++++++--------- 12 files changed, 476 insertions(+), 474 deletions(-) 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(&mut self, - params: &HirVec, + fn with_parent_item_lifetime_defs(&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) -> P { - 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 { + 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 de8c75345fee4..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))] @@ -393,13 +393,13 @@ impl PathSegment { } } -#[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), @@ -431,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, @@ -505,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), @@ -541,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 { @@ -556,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, @@ -576,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, pub where_clause: WhereClause, @@ -584,7 +584,7 @@ pub struct Generics { } impl Generics { - pub fn empty() -> Generics { + pub const fn empty() -> Generics { Generics { params: HirVec::new(), where_clause: WhereClause { @@ -638,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, // Only valid if predicates isn't empty. @@ -656,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), @@ -677,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. @@ -689,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, @@ -697,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, @@ -705,7 +705,7 @@ pub struct WhereEqPredicate { pub rhs_ty: P, } -#[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 @@ -720,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, @@ -815,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, @@ -829,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, @@ -847,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, @@ -910,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, @@ -925,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 @@ -952,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, @@ -997,8 +997,8 @@ pub enum PatKind { Slice(HirVec>, Option>, HirVec>), } -#[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, @@ -1014,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, @@ -1148,7 +1148,7 @@ impl Into for BinOpKind { pub type BinOp = Spanned; -#[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, @@ -1177,7 +1177,7 @@ impl UnOp { } /// A statement. -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(RustcEncodable, RustcDecodable)] pub struct Stmt { pub hir_id: HirId, pub node: StmtKind, @@ -1192,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), @@ -1219,7 +1219,7 @@ impl StmtKind { } /// Represents a `let` statement (i.e., `let : = ;`). -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct Local { pub pat: P, /// Type annotation, if any (otherwise the type will be inferred). @@ -1236,7 +1236,7 @@ pub struct Local { /// Represents a single arm of a `match` expression, e.g. /// ` (if ) => `. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct Arm { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -1250,12 +1250,12 @@ pub struct Arm { pub body: P, } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum Guard { If(P), } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct Field { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -1265,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), @@ -1273,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, @@ -1305,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, pub value: Expr, @@ -1379,7 +1379,7 @@ pub struct AnonConst { } /// An expression -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(RustcEncodable, RustcDecodable)] pub struct Expr { pub span: Span, pub node: ExprKind, @@ -1490,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), @@ -1598,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. @@ -1618,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, @@ -1640,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, @@ -1664,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, @@ -1674,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, @@ -1692,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