diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index fef33939fac6..4c24c7afd735 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -743,26 +743,25 @@ pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v TyPar } pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v GenericParam) { - match *param { - GenericParam::Lifetime(ref ld) => { - visitor.visit_id(ld.lifetime.id); - match ld.lifetime.name { + visitor.visit_id(param.id); + match param.kind { + GenericParamKind::Lifetime { ref bounds, ref lifetime_deprecated, .. } => { + match lifetime_deprecated.name { LifetimeName::Name(name) => { - visitor.visit_name(ld.lifetime.span, name); + visitor.visit_name(param.span, name); } LifetimeName::Fresh(_) | LifetimeName::Static | LifetimeName::Implicit | LifetimeName::Underscore => {} } - walk_list!(visitor, visit_lifetime, &ld.bounds); + walk_list!(visitor, visit_lifetime, bounds); } - GenericParam::Type(ref ty_param) => { - visitor.visit_id(ty_param.id); - visitor.visit_name(ty_param.span, ty_param.name); - walk_list!(visitor, visit_ty_param_bound, &ty_param.bounds); - walk_list!(visitor, visit_ty, &ty_param.default); - walk_list!(visitor, visit_attribute, ty_param.attrs.iter()); + GenericParamKind::Type { name, ref bounds, ref default, ref attrs, .. } => { + visitor.visit_name(param.span, name); + walk_list!(visitor, visit_ty_param_bound, bounds); + walk_list!(visitor, visit_ty, default); + walk_list!(visitor, visit_attribute, attrs.iter()); } } } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 4660352b28bf..0c5c79e8e600 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -116,7 +116,7 @@ pub struct LoweringContext<'a> { // When traversing a signature such as `fn foo(x: impl Trait)`, // we record `impl Trait` as a new type parameter, then later // add it on to `foo`s generics. - in_band_ty_params: Vec, + in_band_ty_params: Vec, // Used to create lifetime definitions from in-band lifetime usages. // e.g. `fn foo(x: &'x u8) -> &'x u8` to `fn foo<'x>(x: &'x u8) -> &'x u8` @@ -695,22 +695,23 @@ impl<'a> LoweringContext<'a> { span, ); - hir::GenericParam::Lifetime(hir::LifetimeDef { - lifetime: hir::Lifetime { - id: def_node_id, - span, - name: hir_name, - }, - bounds: Vec::new().into(), + hir::GenericParam { + id: def_node_id, + span, pure_wrt_drop: false, - in_band: true, - }) + kind: hir::GenericParamKind::Lifetime { + name: hir_name, + bounds: vec![].into(), + in_band: true, + lifetime_deprecated: hir::Lifetime { + id: def_node_id, + span, + name: hir_name, + } + } + } }) - .chain( - in_band_ty_params - .into_iter() - .map(|tp| hir::GenericParam::Type(tp)), - ) + .chain(in_band_ty_params.into_iter()) .collect(); (params, res) @@ -778,12 +779,12 @@ 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, lt_defs: &[hir::LifetimeDef], f: F) -> T + fn with_parent_impl_lifetime_defs(&mut self, params: &[hir::GenericParam], f: F) -> T where F: FnOnce(&mut LoweringContext) -> T, { let old_len = self.in_scope_lifetimes.len(); - let lt_def_names = lt_defs.iter().map(|lt_def| lt_def.lifetime.name.name()); + let lt_def_names = params.iter().map(|param| param.name()); self.in_scope_lifetimes.extend(lt_def_names); let res = f(self); @@ -1252,15 +1253,17 @@ impl<'a> LoweringContext<'a> { let hir_bounds = self.lower_bounds(bounds, itctx); // Set the name to `impl Bound1 + Bound2` let name = Symbol::intern(&pprust::ty_to_string(t)); - self.in_band_ty_params.push(hir::TyParam { - name, + self.in_band_ty_params.push(hir::GenericParam { id: def_node_id, - bounds: hir_bounds, - default: None, span, pure_wrt_drop: false, - synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), - attrs: P::new(), + kind: hir::GenericParamKind::Type { + name, + bounds: hir_bounds, + default: None, + synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), + attrs: P::new(), + } }); hir::TyPath(hir::QPath::Resolved( @@ -1367,10 +1370,10 @@ impl<'a> LoweringContext<'a> { fn visit_generic_param(&mut self, param: &'v hir::GenericParam) { // Record the introduction of 'a in `for<'a> ...` - if let hir::GenericParam::Lifetime(ref lt_def) = *param { + if let hir::GenericParamKind::Lifetime { name, .. } = param.kind { // Introduce lifetimes one at a time so that we can handle // cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd>` - self.currently_bound_lifetimes.push(lt_def.lifetime.name); + self.currently_bound_lifetimes.push(name); } hir::intravisit::walk_generic_param(self, param); @@ -1416,18 +1419,22 @@ impl<'a> LoweringContext<'a> { Mark::root(), lifetime.span, ); - let def_lifetime = hir::Lifetime { + + self.output_lifetime_params.push(hir::GenericParam { id: def_node_id, span: lifetime.span, - name, - }; - self.output_lifetime_params - .push(hir::GenericParam::Lifetime(hir::LifetimeDef { - lifetime: def_lifetime, - bounds: Vec::new().into(), - pure_wrt_drop: false, + pure_wrt_drop: false, + kind: hir::GenericParamKind::Lifetime { + name, + bounds: vec![].into(), in_band: false, - })); + lifetime_deprecated: hir::Lifetime { + id: def_node_id, + span: lifetime.span, + name, + } + } + }); } } } @@ -1887,47 +1894,6 @@ impl<'a> LoweringContext<'a> { } } - fn lower_ty_param( - &mut self, - tp: &TyParam, - add_bounds: &[TyParamBound], - itctx: ImplTraitContext, - ) -> hir::TyParam { - let mut name = self.lower_ident(tp.ident); - - // Don't expose `Self` (recovered "keyword used as ident" parse error). - // `rustc::ty` expects `Self` to be only used for a trait's `Self`. - // Instead, use gensym("Self") to create a distinct name that looks the same. - if name == keywords::SelfType.name() { - name = Symbol::gensym("Self"); - } - - let mut bounds = self.lower_bounds(&tp.bounds, itctx); - if !add_bounds.is_empty() { - bounds = bounds - .into_iter() - .chain(self.lower_bounds(add_bounds, itctx).into_iter()) - .collect(); - } - - hir::TyParam { - id: self.lower_node_id(tp.id).node_id, - name, - bounds, - default: tp.default - .as_ref() - .map(|x| self.lower_ty(x, ImplTraitContext::Disallowed)), - span: tp.ident.span, - pure_wrt_drop: attr::contains_name(&tp.attrs, "may_dangle"), - synthetic: tp.attrs - .iter() - .filter(|attr| attr.check_name("rustc_synthetic")) - .map(|_| hir::SyntheticTyParamKind::ImplTrait) - .nth(0), - attrs: self.lower_attrs(&tp.attrs), - } - } - fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime { let span = l.ident.span; match self.lower_ident(l.ident) { @@ -1962,20 +1928,75 @@ impl<'a> LoweringContext<'a> { } } - fn lower_lifetime_def(&mut self, l: &LifetimeDef) -> hir::LifetimeDef { - let was_collecting_in_band = self.is_collecting_in_band_lifetimes; - self.is_collecting_in_band_lifetimes = false; + fn lower_generic_param(&mut self, + param: &GenericParamAST, + add_bounds: &NodeMap>, + itctx: ImplTraitContext) + -> hir::GenericParam { + match param { + GenericParamAST::Lifetime(ref lifetime_def) => { + let was_collecting_in_band = self.is_collecting_in_band_lifetimes; + self.is_collecting_in_band_lifetimes = false; - let def = hir::LifetimeDef { - lifetime: self.lower_lifetime(&l.lifetime), - bounds: l.bounds.iter().map(|l| self.lower_lifetime(l)).collect(), - pure_wrt_drop: attr::contains_name(&l.attrs, "may_dangle"), - in_band: false, - }; + let lifetime = self.lower_lifetime(&lifetime_def.lifetime); + let param = hir::GenericParam { + id: lifetime.id, + span: lifetime.span, + pure_wrt_drop: attr::contains_name(&lifetime_def.attrs, "may_dangle"), + kind: hir::GenericParamKind::Lifetime { + name: lifetime.name, + bounds: lifetime_def.bounds + .iter() + .map(|lt| self.lower_lifetime(lt)).collect(), + in_band: false, + lifetime_deprecated: lifetime, + } + }; - self.is_collecting_in_band_lifetimes = was_collecting_in_band; + self.is_collecting_in_band_lifetimes = was_collecting_in_band; - def + param + } + GenericParamAST::Type(ref ty_param) => { + let mut name = self.lower_ident(ty_param.ident); + + // Don't expose `Self` (recovered "keyword used as ident" parse error). + // `rustc::ty` expects `Self` to be only used for a trait's `Self`. + // Instead, use gensym("Self") to create a distinct name that looks the same. + if name == keywords::SelfType.name() { + name = Symbol::gensym("Self"); + } + + let mut bounds = self.lower_bounds(&ty_param.bounds, itctx); + let add_bounds = add_bounds.get(&ty_param.id).map_or(&[][..], |x| &x); + if !add_bounds.is_empty() { + bounds = bounds + .into_iter() + .chain(self.lower_bounds(add_bounds, itctx).into_iter()) + .collect(); + } + + hir::GenericParam { + id: self.lower_node_id(ty_param.id).node_id, + span: ty_param.ident.span, + pure_wrt_drop: attr::contains_name(&ty_param.attrs, "may_dangle"), + kind: hir::GenericParamKind::Type { + name, + bounds, + default: ty_param.default.as_ref() + .map(|x| { + self.lower_ty(x, ImplTraitContext::Disallowed) + }), + synthetic: ty_param.attrs + .iter() + .filter(|attr| attr.check_name("rustc_synthetic")) + .map(|_| hir::SyntheticTyParamKind::ImplTrait) + .nth(0), + attrs: self.lower_attrs(&ty_param.attrs), + } + } + } + } } fn lower_generic_params( @@ -1984,19 +2005,7 @@ impl<'a> LoweringContext<'a> { add_bounds: &NodeMap>, itctx: ImplTraitContext, ) -> hir::HirVec { - params - .iter() - .map(|param| match *param { - GenericParamAST::Lifetime(ref lifetime_def) => { - hir::GenericParam::Lifetime(self.lower_lifetime_def(lifetime_def)) - } - GenericParamAST::Type(ref ty_param) => hir::GenericParam::Type(self.lower_ty_param( - ty_param, - add_bounds.get(&ty_param.id).map_or(&[][..], |x| &x), - itctx, - )), - }) - .collect() + params.iter().map(|param| self.lower_generic_param(param, add_bounds, itctx)).collect() } fn lower_generics(&mut self, g: &Generics, itctx: ImplTraitContext) -> hir::Generics { @@ -2175,8 +2184,8 @@ impl<'a> LoweringContext<'a> { let trait_ref = self.with_parent_impl_lifetime_defs( &bound_generic_params .iter() - .filter_map(|p| match *p { - hir::GenericParam::Lifetime(ref ld) => Some(ld.clone()), + .filter_map(|param| match param.kind { + hir::GenericParamKind::Lifetime { .. } => Some(param.clone()), _ => None, }) .collect::>(), diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 7835d4e782c4..d34924547ed6 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -212,7 +212,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { NodeBlock(n) => EntryBlock(parent, dep_node_index, n), NodeStructCtor(n) => EntryStructCtor(parent, dep_node_index, n), NodeLifetime(n) => EntryLifetime(parent, dep_node_index, n), - NodeTyParam(n) => EntryTyParam(parent, dep_node_index, n), + NodeGenericParam(n) => EntryGenericParam(parent, dep_node_index, n), NodeVisibility(n) => EntryVisibility(parent, dep_node_index, n), NodeLocal(n) => EntryLocal(parent, dep_node_index, n), NodeMacroDef(n) => EntryMacroDef(dep_node_index, n), @@ -347,12 +347,12 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_generic_param(&mut self, param: &'hir GenericParam) { - match *param { - GenericParam::Lifetime(ref ld) => { - self.insert(ld.lifetime.id, NodeLifetime(&ld.lifetime)); + match param.kind { + GenericParamKind::Lifetime { ref lifetime_deprecated, .. } => { + self.insert(param.id, NodeLifetime(lifetime_deprecated)); } - GenericParam::Type(ref ty_param) => { - self.insert(ty_param.id, NodeTyParam(ty_param)); + GenericParamKind::Type { .. } => { + self.insert(param.id, NodeGenericParam(param)); } } intravisit::walk_generic_param(self, param); diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index d2e04ef31c86..c46f58137540 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -68,7 +68,7 @@ pub enum Node<'hir> { NodeStructCtor(&'hir VariantData), NodeLifetime(&'hir Lifetime), - NodeTyParam(&'hir TyParam), + NodeGenericParam(&'hir GenericParam), NodeVisibility(&'hir Visibility), } @@ -96,7 +96,7 @@ enum MapEntry<'hir> { EntryBlock(NodeId, DepNodeIndex, &'hir Block), EntryStructCtor(NodeId, DepNodeIndex, &'hir VariantData), EntryLifetime(NodeId, DepNodeIndex, &'hir Lifetime), - EntryTyParam(NodeId, DepNodeIndex, &'hir TyParam), + EntryGenericParam(NodeId, DepNodeIndex, &'hir GenericParam), EntryVisibility(NodeId, DepNodeIndex, &'hir Visibility), EntryLocal(NodeId, DepNodeIndex, &'hir Local), @@ -132,7 +132,7 @@ impl<'hir> MapEntry<'hir> { EntryBlock(id, _, _) => id, EntryStructCtor(id, _, _) => id, EntryLifetime(id, _, _) => id, - EntryTyParam(id, _, _) => id, + EntryGenericParam(id, _, _) => id, EntryVisibility(id, _, _) => id, EntryLocal(id, _, _) => id, @@ -160,7 +160,7 @@ impl<'hir> MapEntry<'hir> { EntryBlock(_, _, n) => NodeBlock(n), EntryStructCtor(_, _, n) => NodeStructCtor(n), EntryLifetime(_, _, n) => NodeLifetime(n), - EntryTyParam(_, _, n) => NodeTyParam(n), + EntryGenericParam(_, _, n) => NodeGenericParam(n), EntryVisibility(_, _, n) => NodeVisibility(n), EntryLocal(_, _, n) => NodeLocal(n), EntryMacroDef(_, n) => NodeMacroDef(n), @@ -328,7 +328,7 @@ impl<'hir> Map<'hir> { EntryBlock(_, dep_node_index, _) | EntryStructCtor(_, dep_node_index, _) | EntryLifetime(_, dep_node_index, _) | - EntryTyParam(_, dep_node_index, _) | + EntryGenericParam(_, dep_node_index, _) | EntryVisibility(_, dep_node_index, _) | EntryAnonConst(_, dep_node_index, _) | EntryExpr(_, dep_node_index, _) | @@ -494,7 +494,7 @@ impl<'hir> Map<'hir> { Some(Def::Macro(self.local_def_id(macro_def.id), MacroKind::Bang)) } - NodeTyParam(param) => { + NodeGenericParam(param) => { Some(Def::TyParam(self.local_def_id(param.id))) } } @@ -600,7 +600,7 @@ impl<'hir> Map<'hir> { pub fn ty_param_owner(&self, id: NodeId) -> NodeId { match self.get(id) { NodeItem(&Item { node: ItemTrait(..), .. }) => id, - NodeTyParam(_) => self.get_parent_node(id), + NodeGenericParam(_) => self.get_parent_node(id), _ => { bug!("ty_param_owner: {} not a type parameter", self.node_to_string(id)) @@ -613,7 +613,7 @@ impl<'hir> Map<'hir> { NodeItem(&Item { node: ItemTrait(..), .. }) => { keywords::SelfType.name() } - NodeTyParam(tp) => tp.name, + NodeGenericParam(param) => param.name(), _ => { bug!("ty_param_name: {} not a type parameter", self.node_to_string(id)) @@ -954,7 +954,7 @@ impl<'hir> Map<'hir> { NodeVariant(v) => v.node.name, NodeField(f) => f.ident.name, NodeLifetime(lt) => lt.name.name(), - NodeTyParam(tp) => tp.name, + NodeGenericParam(param) => param.name(), NodeBinding(&Pat { node: PatKind::Binding(_,_,l,_), .. }) => l.node, NodeStructCtor(_) => self.name(self.get_parent(id)), _ => bug!("no name for {}", self.node_to_string(id)) @@ -974,7 +974,12 @@ impl<'hir> Map<'hir> { Some(NodeField(ref f)) => Some(&f.attrs[..]), Some(NodeExpr(ref e)) => Some(&*e.attrs), Some(NodeStmt(ref s)) => Some(s.node.attrs()), - Some(NodeTyParam(tp)) => Some(&tp.attrs[..]), + Some(NodeGenericParam(param)) => { + match param.kind { + GenericParamKind::Type { ref attrs, .. } => Some(&attrs[..]), + _ => bug!("unexpected non-type NodeGenericParam") + } + } // unit/tuple structs take the attributes straight from // the struct definition. Some(NodeStructCtor(_)) => { @@ -1021,7 +1026,7 @@ impl<'hir> Map<'hir> { Some(EntryBlock(_, _, block)) => block.span, Some(EntryStructCtor(_, _, _)) => self.expect_item(self.get_parent(id)).span, Some(EntryLifetime(_, _, lifetime)) => lifetime.span, - Some(EntryTyParam(_, _, ty_param)) => ty_param.span, + Some(EntryGenericParam(_, _, param)) => param.span, Some(EntryVisibility(_, _, &Visibility::Restricted { ref path, .. })) => path.span, Some(EntryVisibility(_, _, v)) => bug!("unexpected Visibility {:?}", v), Some(EntryLocal(_, _, local)) => local.span, @@ -1226,19 +1231,19 @@ impl<'hir> print::PpAnn for Map<'hir> { impl<'a> print::State<'a> { pub fn print_node(&mut self, node: Node) -> io::Result<()> { match node { - NodeItem(a) => self.print_item(&a), - NodeForeignItem(a) => self.print_foreign_item(&a), - NodeTraitItem(a) => self.print_trait_item(a), - NodeImplItem(a) => self.print_impl_item(a), - NodeVariant(a) => self.print_variant(&a), - NodeAnonConst(a) => self.print_anon_const(&a), - NodeExpr(a) => self.print_expr(&a), - NodeStmt(a) => self.print_stmt(&a), - NodeTy(a) => self.print_type(&a), - NodeTraitRef(a) => self.print_trait_ref(&a), + NodeItem(a) => self.print_item(&a), + NodeForeignItem(a) => self.print_foreign_item(&a), + NodeTraitItem(a) => self.print_trait_item(a), + NodeImplItem(a) => self.print_impl_item(a), + NodeVariant(a) => self.print_variant(&a), + NodeAnonConst(a) => self.print_anon_const(&a), + NodeExpr(a) => self.print_expr(&a), + NodeStmt(a) => self.print_stmt(&a), + NodeTy(a) => self.print_type(&a), + NodeTraitRef(a) => self.print_trait_ref(&a), NodeBinding(a) | - NodePat(a) => self.print_pat(&a), - NodeBlock(a) => { + NodePat(a) => self.print_pat(&a), + NodeBlock(a) => { use syntax::print::pprust::PrintState; // containing cbox, will be closed by print-block at } @@ -1247,16 +1252,16 @@ impl<'a> print::State<'a> { self.ibox(0)?; self.print_block(&a) } - NodeLifetime(a) => self.print_lifetime(&a), - NodeVisibility(a) => self.print_visibility(&a), - NodeTyParam(_) => bug!("cannot print TyParam"), - NodeField(_) => bug!("cannot print StructField"), + NodeLifetime(a) => self.print_lifetime(&a), + NodeVisibility(a) => self.print_visibility(&a), + NodeGenericParam(_) => bug!("cannot print NodeGenericParam"), + NodeField(_) => bug!("cannot print StructField"), // these cases do not carry enough information in the // hir_map to reconstruct their full structure for pretty // printing. - NodeStructCtor(_) => bug!("cannot print isolated StructCtor"), - NodeLocal(a) => self.print_local_decl(&a), - NodeMacroDef(_) => bug!("cannot print MacroDef"), + NodeStructCtor(_) => bug!("cannot print isolated StructCtor"), + NodeLocal(a) => self.print_local_decl(&a), + NodeMacroDef(_) => bug!("cannot print MacroDef"), } } } @@ -1371,8 +1376,8 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { Some(NodeLifetime(_)) => { format!("lifetime {}{}", map.node_to_pretty_string(id), id_str) } - Some(NodeTyParam(ref ty_param)) => { - format!("typaram {:?}{}", ty_param, id_str) + Some(NodeGenericParam(ref param)) => { + format!("genericparam {:?}{}", param, id_str) } Some(NodeVisibility(ref vis)) => { format!("visibility {:?}{}", vis, id_str) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index d4785e40b1f8..6a0301a556fb 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -53,8 +53,6 @@ use rustc_data_structures::sync::{ParallelIterator, par_iter, Send, Sync, scope} use serialize::{self, Encoder, Encodable, Decoder, Decodable}; use std::collections::BTreeMap; use std::fmt; -use std::iter; -use std::slice; /// HIR doesn't commit to a concrete storage type and has its own alias for a vector. /// It can be `Vec`, `P<[T]>` or potentially `Box<[T]>`, or some other container with similar @@ -242,6 +240,24 @@ impl LifetimeName { Name(name) => name, } } + + fn is_elided(&self) -> bool { + use self::LifetimeName::*; + match self { + Implicit | Underscore => true, + + // It might seem surprising that `Fresh(_)` counts as + // *not* elided -- but this is because, as far as the code + // in the compiler is concerned -- `Fresh(_)` variants act + // equivalently to "some fresh name". They correspond to + // early-bound regions on an impl, in other words. + Fresh(_) | Static | Name(_) => false, + } + } + + fn is_static(&self) -> bool { + self == &LifetimeName::Static + } } impl fmt::Debug for Lifetime { @@ -255,36 +271,14 @@ impl fmt::Debug for Lifetime { impl Lifetime { pub fn is_elided(&self) -> bool { - use self::LifetimeName::*; - match self.name { - Implicit | Underscore => true, - - // It might seem surprising that `Fresh(_)` counts as - // *not* elided -- but this is because, as far as the code - // in the compiler is concerned -- `Fresh(_)` variants act - // equivalently to "some fresh name". They correspond to - // early-bound regions on an impl, in other words. - Fresh(_) | Static | Name(_) => false, - } + self.name.is_elided() } pub fn is_static(&self) -> bool { - self.name == LifetimeName::Static + self.name.is_static() } } -/// A lifetime definition, eg `'a: 'b+'c+'d` -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct LifetimeDef { - pub lifetime: Lifetime, - pub bounds: HirVec, - pub pure_wrt_drop: bool, - // Indicates that the lifetime definition was synthetically added - // as a result of an in-band lifetime usage like - // `fn foo(x: &'a u8) -> &'a u8 { x }` - pub in_band: bool, -} - /// 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. @@ -466,70 +460,62 @@ pub enum TraitBoundModifier { pub type TyParamBounds = HirVec; #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct TyParam { - pub name: Name, - pub id: NodeId, - pub bounds: TyParamBounds, - pub default: Option>, - pub span: Span, - pub pure_wrt_drop: bool, - pub synthetic: Option, - pub attrs: HirVec, +pub enum GenericParamKind { + /// A lifetime definition, eg `'a: 'b + 'c + 'd`. + Lifetime { + /// Either "'a", referring to a named lifetime definition, + /// or "" (aka keywords::Invalid), for elision placeholders. + /// + /// HIR lowering inserts these placeholders in type paths that + /// refer to type definitions needing lifetime parameters, + /// `&T` and `&mut T`, and trait objects without `... + 'a`. + name: LifetimeName, + bounds: HirVec, + // Indicates that the lifetime definition was synthetically added + // as a result of an in-band lifetime usage like: + // `fn foo(x: &'a u8) -> &'a u8 { x }` + in_band: bool, + // We keep a `Lifetime` around for now just so we can `visit_lifetime`. + lifetime_deprecated: Lifetime, + }, + Type { + name: Name, + bounds: TyParamBounds, + default: Option>, + synthetic: Option, + attrs: HirVec, + } } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum GenericParam { - Lifetime(LifetimeDef), - Type(TyParam), +pub struct GenericParam { + pub id: NodeId, + pub span: Span, + pub pure_wrt_drop: bool, + + pub kind: GenericParamKind, } impl GenericParam { pub fn is_lifetime_param(&self) -> bool { - match *self { - GenericParam::Lifetime(_) => true, + match self.kind { + GenericParamKind::Lifetime { .. } => true, _ => false, } } pub fn is_type_param(&self) -> bool { - match *self { - GenericParam::Type(_) => true, + match self.kind { + GenericParamKind::Type { .. } => true, _ => false, } } -} -pub trait GenericParamsExt { - fn lifetimes<'a>(&'a self) -> iter::FilterMap< - slice::Iter, - fn(&GenericParam) -> Option<&LifetimeDef>, - >; - - fn ty_params<'a>(&'a self) -> iter::FilterMap< - slice::Iter, - fn(&GenericParam) -> Option<&TyParam>, - >; -} - -impl GenericParamsExt for [GenericParam] { - fn lifetimes<'a>(&'a self) -> iter::FilterMap< - slice::Iter, - fn(&GenericParam) -> Option<&LifetimeDef>, - > { - self.iter().filter_map(|param| match *param { - GenericParam::Lifetime(ref l) => Some(l), - _ => None, - }) - } - - fn ty_params<'a>(&'a self) -> iter::FilterMap< - slice::Iter, - fn(&GenericParam) -> Option<&TyParam>, - > { - self.iter().filter_map(|param| match *param { - GenericParam::Type(ref t) => Some(t), - _ => None, - }) + pub fn name(&self) -> Name { + match self.kind { + GenericParamKind::Lifetime { name, .. } => name.name(), + GenericParamKind::Type { name, .. } => name, + } } } @@ -555,54 +541,39 @@ impl Generics { } pub fn is_lt_parameterized(&self) -> bool { - self.params.iter().any(|param| param.is_lifetime_param()) + self.params.iter().any(|param| { + match param.kind { + GenericParamKind::Lifetime { .. } => true, + _ => false, + } + }) } pub fn is_type_parameterized(&self) -> bool { - self.params.iter().any(|param| param.is_type_param()) - } - - pub fn lifetimes<'a>(&'a self) -> impl DoubleEndedIterator { - self.params.lifetimes() - } - - pub fn ty_params<'a>(&'a self) -> impl DoubleEndedIterator { - self.params.ty_params() - } -} - -pub enum UnsafeGeneric { - Region(LifetimeDef, &'static str), - Type(TyParam, &'static str), -} - -impl UnsafeGeneric { - pub fn attr_name(&self) -> &'static str { - match *self { - UnsafeGeneric::Region(_, s) => s, - UnsafeGeneric::Type(_, s) => s, - } - } -} - -impl Generics { - pub fn carries_unsafe_attr(&self) -> Option { - for param in &self.params { - match *param { - GenericParam::Lifetime(ref l) => { - if l.pure_wrt_drop { - return Some(UnsafeGeneric::Region(l.clone(), "may_dangle")); - } - } - GenericParam::Type(ref t) => { - if t.pure_wrt_drop { - return Some(UnsafeGeneric::Type(t.clone(), "may_dangle")); - } - } + self.params.iter().any(|param| { + match param.kind { + GenericParamKind::Type { .. } => true, + _ => false, } - } + }) + } - None + pub fn lifetimes<'a>(&'a self) -> impl DoubleEndedIterator { + self.params.iter().filter(|param| { + match param.kind { + GenericParamKind::Lifetime { .. } => true, + _ => false, + } + }) + } + + pub fn ty_params<'a>(&'a self) -> impl DoubleEndedIterator { + self.params.iter().filter(|param| { + match param.kind { + GenericParamKind::Type { .. } => true, + _ => false, + } + }) } } diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 5420be64ca43..afb3a6d0e6c4 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -25,7 +25,7 @@ use syntax_pos::{self, BytePos, FileName}; use hir; use hir::{PatKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier, RangeEnd}; -use hir::GenericArg; +use hir::{GenericParam, GenericParamKind, GenericArg}; use std::cell::Cell; use std::io::{self, Write, Read}; @@ -2094,30 +2094,12 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_lifetime(&mut self, lifetime: &hir::Lifetime) -> io::Result<()> { - self.print_name(lifetime.name.name()) - } - - pub fn print_lifetime_def(&mut self, lifetime: &hir::LifetimeDef) -> io::Result<()> { - self.print_lifetime(&lifetime.lifetime)?; - let mut sep = ":"; - for v in &lifetime.bounds { - self.s.word(sep)?; - self.print_lifetime(v)?; - sep = "+"; - } - Ok(()) - } - - pub fn print_generic_params(&mut self, generic_params: &[hir::GenericParam]) -> io::Result<()> { + pub fn print_generic_params(&mut self, generic_params: &[GenericParam]) -> io::Result<()> { if !generic_params.is_empty() { self.s.word("<")?; self.commasep(Inconsistent, generic_params, |s, param| { - match *param { - hir::GenericParam::Lifetime(ref ld) => s.print_lifetime_def(ld), - hir::GenericParam::Type(ref tp) => s.print_ty_param(tp), - } + s.print_generic_param(param) })?; self.s.word(">")?; @@ -2125,19 +2107,36 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_ty_param(&mut self, param: &hir::TyParam) -> io::Result<()> { - self.print_name(param.name)?; - self.print_bounds(":", ¶m.bounds)?; - match param.default { - Some(ref default) => { - self.s.space()?; - self.word_space("=")?; - self.print_type(&default) + pub fn print_generic_param(&mut self, param: &GenericParam) -> io::Result<()> { + self.print_name(param.name())?; + match param.kind { + GenericParamKind::Lifetime { ref bounds, .. } => { + let mut sep = ":"; + for bound in bounds { + self.s.word(sep)?; + self.print_lifetime(bound)?; + sep = "+"; + } + Ok(()) + } + GenericParamKind::Type { ref bounds, ref default, .. } => { + self.print_bounds(":", bounds)?; + match default { + Some(default) => { + self.s.space()?; + self.word_space("=")?; + self.print_type(&default) + } + _ => Ok(()), + } } - _ => Ok(()), } } + pub fn print_lifetime(&mut self, lifetime: &hir::Lifetime) -> io::Result<()> { + self.print_name(lifetime.name.name()) + } + pub fn print_where_clause(&mut self, where_clause: &hir::WhereClause) -> io::Result<()> { if where_clause.predicates.is_empty() { return Ok(()); diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 871e399b4f25..ea12db8681c7 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -161,13 +161,6 @@ impl_stable_hash_for!(struct hir::Lifetime { name }); -impl_stable_hash_for!(struct hir::LifetimeDef { - lifetime, - bounds, - pure_wrt_drop, - in_band -}); - impl_stable_hash_for!(struct hir::Path { span, def, @@ -201,21 +194,36 @@ impl_stable_hash_for!(enum hir::TraitBoundModifier { Maybe }); -impl_stable_hash_for!(struct hir::TyParam { - name, +impl_stable_hash_for!(struct hir::GenericParam { id, - bounds, - default, span, pure_wrt_drop, - synthetic, - attrs + kind }); -impl_stable_hash_for!(enum hir::GenericParam { - Lifetime(lifetime_def), - Type(ty_param) -}); +impl<'a> HashStable> for hir::GenericParamKind { + fn hash_stable(&self, + hcx: &mut StableHashingContext<'a>, + hasher: &mut StableHasher) { + mem::discriminant(self).hash_stable(hcx, hasher); + match self { + hir::GenericParamKind::Lifetime { name, ref bounds, in_band, + ref lifetime_deprecated } => { + name.hash_stable(hcx, hasher); + bounds.hash_stable(hcx, hasher); + in_band.hash_stable(hcx, hasher); + lifetime_deprecated.hash_stable(hcx, hasher); + } + hir::GenericParamKind::Type { name, ref bounds, ref default, synthetic, attrs } => { + name.hash_stable(hcx, hasher); + bounds.hash_stable(hcx, hasher); + default.hash_stable(hcx, hasher); + synthetic.hash_stable(hcx, hasher); + attrs.hash_stable(hcx, hasher); + } + } + } +} impl_stable_hash_for!(struct hir::Generics { params, diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 4bde363672dc..af38e8ba2d49 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -61,7 +61,7 @@ use super::region_constraints::GenericKind; use super::lexical_region_resolve::RegionResolutionError; use std::fmt; -use hir; +use hir::{self, GenericParamKind}; use hir::map as hir_map; use hir::def_id::DefId; use middle::region; @@ -1036,8 +1036,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // Get the `hir::TyParam` to verify whether it already has any bounds. // We do this to avoid suggesting code that ends up as `T: 'a'b`, // instead we suggest `T: 'a + 'b` in that case. - let has_lifetimes = if let hir_map::NodeTyParam(ref p) = hir.get(id) { - p.bounds.len() > 0 + let has_lifetimes = + if let hir_map::NodeGenericParam(ref param) = hir.get(id) { + match param.kind { + GenericParamKind::Type { ref bounds, .. } => { + !bounds.is_empty() + } + _ => bug!("unexpected non-type NodeGenericParam"), + } } else { false }; diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 8f1cd9bb30ec..76680b205355 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -35,7 +35,7 @@ use syntax_pos::Span; use util::nodemap::{DefIdMap, FxHashMap, FxHashSet, NodeMap, NodeSet}; use hir::intravisit::{self, NestedVisitorMap, Visitor}; -use hir::{self, GenericParamsExt}; +use hir::{self, GenericParamKind}; /// The origin of a named lifetime definition. /// @@ -86,20 +86,30 @@ impl Region { fn early( hir_map: &Map, index: &mut u32, - def: &hir::LifetimeDef, + param: &hir::GenericParam, ) -> (hir::LifetimeName, Region) { let i = *index; *index += 1; - let def_id = hir_map.local_def_id(def.lifetime.id); - let origin = LifetimeDefOrigin::from_is_in_band(def.in_band); + let def_id = hir_map.local_def_id(param.id); + let (name, origin) = match param.kind { + GenericParamKind::Lifetime { name, in_band, .. } => { + (name, LifetimeDefOrigin::from_is_in_band(in_band)) + } + _ => bug!("expected a lifetime param"), + }; debug!("Region::early: index={} def_id={:?}", i, def_id); - (def.lifetime.name, Region::EarlyBound(i, def_id, origin)) + (name, Region::EarlyBound(i, def_id, origin)) } - fn late(hir_map: &Map, def: &hir::LifetimeDef) -> (hir::LifetimeName, Region) { + fn late(hir_map: &Map, param: &hir::GenericParam) -> (hir::LifetimeName, Region) { let depth = ty::INNERMOST; - let def_id = hir_map.local_def_id(def.lifetime.id); - let origin = LifetimeDefOrigin::from_is_in_band(def.in_band); + let def_id = hir_map.local_def_id(param.id); + let (name, origin) = match param.kind { + GenericParamKind::Lifetime { name, in_band, .. } => { + (name, LifetimeDefOrigin::from_is_in_band(in_band)) + } + _ => bug!("expected a lifetime param"), + }; debug!( "Region::late: def={:?} depth={:?} def_id={:?} origin={:?}", def, @@ -107,7 +117,7 @@ impl Region { def_id, origin, ); - (def.lifetime.name, Region::LateBound(depth, def_id, origin)) + (name, Region::LateBound(depth, def_id, origin)) } fn late_anon(index: &Cell) -> Region { @@ -567,9 +577,16 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { self.is_in_fn_syntax = true; let scope = Scope::Binder { lifetimes: c.generic_params - .lifetimes() - .map(|def| Region::late(&self.tcx.hir, def)) - .collect(), + .iter() + .filter_map(|param| { + match param.kind { + GenericParamKind::Lifetime { .. } => { + Some(Region::late(&self.tcx.hir, param)) + } + _ => None, + } + }) + .collect(), s: self.scope, next_early_index, track_lifetime_uses: true, @@ -850,10 +867,15 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { self.tcx, &generics.lifetimes().cloned().collect::>(), ); - for ty_param in generics.ty_params() { - walk_list!(self, visit_ty_param_bound, &ty_param.bounds); - if let Some(ref ty) = ty_param.default { - self.visit_ty(&ty); + for param in &generics.params { + match param.kind { + GenericParamKind::Lifetime { .. } => {} + GenericParamKind::Type { ref bounds, ref default, .. } => { + walk_list!(self, visit_ty_param_bound, bounds); + if let Some(ref ty) = default { + self.visit_ty(&ty); + } + } } } for predicate in &generics.where_clause.predicates { @@ -869,8 +891,15 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let next_early_index = self.next_early_index(); let scope = Scope::Binder { lifetimes: bound_generic_params - .lifetimes() - .map(|def| Region::late(&self.tcx.hir, def)) + .iter() + .filter_map(|param| { + match param.kind { + GenericParamKind::Lifetime { .. } => { + Some(Region::late(&self.tcx.hir, param)) + } + _ => None, + } + }) .collect(), s: self.scope, next_early_index, @@ -936,8 +965,15 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let scope = Scope::Binder { lifetimes: trait_ref .bound_generic_params - .lifetimes() - .map(|def| Region::late(&self.tcx.hir, def)) + .iter() + .filter_map(|param| { + match param.kind { + GenericParamKind::Lifetime { .. } => { + Some(Region::late(&self.tcx.hir, param)) + } + _ => None, + } + }) .collect(), s: self.scope, next_early_index, @@ -987,10 +1023,10 @@ fn original_lifetime(span: Span) -> Original { span: span, } } -fn shadower_lifetime(l: &hir::Lifetime) -> Shadower { +fn shadower_lifetime(param: &hir::GenericParam) -> Shadower { Shadower { kind: ShadowKind::Lifetime, - span: l.span, + span: param.span, } } @@ -1005,23 +1041,29 @@ impl ShadowKind { fn check_mixed_explicit_and_in_band_defs( tcx: TyCtxt<'_, '_, '_>, - lifetime_defs: &[hir::LifetimeDef], + params: &[hir::GenericParam], ) { - let oob_def = lifetime_defs.iter().find(|lt| !lt.in_band); - let in_band_def = lifetime_defs.iter().find(|lt| lt.in_band); + let in_bands: Vec<_> = params.iter().map(|param| { + match param.kind { + GenericParamKind::Lifetime { in_band, .. } => (in_band, param.span), + _ => bug!("expected lifetime param"), + } + }).collect(); + let out_of_band = in_bands.iter().find(|(in_band, _)| !in_band); + let in_band = in_bands.iter().find(|(in_band, _)| *in_band); - if let (Some(oob_def), Some(in_band_def)) = (oob_def, in_band_def) { + if let (Some((_, out_of_band_span)), Some((_, in_band_span))) + = (out_of_band, in_band) { struct_span_err!( tcx.sess, - in_band_def.lifetime.span, + *in_band_span, E0688, "cannot mix in-band and explicit lifetime definitions" ).span_label( - in_band_def.lifetime.span, + *in_band_span, "in-band lifetime definition here", - ) - .span_label(oob_def.lifetime.span, "explicit lifetime definition here") - .emit(); + ).span_label(*out_of_band_span, "explicit lifetime definition here") + .emit(); } } @@ -1178,8 +1220,6 @@ fn compute_object_lifetime_defaults( .lifetimes() .nth(i as usize) .unwrap() - .lifetime - .name .name() .to_string(), Set1::One(_) => bug!(), @@ -1213,58 +1253,67 @@ fn object_lifetime_defaults_for_item( } } - generics - .ty_params() - .map(|param| { - let mut set = Set1::Empty; + generics.params.iter().filter_map(|param| { + match param.kind { + GenericParamKind::Lifetime { .. } => None, + GenericParamKind::Type { ref bounds, .. } => { + let mut set = Set1::Empty; - add_bounds(&mut set, ¶m.bounds); + add_bounds(&mut set, &bounds); - let param_def_id = tcx.hir.local_def_id(param.id); - for predicate in &generics.where_clause.predicates { - // Look for `type: ...` where clauses. - let data = match *predicate { - hir::WherePredicate::BoundPredicate(ref data) => data, - _ => continue, - }; + let param_def_id = tcx.hir.local_def_id(param.id); + for predicate in &generics.where_clause.predicates { + // Look for `type: ...` where clauses. + let data = match *predicate { + hir::WherePredicate::BoundPredicate(ref data) => data, + _ => continue, + }; - // Ignore `for<'a> type: ...` as they can change what - // lifetimes mean (although we could "just" handle it). - if !data.bound_generic_params.is_empty() { - continue; - } + // Ignore `for<'a> type: ...` as they can change what + // lifetimes mean (although we could "just" handle it). + if !data.bound_generic_params.is_empty() { + continue; + } - let def = match data.bounded_ty.node { - hir::TyPath(hir::QPath::Resolved(None, ref path)) => path.def, - _ => continue, - }; + let def = match data.bounded_ty.node { + hir::TyPath(hir::QPath::Resolved(None, ref path)) => path.def, + _ => continue, + }; - if def == Def::TyParam(param_def_id) { - add_bounds(&mut set, &data.bounds); - } - } - - match set { - Set1::Empty => Set1::Empty, - Set1::One(name) => { - if name == hir::LifetimeName::Static { - Set1::One(Region::Static) - } else { - generics - .lifetimes() - .enumerate() - .find(|&(_, def)| def.lifetime.name == name) - .map_or(Set1::Many, |(i, def)| { - let def_id = tcx.hir.local_def_id(def.lifetime.id); - let origin = LifetimeDefOrigin::from_is_in_band(def.in_band); - Set1::One(Region::EarlyBound(i as u32, def_id, origin)) - }) + if def == Def::TyParam(param_def_id) { + add_bounds(&mut set, &data.bounds); } } - Set1::Many => Set1::Many, + + Some(match set { + Set1::Empty => Set1::Empty, + Set1::One(name) => { + if name == hir::LifetimeName::Static { + Set1::One(Region::Static) + } else { + generics.params.iter().filter_map(|param| { + match param.kind { + GenericParamKind::Lifetime { name, in_band, .. } => { + Some((param.id, name, in_band)) + } + _ => None, + } + }) + .enumerate() + .find(|&(_, (_, lt_name, _))| lt_name == name) + .map_or(Set1::Many, |(i, (id, _, in_band))| { + let def_id = tcx.hir.local_def_id(id); + let origin = LifetimeDefOrigin::from_is_in_band(in_band); + Set1::One(Region::EarlyBound(i as u32, def_id, origin)) + }) + } + } + Set1::Many => Set1::Many, + }) } - }) - .collect() + } + }) + .collect() } impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { @@ -1438,11 +1487,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let lifetimes = generics .lifetimes() - .map(|def| { - if self.map.late_bound.contains(&def.lifetime.id) { - Region::late(&self.tcx.hir, def) + .map(|param| { + if self.map.late_bound.contains(¶m.id) { + Region::late(&self.tcx.hir, param) } else { - Region::early(&self.tcx.hir, &mut index, def) + Region::early(&self.tcx.hir, &mut index, param) } }) .collect(); @@ -1943,7 +1992,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } fn visit_generic_param(&mut self, param: &hir::GenericParam) { - if let hir::GenericParam::Lifetime(_) = *param { + if let hir::GenericParamKind::Lifetime { .. } = param.kind { // FIXME(eddyb) Do we want this? It only makes a difference // if this `for<'a>` lifetime parameter is never used. self.have_bound_regions = true; @@ -2160,20 +2209,26 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } fn check_lifetime_params(&mut self, old_scope: ScopeRef, params: &'tcx [hir::GenericParam]) { - for (i, lifetime_i) in params.lifetimes().enumerate() { - match lifetime_i.lifetime.name { + let lifetimes: Vec<_> = params.iter().filter_map(|param| { + match param.kind { + GenericParamKind::Lifetime { name, .. } => Some((param, name)), + _ => None, + } + }).collect(); + for (i, (lifetime_i, lifetime_i_name)) in lifetimes.iter().enumerate() { + match lifetime_i_name { hir::LifetimeName::Static | hir::LifetimeName::Underscore => { let lifetime = lifetime_i.lifetime; - let name = lifetime.name.name(); + let name = lifetime_i.name(); let mut err = struct_span_err!( self.tcx.sess, - lifetime.span, + lifetime_i.span, E0262, "invalid lifetime parameter name: `{}`", name ); err.span_label( - lifetime.span, + lifetime_i.span, format!("{} is a reserved lifetime name", name), ); err.emit(); @@ -2184,24 +2239,28 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } // It is a hard error to shadow a lifetime within the same scope. - for lifetime_j in params.lifetimes().skip(i + 1) { - if lifetime_i.lifetime.name == lifetime_j.lifetime.name { + for (lifetime_j, lifetime_j_name) in lifetimes.iter().skip(i + 1) { + if lifetime_i_name == lifetime_j_name { struct_span_err!( self.tcx.sess, - lifetime_j.lifetime.span, + lifetime_j.span, E0263, "lifetime name `{}` declared twice in the same scope", - lifetime_j.lifetime.name.name() - ).span_label(lifetime_j.lifetime.span, "declared twice") - .span_label(lifetime_i.lifetime.span, "previous declaration here") + lifetime_j.name() + ).span_label(lifetime_j.span, "declared twice") + .span_label(lifetime_i.span, "previous declaration here") .emit(); } } // It is a soft error to shadow a lifetime within a parent scope. - self.check_lifetime_def_for_shadowing(old_scope, &lifetime_i.lifetime); + self.check_lifetime_param_for_shadowing(old_scope, &lifetime_i); - for bound in &lifetime_i.bounds { + let bounds = match lifetime_i.kind { + GenericParamKind::Lifetime { ref bounds, .. } => bounds, + _ => bug!(), + }; + for bound in bounds { match bound.name { hir::LifetimeName::Underscore => { let mut err = struct_span_err!( @@ -2218,16 +2277,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { self.tcx .sess .struct_span_warn( - lifetime_i.lifetime.span.to(bound.span), + lifetime_i.span.to(bound.span), &format!( "unnecessary lifetime parameter `{}`", - lifetime_i.lifetime.name.name() + lifetime_i.name() ), ) .help(&format!( "you can use the `'static` lifetime directly, in place \ of `{}`", - lifetime_i.lifetime.name.name() + lifetime_i.name() )) .emit(); } @@ -2241,24 +2300,29 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } - fn check_lifetime_def_for_shadowing( + fn check_lifetime_param_for_shadowing( &self, mut old_scope: ScopeRef, - lifetime: &'tcx hir::Lifetime, + param: &'tcx hir::GenericParam, ) { for &(label, label_span) in &self.labels_in_fn { // FIXME (#24278): non-hygienic comparison - if lifetime.name.name() == label { + if param.name() == label { signal_shadowing_problem( self.tcx, label, original_label(label_span), - shadower_lifetime(&lifetime), + shadower_lifetime(¶m), ); return; } } + let name = match param.kind { + GenericParamKind::Lifetime { name, .. } => name, + _ => bug!("expected lifetime param"), + }; + loop { match *old_scope { Scope::Body { s, .. } @@ -2274,14 +2338,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Scope::Binder { ref lifetimes, s, .. } => { - if let Some(&def) = lifetimes.get(&lifetime.name) { + if let Some(&def) = lifetimes.get(&name) { let node_id = self.tcx.hir.as_local_node_id(def.id().unwrap()).unwrap(); signal_shadowing_problem( self.tcx, - lifetime.name.name(), + param.name(), original_lifetime(self.tcx.hir.span(node_id)), - shadower_lifetime(&lifetime), + shadower_lifetime(¶m), ); return; } @@ -2429,14 +2493,14 @@ fn insert_late_bound_lifetimes( appears_in_where_clause.visit_generics(generics); for param in &generics.params { - match *param { - hir::GenericParam::Lifetime(ref lifetime_def) => { - if !lifetime_def.bounds.is_empty() { + match param.kind { + hir::GenericParamKind::Lifetime { ref bounds, .. } => { + if !bounds.is_empty() { // `'a: 'b` means both `'a` and `'b` are referenced appears_in_where_clause.regions.insert(lifetime_def.lifetime.name); } } - hir::GenericParam::Type(_) => {} + hir::GenericParamKind::Type { .. } => {} } } @@ -2450,7 +2514,10 @@ fn insert_late_bound_lifetimes( // - do not appear in the where-clauses // - are not implicitly captured by `impl Trait` for lifetime in generics.lifetimes() { - let name = lifetime.lifetime.name; + let name = match lifetime.kind { + GenericParamKind::Lifetime { name, .. } => name, + _ => bug!(), + }; // appears in the where clauses? early-bound. if appears_in_where_clause.regions.contains(&name) { @@ -2464,18 +2531,12 @@ fn insert_late_bound_lifetimes( continue; } - debug!( - "insert_late_bound_lifetimes: \ - lifetime {:?} with id {:?} is late-bound", - lifetime.lifetime.name, lifetime.lifetime.id - ); + debug!("insert_late_bound_lifetimes: lifetime {:?} with id {:?} is late-bound", + name, + lifetime.id); - let inserted = map.late_bound.insert(lifetime.lifetime.id); - assert!( - inserted, - "visited lifetime {:?} twice", - lifetime.lifetime.id - ); + let inserted = map.late_bound.insert(lifetime.id); + assert!(inserted, "visited lifetime {:?} twice", lifetime.id); } return; diff --git a/src/librustc_lint/bad_style.rs b/src/librustc_lint/bad_style.rs index dbf756f80ca3..f456ab367998 100644 --- a/src/librustc_lint/bad_style.rs +++ b/src/librustc_lint/bad_style.rs @@ -18,7 +18,7 @@ use syntax::ast; use syntax::attr; use syntax_pos::Span; -use rustc::hir::{self, PatKind}; +use rustc::hir::{self, GenericParamKind, PatKind}; use rustc::hir::intravisit::FnKind; #[derive(PartialEq)] @@ -147,9 +147,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCamelCaseTypes { } fn check_generic_param(&mut self, cx: &LateContext, param: &hir::GenericParam) { - if let hir::GenericParam::Type(ref gen) = *param { - if gen.synthetic.is_none() { - self.check_case(cx, "type parameter", gen.name, gen.span); + match param.kind { + GenericParamKind::Lifetime { .. } => {} + GenericParamKind::Type { synthetic, .. } => { + if synthetic.is_none() { + self.check_case(cx, "type parameter", param.name(), param.span); + } } } } @@ -253,13 +256,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { } fn check_generic_param(&mut self, cx: &LateContext, param: &hir::GenericParam) { - if let hir::GenericParam::Lifetime(ref ld) = *param { - self.check_snake_case( - cx, - "lifetime", - &ld.lifetime.name.name().as_str(), - Some(ld.lifetime.span) - ); + match param.kind { + GenericParamKind::Lifetime { .. } => { + self.check_snake_case(cx, "lifetime", ¶m.name().as_str(), Some(param.span)); + } + GenericParamKind::Type { .. } => {} } } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 79796d788719..b981d075d534 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -49,7 +49,7 @@ use syntax_pos::{BytePos, Span, SyntaxContext}; use syntax::symbol::keywords; use syntax::errors::{Applicability, DiagnosticBuilder}; -use rustc::hir::{self, PatKind}; +use rustc::hir::{self, GenericParamKind, PatKind}; use rustc::hir::intravisit::FnKind; use bad_style::{MethodLateContext, method_context}; @@ -1531,9 +1531,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds { } // The parameters must not have bounds for param in type_alias_generics.params.iter() { - let spans : Vec<_> = match param { - &hir::GenericParam::Lifetime(ref l) => l.bounds.iter().map(|b| b.span).collect(), - &hir::GenericParam::Type(ref ty) => ty.bounds.iter().map(|b| b.span()).collect(), + let spans: Vec<_> = match param.kind { + GenericParamKind::Lifetime { ref bounds, .. } => { + bounds.iter().map(|b| b.span).collect() + } + GenericParamKind::Type { ref bounds, .. } => { + bounds.iter().map(|b| b.span()).collect() + } }; if !spans.is_empty() { let mut err = cx.struct_span_lint( diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 33d4df1c3a5d..c1a22c353c7a 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -1645,10 +1645,17 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { } fn encode_info_for_generics(&mut self, generics: &hir::Generics) { - for ty_param in generics.ty_params() { - let def_id = self.tcx.hir.local_def_id(ty_param.id); - let has_default = Untracked(ty_param.default.is_some()); - self.record(def_id, IsolatedEncoder::encode_info_for_ty_param, (def_id, has_default)); + for param in &generics.params { + match param.kind { + hir::GenericParamKind::Lifetime { .. } => {} + hir::GenericParamKind::Type { ref default, .. } => { + let def_id = self.tcx.hir.local_def_id(param.id); + let has_default = Untracked(default.is_some()); + self.record(def_id, + IsolatedEncoder::encode_info_for_ty_param, + (def_id, has_default)); + } + } } } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 291092015b57..19ed04a79684 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -22,7 +22,7 @@ extern crate rustc_typeck; extern crate syntax_pos; extern crate rustc_data_structures; -use rustc::hir::{self, PatKind}; +use rustc::hir::{self, GenericParamKind, PatKind}; use rustc::hir::def::Def; use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId}; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; @@ -1268,9 +1268,14 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { } fn visit_generics(&mut self, generics: &'tcx hir::Generics) { - for ty_param in generics.ty_params() { - for bound in ty_param.bounds.iter() { - self.check_ty_param_bound(bound) + for param in &generics.params { + match param.kind { + GenericParamKind::Lifetime { .. } => {} + GenericParamKind::Type { ref bounds, .. } => { + for bound in bounds { + self.check_ty_param_bound(bound); + } + } } } for predicate in &generics.where_clause.predicates { diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 808c134e9944..f573ad7ef275 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc::hir::{self, ImplItemKind, TraitItemKind}; +use rustc::hir::{self, GenericParamKind, ImplItemKind, TraitItemKind}; use rustc::infer::{self, InferOk}; use rustc::ty::{self, TyCtxt, GenericParamDefKind}; use rustc::ty::util::ExplicitSelf; @@ -843,19 +843,19 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } let span = visitor.0?; - let param = impl_m.generics.params.iter().filter_map(|param| { - match param { - hir::GenericParam::Type(param) => { + let bounds = impl_m.generics.params.iter().find_map(|param| { + match param.kind { + GenericParamKind::Lifetime { .. } => None, + GenericParamKind::Type { ref bounds, .. } => { if param.id == impl_node_id { - Some(param) + Some(bounds) } else { None } - }, - hir::GenericParam::Lifetime(..) => None, + } } - }).next()?; - let bounds = param.bounds.first()?.span().to(param.bounds.last()?.span()); + })?; + let bounds = bounds.first()?.span().to(bounds.last()?.span()); let bounds = tcx .sess .codemap() diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c0779235e893..0066e3ce8466 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5188,9 +5188,8 @@ pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, for (&used, param) in tps_used.iter().zip(generics.ty_params()) { if !used { - struct_span_err!(tcx.sess, param.span, E0091, - "type parameter `{}` is unused", - param.name) + struct_span_err!(tcx.sess, param.span, E0091, "type parameter `{}` is unused", + param.name()) .span_label(param.span, "unused type parameter") .emit(); } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 7a2c38468e04..8d2c1e07ec8e 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -631,11 +631,8 @@ fn check_variances_for_type_defn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, continue; } - let (span, name) = match ast_generics.params[index] { - hir::GenericParam::Lifetime(ref ld) => (ld.lifetime.span, ld.lifetime.name.name()), - hir::GenericParam::Type(ref tp) => (tp.span, tp.name), - }; - report_bivariance(tcx, span, name); + let param = &ast_generics.params[index]; + report_bivariance(tcx, param.span, param.name()); } } diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs index 4aa876e85b69..007ef4dee559 100644 --- a/src/librustc_typeck/coherence/unsafety.rs +++ b/src/librustc_typeck/coherence/unsafety.rs @@ -35,7 +35,14 @@ impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> { Some(trait_ref) => { let trait_def = self.tcx.trait_def(trait_ref.def_id); - let unsafe_attr = impl_generics.and_then(|g| g.carries_unsafe_attr()); + let unsafe_attr = impl_generics.and_then(|g| { + for param in &g.params { + if param.pure_wrt_drop { + return Some("may_dangle"); + } + } + None + }); match (trait_def.unsafety, unsafe_attr, unsafety, polarity) { (Unsafety::Normal, None, Unsafety::Unsafe, hir::ImplPolarity::Positive) => { span_err!(self.tcx.sess, @@ -53,13 +60,14 @@ impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> { trait_ref); } - (Unsafety::Normal, Some(g), Unsafety::Normal, hir::ImplPolarity::Positive) => + (Unsafety::Normal, Some(attr_name), Unsafety::Normal, + hir::ImplPolarity::Positive) => { span_err!(self.tcx.sess, item.span, E0569, "requires an `unsafe impl` declaration due to `#[{}]` attribute", - g.attr_name()); + attr_name); } (_, _, Unsafety::Unsafe, hir::ImplPolarity::Negative) => { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 58e804fc13f2..36436d95e9f1 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -49,6 +49,7 @@ use syntax::feature_gate; use syntax_pos::{Span, DUMMY_SP}; use rustc::hir::{self, map as hir_map, CodegenFnAttrs, CodegenFnAttrFlags, Unsafety}; +use rustc::hir::GenericParamKind; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir::def::{Def, CtorKind}; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; @@ -113,10 +114,15 @@ impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> { } fn visit_generics(&mut self, generics: &'tcx hir::Generics) { - for param in generics.ty_params() { - if param.default.is_some() { - let def_id = self.tcx.hir.local_def_id(param.id); - self.tcx.type_of(def_id); + for param in &generics.params { + match param.kind { + hir::GenericParamKind::Lifetime { .. } => {} + hir::GenericParamKind::Type { ref default, .. } => { + if default.is_some() { + let def_id = self.tcx.hir.local_def_id(param.id); + self.tcx.type_of(def_id); + } + } } } intravisit::walk_generics(self, generics); @@ -308,9 +314,20 @@ impl<'a, 'tcx> ItemCtxt<'a, 'tcx> { -> Vec> { let from_ty_params = - ast_generics.ty_params() - .filter(|p| p.id == param_id) - .flat_map(|p| p.bounds.iter()) + ast_generics.params.iter() + .filter_map(|param| { + match param.kind { + GenericParamKind::Type { ref bounds, .. } => { + if param.id == param_id { + Some(bounds) + } else { + None + } + } + _ => None + } + }) + .flat_map(|bounds| bounds.iter()) .flat_map(|b| predicates_from_bound(self, ty, b)); let from_where_clauses = @@ -740,9 +757,9 @@ fn has_late_bound_regions<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, has_late_bound_regions: None, }; for lifetime in generics.lifetimes() { - let hir_id = tcx.hir.node_to_hir_id(lifetime.lifetime.id); + let hir_id = tcx.hir.node_to_hir_id(lifetime.id); if tcx.is_late_bound(hir_id) { - return Some(lifetime.lifetime.span); + return Some(lifetime.span); } } visitor.visit_fn_decl(decl); @@ -883,12 +900,12 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let mut params: Vec<_> = opt_self.into_iter().collect(); let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics); - params.extend(early_lifetimes.enumerate().map(|(i, l)| { + params.extend(early_lifetimes.enumerate().map(|(i, param)| { ty::GenericParamDef { - name: l.lifetime.name.name().as_interned_str(), + name: param.name().as_interned_str(), index: own_start + i as u32, - def_id: tcx.hir.local_def_id(l.lifetime.id), - pure_wrt_drop: l.pure_wrt_drop, + def_id: tcx.hir.local_def_id(param.id), + pure_wrt_drop: param.pure_wrt_drop, kind: ty::GenericParamDefKind::Lifetime, } })); @@ -898,33 +915,39 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Now create the real type parameters. let type_start = own_start - has_self as u32 + params.len() as u32; - params.extend(ast_generics.ty_params().enumerate().map(|(i, p)| { - if p.name == keywords::SelfType.name() { - span_bug!(p.span, "`Self` should not be the name of a regular parameter"); - } + params.extend(ast_generics.ty_params().enumerate().map(|(i, param)| { + match param.kind { + GenericParamKind::Type { ref default, synthetic, .. } => { + if param.name() == keywords::SelfType.name() { + span_bug!(param.span, + "`Self` should not be the name of a regular parameter"); + } - if !allow_defaults && p.default.is_some() { - if !tcx.features().default_type_parameter_fallback { - tcx.lint_node( - lint::builtin::INVALID_TYPE_PARAM_DEFAULT, - p.id, - p.span, - &format!("defaults for type parameters are only allowed in `struct`, \ - `enum`, `type`, or `trait` definitions.")); + if !allow_defaults && default.is_some() { + if !tcx.features().default_type_parameter_fallback { + tcx.lint_node( + lint::builtin::INVALID_TYPE_PARAM_DEFAULT, + param.id, + param.span, + &format!("defaults for type parameters are only allowed in \ + `struct`, `enum`, `type`, or `trait` definitions.")); + } + } + + ty::GenericParamDef { + index: type_start + i as u32, + name: param.name().as_interned_str(), + def_id: tcx.hir.local_def_id(param.id), + pure_wrt_drop: param.pure_wrt_drop, + kind: ty::GenericParamDefKind::Type { + has_default: default.is_some(), + object_lifetime_default: + object_lifetime_defaults.as_ref().map_or(rl::Set1::Empty, |o| o[i]), + synthetic, + }, + } } - } - - ty::GenericParamDef { - index: type_start + i as u32, - name: p.name.as_interned_str(), - def_id: tcx.hir.local_def_id(p.id), - pure_wrt_drop: p.pure_wrt_drop, - kind: ty::GenericParamDefKind::Type { - has_default: p.default.is_some(), - object_lifetime_default: - object_lifetime_defaults.as_ref().map_or(rl::Set1::Empty, |o| o[i]), - synthetic: p.synthetic, - }, + _ => bug!() } })); @@ -1119,8 +1142,13 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } }, - NodeTyParam(&hir::TyParam { default: Some(ref ty), .. }) => { - icx.to_ty(ty) + NodeGenericParam(param) => { + match param.kind { + hir::GenericParamKind::Type { default: Some(ref ty), .. } => { + icx.to_ty(ty) + } + _ => bug!("unexpected non-type NodeGenericParam"), + } } x => { @@ -1274,15 +1302,18 @@ fn is_unsized<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>, /// `resolve_lifetime::early_bound_lifetimes`. fn early_bound_lifetimes_from_generics<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, - ast_generics: &'a hir::Generics) - -> impl Iterator + Captures<'tcx> + generics: &'a hir::Generics) + -> impl Iterator + Captures<'tcx> { - ast_generics - .lifetimes() - .filter(move |l| { - let hir_id = tcx.hir.node_to_hir_id(l.lifetime.id); - !tcx.is_late_bound(hir_id) - }) + generics.params.iter().filter(move |param| { + match param.kind { + GenericParamKind::Lifetime { .. } => { + let hir_id = tcx.hir.node_to_hir_id(param.id); + !tcx.is_late_bound(hir_id) + } + _ => false, + } + }) } fn predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -1410,28 +1441,38 @@ pub fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let mut index = parent_count + has_own_self as u32; for param in early_bound_lifetimes_from_generics(tcx, ast_generics) { let region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { - def_id: tcx.hir.local_def_id(param.lifetime.id), + def_id: tcx.hir.local_def_id(param.id), index, - name: param.lifetime.name.name().as_interned_str(), + name: param.name().as_interned_str(), })); index += 1; - for bound in ¶m.bounds { - let bound_region = AstConv::ast_region_to_region(&icx, bound, None); - let outlives = ty::Binder::bind(ty::OutlivesPredicate(region, bound_region)); - predicates.push(outlives.to_predicate()); + match param.kind { + GenericParamKind::Lifetime { ref bounds, .. } => { + for bound in bounds { + let bound_region = AstConv::ast_region_to_region(&icx, bound, None); + let outlives = + ty::Binder::bind(ty::OutlivesPredicate(region, bound_region)); + predicates.push(outlives.to_predicate()); + } + }, + _ => bug!(), } } // Collect the predicates that were written inline by the user on each // type parameter (e.g., ``). for param in ast_generics.ty_params() { - let param_ty = ty::ParamTy::new(index, param.name.as_interned_str()).to_ty(tcx); + let param_ty = ty::ParamTy::new(index, param.name().as_interned_str()).to_ty(tcx); index += 1; + let bounds = match param.kind { + GenericParamKind::Type { ref bounds, .. } => bounds, + _ => bug!(), + }; let bounds = compute_bounds(&icx, param_ty, - ¶m.bounds, + bounds, SizedByDefault::Yes, param.span); predicates.extend(bounds.predicates(tcx, param_ty)); diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 80f57adf580b..fb005ba18e9f 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -76,6 +76,7 @@ This API is completely unstable and subject to change. #![feature(crate_visibility_modifier)] #![feature(from_ref)] #![feature(exhaustive_patterns)] +#![feature(iterator_find_map)] #![feature(quote)] #![feature(refcell_replace_swap)] #![feature(rustc_diagnostic_macros)] diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 0d44c583cffd..40fdd6d8d2de 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1466,14 +1466,19 @@ pub struct TyParam { pub synthetic: Option, } -impl Clean for hir::TyParam { +impl Clean for hir::GenericParam { fn clean(&self, cx: &DocContext) -> TyParam { - TyParam { - name: self.name.clean(cx), - did: cx.tcx.hir.local_def_id(self.id), - bounds: self.bounds.clean(cx), - default: self.default.clean(cx), - synthetic: self.synthetic, + match self.kind { + hir::GenericParamKind::Type { ref bounds, ref default, synthetic, .. } => { + TyParam { + name: self.name().clean(cx), + did: cx.tcx.hir.local_def_id(self.id), + bounds: bounds.clean(cx), + default: default.clean(cx), + synthetic: synthetic, + } + } + _ => panic!(), } } } @@ -1707,18 +1712,21 @@ impl Clean for hir::Lifetime { } } -impl Clean for hir::LifetimeDef { +impl Clean for hir::GenericParam { fn clean(&self, _: &DocContext) -> Lifetime { - if self.bounds.len() > 0 { - let mut s = format!("{}: {}", - self.lifetime.name.name(), - self.bounds[0].name.name()); - for bound in self.bounds.iter().skip(1) { - s.push_str(&format!(" + {}", bound.name.name())); + match self.kind { + hir::GenericParamKind::Lifetime { ref bounds, .. } => { + if bounds.len() > 0 { + let mut s = format!("{}: {}", self.name(), bounds[0].name.name()); + for bound in bounds.iter().skip(1) { + s.push_str(&format!(" + {}", bound.name.name())); + } + Lifetime(s) + } else { + Lifetime(self.name().to_string()) + } } - Lifetime(s) - } else { - Lifetime(self.lifetime.name.name().to_string()) + _ => panic!(), } } } @@ -1880,9 +1888,11 @@ impl GenericParamDef { impl Clean for hir::GenericParam { fn clean(&self, cx: &DocContext) -> GenericParamDef { - match *self { - hir::GenericParam::Lifetime(ref l) => GenericParamDef::Lifetime(l.clean(cx)), - hir::GenericParam::Type(ref t) => GenericParamDef::Type(t.clean(cx)), + match self.kind { + hir::GenericParamKind::Lifetime { .. } => { + GenericParamDef::Lifetime(self.clean(cx)) + } + hir::GenericParamKind::Type { .. } => GenericParamDef::Type(self.clean(cx)), } } } @@ -1900,10 +1910,11 @@ impl Clean for hir::Generics { // In order for normal parameters to be able to refer to synthetic ones, // scans them first. fn is_impl_trait(param: &hir::GenericParam) -> bool { - if let hir::GenericParam::Type(ref tp) = param { - tp.synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) - } else { - false + match param.kind { + hir::GenericParamKind::Type { synthetic, .. } => { + synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) + } + _ => false, } } let impl_trait_params = self.params @@ -2857,25 +2868,25 @@ impl Clean for hir::Ty { types: 0 }; for param in generics.params.iter() { - match param { - hir::GenericParam::Lifetime(lt_param) => { + match param.kind { + hir::GenericParamKind::Lifetime { .. } => { if let Some(lt) = generic_args.lifetimes() .nth(indices.lifetimes).cloned() { if !lt.is_elided() { let lt_def_id = - cx.tcx.hir.local_def_id(lt_param.lifetime.id); + cx.tcx.hir.local_def_id(param.id); lt_substs.insert(lt_def_id, lt.clean(cx)); } } indices.lifetimes += 1; } - hir::GenericParam::Type(ty_param) => { + hir::GenericParamKind::Type { ref default, .. } => { let ty_param_def = - Def::TyParam(cx.tcx.hir.local_def_id(ty_param.id)); + Def::TyParam(cx.tcx.hir.local_def_id(param.id)); if let Some(ty) = generic_args.types() .nth(indices.types).cloned() { ty_substs.insert(ty_param_def, ty.into_inner().clean(cx)); - } else if let Some(default) = ty_param.default.clone() { + } else if let Some(default) = default.clone() { ty_substs.insert(ty_param_def, default.into_inner().clean(cx)); } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 8a4fde21e63f..091673bfba99 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -73,7 +73,9 @@ pub trait Visitor<'ast>: Sized { fn visit_expr(&mut self, ex: &'ast Expr) { walk_expr(self, ex) } fn visit_expr_post(&mut self, _ex: &'ast Expr) { } fn visit_ty(&mut self, t: &'ast Ty) { walk_ty(self, t) } - fn visit_generic_param(&mut self, param: &'ast GenericParamAST) { walk_generic_param(self, param) } + fn visit_generic_param(&mut self, param: &'ast GenericParamAST) { + walk_generic_param(self, param) + } fn visit_generics(&mut self, g: &'ast Generics) { walk_generics(self, g) } fn visit_where_predicate(&mut self, p: &'ast WherePredicate) { walk_where_predicate(self, p) diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index f85091b0e719..4bc8d208bab9 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -568,7 +568,8 @@ impl<'a> TraitDef<'a> { bounds.push((*declared_bound).clone()); } - GenericParamAST::Type(cx.typaram(self.span, ty_param.ident, vec![], bounds, None)) + let ty_param = cx.typaram(self.span, ty_param.ident, vec![], bounds, None); + GenericParamAST::Type(ty_param) } } })); diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs index 92046262ed25..22487e7bfe39 100644 --- a/src/libsyntax_ext/deriving/generic/ty.rs +++ b/src/libsyntax_ext/deriving/generic/ty.rs @@ -192,7 +192,9 @@ impl<'a> Ty<'a> { let ty_params: Vec> = self_generics.params .iter() .filter_map(|param| match *param { - GenericParamAST::Type(ref ty_param) => Some(cx.ty_ident(span, ty_param.ident)), + GenericParamAST::Type(ref ty_param) => { + Some(cx.ty_ident(span, ty_param.ident)) + } _ => None, }) .collect(); @@ -280,7 +282,8 @@ impl<'a> LifetimeBounds<'a> { let bounds = bounds.iter() .map(|b| cx.lifetime(span, Ident::from_str(b))) .collect(); - GenericParamAST::Lifetime(cx.lifetime_def(span, Ident::from_str(lt), vec![], bounds)) + let lifetime_def = cx.lifetime_def(span, Ident::from_str(lt), vec![], bounds); + GenericParamAST::Lifetime(lifetime_def) }) .chain(self.bounds .iter()