summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2018-05-30 14:36:53 +0300
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2018-05-30 20:29:38 +0300
commit5c76b64546a0bb8f087562e4d19d62b828c8d6d0 (patch)
treeeeea50a12b45dbbbad9c26b94b27db9af008fea3
parentsyntax: remove overloading of fold_lifetime{,_def}{,s}. (diff)
downloadgrust-5c76b64546a0bb8f087562e4d19d62b828c8d6d0.tar.gz
grust-5c76b64546a0bb8f087562e4d19d62b828c8d6d0.tar.bz2
grust-5c76b64546a0bb8f087562e4d19d62b828c8d6d0.tar.xz
rustc: don't visit lifetime parameters through visit_lifetime.
-rw-r--r--src/librustc/hir/intravisit.rs13
-rw-r--r--src/librustc/hir/lowering.rs35
-rw-r--r--src/librustc/hir/map/collector.rs14
-rw-r--r--src/librustc/middle/resolve_lifetime.rs100
-rw-r--r--src/librustc_passes/ast_validation.rs7
-rw-r--r--src/libsyntax/visit.rs4
-rw-r--r--src/test/compile-fail/underscore-lifetime-binders.rs1
-rw-r--r--src/test/run-pass/issue-51185.rs17
8 files changed, 102 insertions, 89 deletions
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index 5a49ee30d9..5471568d0a 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -580,8 +580,8 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
580 walk_list!(visitor, visit_ty, tuple_element_types); 580 walk_list!(visitor, visit_ty, tuple_element_types);
581 } 581 }
582 TyBareFn(ref function_declaration) => { 582 TyBareFn(ref function_declaration) => {
583 visitor.visit_fn_decl(&function_declaration.decl);
584 walk_list!(visitor, visit_generic_param, &function_declaration.generic_params); 583 walk_list!(visitor, visit_generic_param, &function_declaration.generic_params);
584 visitor.visit_fn_decl(&function_declaration.decl);
585 } 585 }
586 TyPath(ref qpath) => { 586 TyPath(ref qpath) => {
587 visitor.visit_qpath(qpath, typ.id, typ.span); 587 visitor.visit_qpath(qpath, typ.id, typ.span);
@@ -733,7 +733,16 @@ pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v TyPar
733pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v GenericParam) { 733pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v GenericParam) {
734 match *param { 734 match *param {
735 GenericParam::Lifetime(ref ld) => { 735 GenericParam::Lifetime(ref ld) => {
736 visitor.visit_lifetime(&ld.lifetime); 736 visitor.visit_id(ld.lifetime.id);
737 match ld.lifetime.name {
738 LifetimeName::Name(name) => {
739 visitor.visit_name(ld.lifetime.span, name);
740 }
741 LifetimeName::Fresh(_) |
742 LifetimeName::Static |
743 LifetimeName::Implicit |
744 LifetimeName::Underscore => {}
745 }
737 walk_list!(visitor, visit_lifetime, &ld.bounds); 746 walk_list!(visitor, visit_lifetime, &ld.bounds);
738 } 747 }
739 GenericParam::Type(ref ty_param) => { 748 GenericParam::Type(ref ty_param) => {
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index f24a803bac..af269078b6 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -1214,7 +1214,13 @@ impl<'a> LoweringContext<'a> {
1214 if let &hir::Ty_::TyBareFn(_) = &t.node { 1214 if let &hir::Ty_::TyBareFn(_) = &t.node {
1215 let old_collect_elided_lifetimes = self.collect_elided_lifetimes; 1215 let old_collect_elided_lifetimes = self.collect_elided_lifetimes;
1216 self.collect_elided_lifetimes = false; 1216 self.collect_elided_lifetimes = false;
1217
1218 // Record the "stack height" of `for<'a>` lifetime bindings
1219 // to be able to later fully undo their introduction.
1220 let old_len = self.currently_bound_lifetimes.len();
1217 hir::intravisit::walk_ty(self, t); 1221 hir::intravisit::walk_ty(self, t);
1222 self.currently_bound_lifetimes.truncate(old_len);
1223
1218 self.collect_elided_lifetimes = old_collect_elided_lifetimes; 1224 self.collect_elided_lifetimes = old_collect_elided_lifetimes;
1219 } else { 1225 } else {
1220 hir::intravisit::walk_ty(self, t); 1226 hir::intravisit::walk_ty(self, t);
@@ -1223,28 +1229,25 @@ impl<'a> LoweringContext<'a> {
1223 1229
1224 fn visit_poly_trait_ref( 1230 fn visit_poly_trait_ref(
1225 &mut self, 1231 &mut self,
1226 polytr: &'v hir::PolyTraitRef, 1232 trait_ref: &'v hir::PolyTraitRef,
1227 _: hir::TraitBoundModifier, 1233 modifier: hir::TraitBoundModifier,
1228 ) { 1234 ) {
1235 // Record the "stack height" of `for<'a>` lifetime bindings
1236 // to be able to later fully undo their introduction.
1229 let old_len = self.currently_bound_lifetimes.len(); 1237 let old_len = self.currently_bound_lifetimes.len();
1238 hir::intravisit::walk_poly_trait_ref(self, trait_ref, modifier);
1239 self.currently_bound_lifetimes.truncate(old_len);
1240 }
1230 1241
1242 fn visit_generic_param(&mut self, param: &'v hir::GenericParam) {
1231 // Record the introduction of 'a in `for<'a> ...` 1243 // Record the introduction of 'a in `for<'a> ...`
1232 for param in &polytr.bound_generic_params { 1244 if let hir::GenericParam::Lifetime(ref lt_def) = *param {
1233 if let hir::GenericParam::Lifetime(ref lt_def) = *param { 1245 // Introduce lifetimes one at a time so that we can handle
1234 // Introduce lifetimes one at a time so that we can handle 1246 // cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd>`
1235 // cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd>` 1247 self.currently_bound_lifetimes.push(lt_def.lifetime.name);
1236 self.currently_bound_lifetimes.push(lt_def.lifetime.name);
1237
1238 // Visit the lifetime bounds
1239 for lt_bound in &lt_def.bounds {
1240 self.visit_lifetime(&lt_bound);
1241 }
1242 }
1243 } 1248 }
1244 1249
1245 hir::intravisit::walk_trait_ref(self, &polytr.trait_ref); 1250 hir::intravisit::walk_generic_param(self, param);
1246
1247 self.currently_bound_lifetimes.truncate(old_len);
1248 } 1251 }
1249 1252
1250 fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) { 1253 fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs
index 8f28dfab1e..13df1ced60 100644
--- a/src/librustc/hir/map/collector.rs
+++ b/src/librustc/hir/map/collector.rs
@@ -346,12 +346,16 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
346 }); 346 });
347 } 347 }
348 348
349 fn visit_generics(&mut self, generics: &'hir Generics) { 349 fn visit_generic_param(&mut self, param: &'hir GenericParam) {
350 for ty_param in generics.ty_params() { 350 match *param {
351 self.insert(ty_param.id, NodeTyParam(ty_param)); 351 GenericParam::Lifetime(ref ld) => {
352 self.insert(ld.lifetime.id, NodeLifetime(&ld.lifetime));
353 }
354 GenericParam::Type(ref ty_param) => {
355 self.insert(ty_param.id, NodeTyParam(ty_param));
356 }
352 } 357 }
353 358 intravisit::walk_generic_param(self, param);
354 intravisit::walk_generics(self, generics);
355 } 359 }
356 360
357 fn visit_trait_item(&mut self, ti: &'hir TraitItem) { 361 fn visit_trait_item(&mut self, ti: &'hir TraitItem) {
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 53d51d9429..c82597813e 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -1928,10 +1928,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
1928 } 1928 }
1929 1929
1930 fn visit_generic_param(&mut self, param: &hir::GenericParam) { 1930 fn visit_generic_param(&mut self, param: &hir::GenericParam) {
1931 if let hir::GenericParam::Lifetime(ref lifetime_def) = *param { 1931 if let hir::GenericParam::Lifetime(_) = *param {
1932 for l in &lifetime_def.bounds { 1932 // FIXME(eddyb) Do we want this? It only makes a difference
1933 self.visit_lifetime(l); 1933 // if this `for<'a>` lifetime parameter is never used.
1934 } 1934 self.have_bound_regions = true;
1935 } 1935 }
1936 1936
1937 intravisit::walk_generic_param(self, param); 1937 intravisit::walk_generic_param(self, param);
@@ -2144,28 +2144,26 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
2144 2144
2145 fn check_lifetime_params(&mut self, old_scope: ScopeRef, params: &'tcx [hir::GenericParam]) { 2145 fn check_lifetime_params(&mut self, old_scope: ScopeRef, params: &'tcx [hir::GenericParam]) {
2146 for (i, lifetime_i) in params.lifetimes().enumerate() { 2146 for (i, lifetime_i) in params.lifetimes().enumerate() {
2147 for lifetime in params.lifetimes() { 2147 match lifetime_i.lifetime.name {
2148 match lifetime.lifetime.name { 2148 hir::LifetimeName::Static | hir::LifetimeName::Underscore => {
2149 hir::LifetimeName::Static | hir::LifetimeName::Underscore => { 2149 let lifetime = lifetime_i.lifetime;
2150 let lifetime = lifetime.lifetime; 2150 let name = lifetime.name.name();
2151 let name = lifetime.name.name(); 2151 let mut err = struct_span_err!(
2152 let mut err = struct_span_err!( 2152 self.tcx.sess,
2153 self.tcx.sess, 2153 lifetime.span,
2154 lifetime.span, 2154 E0262,
2155 E0262, 2155 "invalid lifetime parameter name: `{}`",
2156 "invalid lifetime parameter name: `{}`", 2156 name
2157 name 2157 );
2158 ); 2158 err.span_label(
2159 err.span_label( 2159 lifetime.span,
2160 lifetime.span, 2160 format!("{} is a reserved lifetime name", name),
2161 format!("{} is a reserved lifetime name", name), 2161 );
2162 ); 2162 err.emit();
2163 err.emit();
2164 }
2165 hir::LifetimeName::Fresh(_)
2166 | hir::LifetimeName::Implicit
2167 | hir::LifetimeName::Name(_) => {}
2168 } 2163 }
2164 hir::LifetimeName::Fresh(_)
2165 | hir::LifetimeName::Implicit
2166 | hir::LifetimeName::Name(_) => {}
2169 } 2167 }
2170 2168
2171 // It is a hard error to shadow a lifetime within the same scope. 2169 // It is a hard error to shadow a lifetime within the same scope.
@@ -2347,31 +2345,18 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
2347 | Region::LateBound(_, def_id, _) 2345 | Region::LateBound(_, def_id, _)
2348 | Region::EarlyBound(_, def_id, _) => { 2346 | Region::EarlyBound(_, def_id, _) => {
2349 // A lifetime declared by the user. 2347 // A lifetime declared by the user.
2350 let def_local_id = self.tcx.hir.as_local_node_id(def_id).unwrap(); 2348 let track_lifetime_uses = self.track_lifetime_uses();
2351 if def_local_id == lifetime_ref.id { 2349 debug!(
2352 // This is weird. Because the HIR defines a 2350 "insert_lifetime: track_lifetime_uses={}",
2353 // lifetime *definition* as wrapping a Lifetime, 2351 track_lifetime_uses
2354 // we wind up invoking this method also for the 2352 );
2355 // definitions in some cases (notably 2353 if track_lifetime_uses && !self.lifetime_uses.contains_key(&def_id) {
2356 // higher-ranked types). This means that a 2354 debug!("insert_lifetime: first use of {:?}", def_id);
2357 // lifetime with one use (e.g., `for<'a> fn(&'a 2355 self.lifetime_uses
2358 // u32)`) wind up being counted as two uses. To 2356 .insert(def_id, LifetimeUseSet::One(lifetime_ref));
2359 // avoid that, we just ignore the lifetime that
2360 // corresponds to the definition.
2361 } else { 2357 } else {
2362 let track_lifetime_uses = self.track_lifetime_uses(); 2358 debug!("insert_lifetime: many uses of {:?}", def_id);
2363 debug!( 2359 self.lifetime_uses.insert(def_id, LifetimeUseSet::Many);
2364 "insert_lifetime: track_lifetime_uses={}",
2365 track_lifetime_uses
2366 );
2367 if track_lifetime_uses && !self.lifetime_uses.contains_key(&def_id) {
2368 debug!("insert_lifetime: first use of {:?}", def_id);
2369 self.lifetime_uses
2370 .insert(def_id, LifetimeUseSet::One(lifetime_ref));
2371 } else {
2372 debug!("insert_lifetime: many uses of {:?}", def_id);
2373 self.lifetime_uses.insert(def_id, LifetimeUseSet::Many);
2374 }
2375 } 2360 }
2376 } 2361 }
2377 } 2362 }
@@ -2424,31 +2409,20 @@ fn insert_late_bound_lifetimes(
2424 let mut appears_in_where_clause = AllCollector { 2409 let mut appears_in_where_clause = AllCollector {
2425 regions: FxHashSet(), 2410 regions: FxHashSet(),
2426 }; 2411 };
2412 appears_in_where_clause.visit_generics(generics);
2427 2413
2428 for param in &generics.params { 2414 for param in &generics.params {
2429 match *param { 2415 match *param {
2430 hir::GenericParam::Lifetime(ref lifetime_def) => { 2416 hir::GenericParam::Lifetime(ref lifetime_def) => {
2431 if !lifetime_def.bounds.is_empty() { 2417 if !lifetime_def.bounds.is_empty() {
2432 // `'a: 'b` means both `'a` and `'b` are referenced 2418 // `'a: 'b` means both `'a` and `'b` are referenced
2433 appears_in_where_clause.visit_generic_param(param); 2419 appears_in_where_clause.regions.insert(lifetime_def.lifetime.name);
2434 } 2420 }
2435 } 2421 }
2436 hir::GenericParam::Type(ref ty_param) => { 2422 hir::GenericParam::Type(_) => {}
2437 walk_list!(
2438 &mut appears_in_where_clause,
2439 visit_ty_param_bound,
2440 &ty_param.bounds
2441 );
2442 }
2443 } 2423 }
2444 } 2424 }
2445 2425
2446 walk_list!(
2447 &mut appears_in_where_clause,
2448 visit_where_predicate,
2449 &generics.where_clause.predicates
2450 );
2451
2452 debug!( 2426 debug!(
2453 "insert_late_bound_lifetimes: appears_in_where_clause={:?}", 2427 "insert_late_bound_lifetimes: appears_in_where_clause={:?}",
2454 appears_in_where_clause.regions 2428 appears_in_where_clause.regions
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index abbd399a94..39e0a53925 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -441,6 +441,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
441 visit::walk_generics(self, g) 441 visit::walk_generics(self, g)
442 } 442 }
443 443
444 fn visit_generic_param(&mut self, param: &'a GenericParam) {
445 if let GenericParam::Lifetime(ref ld) = *param {
446 self.check_lifetime(ld.lifetime.ident);
447 }
448 visit::walk_generic_param(self, param);
449 }
450
444 fn visit_pat(&mut self, pat: &'a Pat) { 451 fn visit_pat(&mut self, pat: &'a Pat) {
445 match pat.node { 452 match pat.node {
446 PatKind::Lit(ref expr) => { 453 PatKind::Lit(ref expr) => {
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index fdf8e52bbd..dca0e2f634 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -318,8 +318,8 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
318 walk_list!(visitor, visit_ty, tuple_element_types); 318 walk_list!(visitor, visit_ty, tuple_element_types);
319 } 319 }
320 TyKind::BareFn(ref function_declaration) => { 320 TyKind::BareFn(ref function_declaration) => {
321 walk_fn_decl(visitor, &function_declaration.decl);
322 walk_list!(visitor, visit_generic_param, &function_declaration.generic_params); 321 walk_list!(visitor, visit_generic_param, &function_declaration.generic_params);
322 walk_fn_decl(visitor, &function_declaration.decl);
323 } 323 }
324 TyKind::Path(ref maybe_qself, ref path) => { 324 TyKind::Path(ref maybe_qself, ref path) => {
325 if let Some(ref qself) = *maybe_qself { 325 if let Some(ref qself) = *maybe_qself {
@@ -485,7 +485,7 @@ pub fn walk_ty_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a TyPar
485pub fn walk_generic_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a GenericParam) { 485pub fn walk_generic_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a GenericParam) {
486 match *param { 486 match *param {
487 GenericParam::Lifetime(ref l) => { 487 GenericParam::Lifetime(ref l) => {
488 visitor.visit_lifetime(&l.lifetime); 488 visitor.visit_ident(l.lifetime.ident);
489 walk_list!(visitor, visit_lifetime, &l.bounds); 489 walk_list!(visitor, visit_lifetime, &l.bounds);
490 walk_list!(visitor, visit_attribute, &*l.attrs); 490 walk_list!(visitor, visit_attribute, &*l.attrs);
491 } 491 }
diff --git a/src/test/compile-fail/underscore-lifetime-binders.rs b/src/test/compile-fail/underscore-lifetime-binders.rs
index eb00ab5f67..6a6698957d 100644
--- a/src/test/compile-fail/underscore-lifetime-binders.rs
+++ b/src/test/compile-fail/underscore-lifetime-binders.rs
@@ -23,7 +23,6 @@ impl<'a> Meh<'a> for u8 {}
23 23
24fn meh() -> Box<for<'_> Meh<'_>> //~ ERROR invalid lifetime parameter name: `'_` 24fn meh() -> Box<for<'_> Meh<'_>> //~ ERROR invalid lifetime parameter name: `'_`
25//~^ ERROR missing lifetime specifier 25//~^ ERROR missing lifetime specifier
26//~^^ ERROR missing lifetime specifier
27{ 26{
28 Box::new(5u8) 27 Box::new(5u8)
29} 28}
diff --git a/src/test/run-pass/issue-51185.rs b/src/test/run-pass/issue-51185.rs
new file mode 100644
index 0000000000..8e286ad141
--- /dev/null
+++ b/src/test/run-pass/issue-51185.rs
@@ -0,0 +1,17 @@
1// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11fn foo() -> impl Into<for<'a> fn(&'a ())> {
12 (|_| {}) as for<'a> fn(&'a ())
13}
14
15fn main() {
16 foo().into()(&());
17}