diff options
| author | Taylor Cramer <cramertj@google.com> | 2017-09-19 16:36:54 -0700 |
|---|---|---|
| committer | Taylor Cramer <cramertj@google.com> | 2017-09-21 10:19:03 -0700 |
| commit | f64af7a32e83ae6c02a0e0378c024e687fec5223 (patch) | |
| tree | ed16ec1b749116db24ad2ddd00a2fe5ea110cdb6 | |
| parent | 64314e3ae218cb004735735667581f12df8461ef (diff) | |
| download | rust-f64af7a32e83ae6c02a0e0378c024e687fec5223.tar.gz rust-f64af7a32e83ae6c02a0e0378c024e687fec5223.zip | |
Refactor lifetime name into an enum
| -rw-r--r-- | src/librustc/hir/intravisit.rs | 7 | ||||
| -rw-r--r-- | src/librustc/hir/lowering.rs | 8 | ||||
| -rw-r--r-- | src/librustc/hir/map/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustc/hir/mod.rs | 31 | ||||
| -rw-r--r-- | src/librustc/hir/print.rs | 2 | ||||
| -rw-r--r-- | src/librustc/ich/impls_hir.rs | 7 | ||||
| -rw-r--r-- | src/librustc/middle/resolve_lifetime.rs | 84 | ||||
| -rw-r--r-- | src/librustc_lint/bad_style.rs | 2 | ||||
| -rw-r--r-- | src/librustc_typeck/check/wfcheck.rs | 2 | ||||
| -rw-r--r-- | src/librustc_typeck/collect.rs | 4 | ||||
| -rw-r--r-- | src/librustc_typeck/impl_wf_check.rs | 2 | ||||
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 10 | ||||
| -rw-r--r-- | src/test/run-pass/underscore-lifetimes.rs | 12 |
13 files changed, 118 insertions, 55 deletions
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 9d8075de2eb..088fd8d9090 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -422,7 +422,12 @@ pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) { pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) { visitor.visit_id(lifetime.id); - visitor.visit_name(lifetime.span, lifetime.name); + match lifetime.name { + LifetimeName::Name(name) => { + visitor.visit_name(lifetime.span, name); + } + LifetimeName::Static | LifetimeName::Implicit | LifetimeName::Underscore => {} + } } pub fn walk_lifetime_def<'v, V: Visitor<'v>>(visitor: &mut V, lifetime_def: &'v LifetimeDef) { diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index c7ea9c47028..465520ea034 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1121,7 +1121,11 @@ impl<'a> LoweringContext<'a> { fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime { hir::Lifetime { id: self.lower_node_id(l.id).node_id, - name: self.lower_ident(l.ident), + name: match self.lower_ident(l.ident) { + x if x == "'_" => hir::LifetimeName::Underscore, + x if x == "'static" => hir::LifetimeName::Static, + name => hir::LifetimeName::Name(name), + }, span: l.span, } } @@ -3005,7 +3009,7 @@ impl<'a> LoweringContext<'a> { hir::Lifetime { id: self.next_id().node_id, span, - name: keywords::Invalid.name() + name: hir::LifetimeName::Implicit, } } } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index b2d6886e7f2..c0577039f0c 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -805,7 +805,7 @@ impl<'hir> Map<'hir> { NodeTraitItem(ti) => ti.name, NodeVariant(v) => v.node.name, NodeField(f) => f.name, - NodeLifetime(lt) => lt.name, + NodeLifetime(lt) => lt.name.name(), NodeTyParam(tp) => tp.name, NodeBinding(&Pat { node: PatKind::Binding(_,_,l,_), .. }) => l.node, NodeStructCtor(_) => self.name(self.get_parent(id)), diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 3d82481807e..1bef17b28ac 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -145,7 +145,27 @@ pub struct Lifetime { /// 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`. - pub name: Name, + pub name: LifetimeName, +} + +#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)] +pub enum LifetimeName { + Implicit, + Underscore, + Static, + Name(Name), +} + +impl LifetimeName { + pub fn name(&self) -> Name { + use self::LifetimeName::*; + match *self { + Implicit => keywords::Invalid.name(), + Underscore => Symbol::intern("'_"), + Static => keywords::StaticLifetime.name(), + Name(name) => name, + } + } } impl fmt::Debug for Lifetime { @@ -159,12 +179,15 @@ impl fmt::Debug for Lifetime { impl Lifetime { pub fn is_elided(&self) -> bool { - self.name == keywords::Invalid.name() || - self.name == "'_" + use self::LifetimeName::*; + match self.name { + Implicit | Underscore => true, + Static | Name(_) => false, + } } pub fn is_static(&self) -> bool { - self.name == "'static" + self.name == LifetimeName::Static } } diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 41a253f7904..ad31b2009a0 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1975,7 +1975,7 @@ impl<'a> State<'a> { } pub fn print_lifetime(&mut self, lifetime: &hir::Lifetime) -> io::Result<()> { - self.print_name(lifetime.name) + self.print_name(lifetime.name.name()) } pub fn print_lifetime_def(&mut self, lifetime: &hir::LifetimeDef) -> io::Result<()> { diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 9582b03ce1c..b3af44c952b 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -123,6 +123,13 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::ImplItemId { } } +impl_stable_hash_for!(enum hir::LifetimeName { + Implicit, + Underscore, + Static, + Name(name) +}); + impl_stable_hash_for!(struct hir::Lifetime { id, span, diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 8b58c75e241..60f03eb5d89 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -46,14 +46,16 @@ pub enum Region { } impl Region { - fn early(hir_map: &Map, index: &mut u32, def: &hir::LifetimeDef) -> (ast::Name, Region) { + fn early(hir_map: &Map, index: &mut u32, def: &hir::LifetimeDef) + -> (hir::LifetimeName, Region) + { let i = *index; *index += 1; let def_id = hir_map.local_def_id(def.lifetime.id); (def.lifetime.name, Region::EarlyBound(i, def_id)) } - fn late(hir_map: &Map, def: &hir::LifetimeDef) -> (ast::Name, Region) { + fn late(hir_map: &Map, def: &hir::LifetimeDef) -> (hir::LifetimeName, Region) { let depth = ty::DebruijnIndex::new(1); let def_id = hir_map.local_def_id(def.lifetime.id); (def.lifetime.name, Region::LateBound(depth, def_id)) @@ -198,7 +200,7 @@ enum Scope<'a> { /// it should be shifted by the number of `Binder`s in between the /// declaration `Binder` and the location it's referenced from. Binder { - lifetimes: FxHashMap<ast::Name, Region>, + lifetimes: FxHashMap<hir::LifetimeName, Region>, s: ScopeRef<'a> }, @@ -654,7 +656,7 @@ fn extract_labels(ctxt: &mut LifetimeContext, body: &hir::Body) { Scope::Binder { ref lifetimes, s } => { // FIXME (#24278): non-hygienic comparison - if let Some(def) = lifetimes.get(&label) { + if let Some(def) = lifetimes.get(&hir::LifetimeName::Name(label)) { let node_id = hir_map.as_local_node_id(def.id().unwrap()) .unwrap(); @@ -692,7 +694,7 @@ fn compute_object_lifetime_defaults(sess: &Session, hir_map: &Map) Set1::Empty => "BaseDefault".to_string(), Set1::One(Region::Static) => "'static".to_string(), Set1::One(Region::EarlyBound(i, _)) => { - generics.lifetimes[i as usize].lifetime.name.to_string() + generics.lifetimes[i as usize].lifetime.name.name().to_string() } Set1::One(_) => bug!(), Set1::Many => "Ambiguous".to_string(), @@ -714,7 +716,7 @@ fn compute_object_lifetime_defaults(sess: &Session, hir_map: &Map) /// for each type parameter. fn object_lifetime_defaults_for_item(hir_map: &Map, generics: &hir::Generics) -> Vec<ObjectLifetimeDefault> { - fn add_bounds(set: &mut Set1<ast::Name>, bounds: &[hir::TyParamBound]) { + fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::TyParamBound]) { for bound in bounds { if let hir::RegionTyParamBound(ref lifetime) = *bound { set.insert(lifetime.name); @@ -754,7 +756,7 @@ fn object_lifetime_defaults_for_item(hir_map: &Map, generics: &hir::Generics) match set { Set1::Empty => Set1::Empty, Set1::One(name) => { - if name == "'static" { + if name == hir::LifetimeName::Static { Set1::One(Region::Static) } else { generics.lifetimes.iter().enumerate().find(|&(_, def)| { @@ -922,7 +924,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { self.insert_lifetime(lifetime_ref, def); } else { struct_span_err!(self.sess, lifetime_ref.span, E0261, - "use of undeclared lifetime name `{}`", lifetime_ref.name) + "use of undeclared lifetime name `{}`", lifetime_ref.name.name()) .span_label(lifetime_ref.span, "undeclared lifetime") .emit(); } @@ -1422,13 +1424,17 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let lifetime_i = &lifetimes[i]; for lifetime in lifetimes { - if lifetime.lifetime.is_static() || lifetime.lifetime.name == "'_" { - let lifetime = lifetime.lifetime; - let mut err = struct_span_err!(self.sess, lifetime.span, E0262, - "invalid lifetime parameter name: `{}`", lifetime.name); - err.span_label(lifetime.span, - format!("{} is a reserved lifetime name", lifetime.name)); - err.emit(); + match lifetime.lifetime.name { + hir::LifetimeName::Static | hir::LifetimeName::Underscore => { + let lifetime = lifetime.lifetime; + let name = lifetime.name.name(); + let mut err = struct_span_err!(self.sess, lifetime.span, E0262, + "invalid lifetime parameter name: `{}`", name); + err.span_label(lifetime.span, + format!("{} is a reserved lifetime name", name)); + err.emit(); + } + hir::LifetimeName::Implicit | hir::LifetimeName::Name(_) => {} } } @@ -1439,7 +1445,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { if lifetime_i.lifetime.name == lifetime_j.lifetime.name { struct_span_err!(self.sess, lifetime_j.lifetime.span, E0263, "lifetime name `{}` declared twice in the same scope", - lifetime_j.lifetime.name) + lifetime_j.lifetime.name.name()) .span_label(lifetime_j.lifetime.span, "declared twice") .span_label(lifetime_i.lifetime.span, @@ -1452,21 +1458,27 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { self.check_lifetime_def_for_shadowing(old_scope, &lifetime_i.lifetime); for bound in &lifetime_i.bounds { - if bound.name == "'_" { - let mut err = struct_span_err!(self.sess, bound.span, E0637, - "invalid lifetime bound name: `{}`", bound.name); - err.span_label(bound.span, - format!("{} is a reserved lifetime name", bound.name)); - err.emit(); - } else if !bound.is_static() { - self.resolve_lifetime_ref(bound); - } else { - self.insert_lifetime(bound, Region::Static); - self.sess.struct_span_warn(lifetime_i.lifetime.span.to(bound.span), - &format!("unnecessary lifetime parameter `{}`", lifetime_i.lifetime.name)) - .help(&format!("you can use the `'static` lifetime directly, in place \ - of `{}`", lifetime_i.lifetime.name)) - .emit(); + match bound.name { + hir::LifetimeName::Underscore => { + let mut err = struct_span_err!(self.sess, bound.span, E0637, + "invalid lifetime bound name: `'_`"); + err.span_label(bound.span, "`'_` is a reserved lifetime name"); + err.emit(); + } + hir::LifetimeName::Static => { + self.insert_lifetime(bound, Region::Static); + self.sess.struct_span_warn(lifetime_i.lifetime.span.to(bound.span), + &format!("unnecessary lifetime parameter `{}`", + lifetime_i.lifetime.name.name())) + .help(&format!( + "you can use the `'static` lifetime directly, in place \ + of `{}`", lifetime_i.lifetime.name.name())) + .emit(); + } + hir::LifetimeName::Implicit | + hir::LifetimeName::Name(_) => { + self.resolve_lifetime_ref(bound); + } } } } @@ -1478,9 +1490,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { { for &(label, label_span) in &self.labels_in_fn { // FIXME (#24278): non-hygienic comparison - if lifetime.name == label { + if lifetime.name.name() == label { signal_shadowing_problem(self.sess, - lifetime.name, + label, original_label(label_span), shadower_lifetime(&lifetime)); return; @@ -1507,7 +1519,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { signal_shadowing_problem( self.sess, - lifetime.name, + lifetime.name.name(), original_lifetime(self.hir_map.span(node_id)), shadower_lifetime(&lifetime)); return; @@ -1623,7 +1635,7 @@ fn insert_late_bound_lifetimes(map: &mut NamedRegionMap, return; struct ConstrainedCollector { - regions: FxHashSet<ast::Name>, + regions: FxHashSet<hir::LifetimeName>, } impl<'v> Visitor<'v> for ConstrainedCollector { @@ -1663,7 +1675,7 @@ fn insert_late_bound_lifetimes(map: &mut NamedRegionMap, } struct AllCollector { - regions: FxHashSet<ast::Name>, + regions: FxHashSet<hir::LifetimeName>, impl_trait: bool } diff --git a/src/librustc_lint/bad_style.rs b/src/librustc_lint/bad_style.rs index d4b8f0a4924..cbc012a65fa 100644 --- a/src/librustc_lint/bad_style.rs +++ b/src/librustc_lint/bad_style.rs @@ -278,7 +278,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { fn check_lifetime_def(&mut self, cx: &LateContext, t: &hir::LifetimeDef) { self.check_snake_case(cx, "lifetime", - &t.lifetime.name.as_str(), + &t.lifetime.name.name().as_str(), Some(t.lifetime.span)); } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index f17df8b22f3..ddbdd204305 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -523,7 +523,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { let (span, name) = if index < ast_generics.lifetimes.len() { (ast_generics.lifetimes[index].lifetime.span, - ast_generics.lifetimes[index].lifetime.name) + ast_generics.lifetimes[index].lifetime.name.name()) } else { let index = index - ast_generics.lifetimes.len(); (ast_generics.ty_params[index].span, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 79cb9147c18..8d078b92275 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -953,7 +953,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics); let regions = early_lifetimes.enumerate().map(|(i, l)| { ty::RegionParameterDef { - name: l.lifetime.name, + name: l.lifetime.name.name(), index: own_start + i as u32, def_id: tcx.hir.local_def_id(l.lifetime.id), pure_wrt_drop: l.pure_wrt_drop, @@ -1423,7 +1423,7 @@ fn predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { def_id: tcx.hir.local_def_id(param.lifetime.id), index, - name: param.lifetime.name + name: param.lifetime.name.name(), })); index += 1; diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index 14e48b93029..15708ab766a 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -132,7 +132,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, !input_parameters.contains(¶m) { report_unused_parameter(tcx, lifetime.lifetime.span, - "lifetime", &lifetime.lifetime.name.to_string()); + "lifetime", &lifetime.lifetime.name.name().to_string()); } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 095eb7797d4..1e25a57b1d2 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -876,7 +876,7 @@ impl Clean<Lifetime> for hir::Lifetime { } _ => {} } - Lifetime(self.name.to_string()) + Lifetime(self.name.name().to_string()) } } @@ -884,14 +884,14 @@ impl Clean<Lifetime> for hir::LifetimeDef { fn clean(&self, _: &DocContext) -> Lifetime { if self.bounds.len() > 0 { let mut s = format!("{}: {}", - self.lifetime.name.to_string(), - self.bounds[0].name.to_string()); + self.lifetime.name.name(), + self.bounds[0].name.name()); for bound in self.bounds.iter().skip(1) { - s.push_str(&format!(" + {}", bound.name.to_string())); + s.push_str(&format!(" + {}", bound.name.name())); } Lifetime(s) } else { - Lifetime(self.lifetime.name.to_string()) + Lifetime(self.lifetime.name.name().to_string()) } } } diff --git a/src/test/run-pass/underscore-lifetimes.rs b/src/test/run-pass/underscore-lifetimes.rs index d3db34a7caa..ed0369353bc 100644 --- a/src/test/run-pass/underscore-lifetimes.rs +++ b/src/test/run-pass/underscore-lifetimes.rs @@ -26,10 +26,22 @@ fn foo3(x: &'_ u8) -> Foo { fn foo4(_: Foo<'_>) {} +struct Foo2<'a, 'b> { + a: &'a u8, + b: &'b u8, +} +fn foo5<'b>(foo: Foo2<'_, 'b>) -> &'b u8 { + foo.b +} + fn main() { let x = &5; let _ = foo(x); let _ = foo2(x); let _ = foo3(x); foo4(Foo(x)); + let _ = foo5(Foo2 { + a: x, + b: &6, + }); } |
