@@ -37,6 +37,7 @@ use util::nodemap::NodeMap;
37
37
#[ derive( Clone , Copy , PartialEq , Eq , Hash , RustcEncodable , RustcDecodable , Debug ) ]
38
38
pub enum DefRegion {
39
39
DefStaticRegion ,
40
+ DefAnonRegion ,
40
41
DefEarlyBoundRegion ( /* space */ subst:: ParamSpace ,
41
42
/* index */ u32 ,
42
43
/* lifetime decl */ ast:: NodeId ) ,
@@ -72,6 +73,9 @@ struct LifetimeContext<'a> {
72
73
// I'm sorry.
73
74
trait_ref_hack : bool ,
74
75
76
+ // Pre-interned "'_", if #[feature(anon_lifetime)] is enabled.
77
+ anon_lifetime_name : Option < ast:: Name > ,
78
+
75
79
// List of labels in the function/method currently under analysis.
76
80
labels_in_fn : Vec < ( ast:: Ident , Span ) > ,
77
81
}
@@ -95,12 +99,18 @@ static ROOT_SCOPE: ScopeChain<'static> = RootScope;
95
99
96
100
pub fn krate ( sess : & Session , krate : & ast:: Crate , def_map : & DefMap ) -> NamedRegionMap {
97
101
let mut named_region_map = NodeMap ( ) ;
102
+ let anon_lifetime_name = if sess. features . borrow ( ) . anon_lifetime {
103
+ Some ( token:: intern ( "'_" ) )
104
+ } else {
105
+ None
106
+ } ;
98
107
visit:: walk_crate ( & mut LifetimeContext {
99
108
sess : sess,
100
109
named_region_map : & mut named_region_map,
101
110
scope : & ROOT_SCOPE ,
102
111
def_map : def_map,
103
112
trait_ref_hack : false ,
113
+ anon_lifetime_name : anon_lifetime_name,
104
114
labels_in_fn : vec ! [ ] ,
105
115
} , krate) ;
106
116
sess. abort_if_errors ( ) ;
@@ -224,11 +234,28 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
224
234
}
225
235
226
236
fn visit_lifetime_ref ( & mut self , lifetime_ref : & ast:: Lifetime ) {
227
- if lifetime_ref. name == special_idents:: static_lifetime. name {
228
- self . insert_lifetime ( lifetime_ref, DefStaticRegion ) ;
229
- return ;
237
+ if lifetime_ref. id == ast:: DUMMY_NODE_ID {
238
+ self . sess . span_bug ( lifetime_ref. span ,
239
+ "lifetime reference not renumbered, \
240
+ probably a bug in syntax::fold") ;
230
241
}
231
- self . resolve_lifetime_ref ( lifetime_ref) ;
242
+
243
+ let def = if lifetime_ref. name == special_idents:: static_lifetime. name {
244
+ DefStaticRegion
245
+ } else if let Ok ( def) = self . resolve_lifetime_ref ( lifetime_ref) {
246
+ def
247
+ } else if Some ( lifetime_ref. name ) == self . anon_lifetime_name {
248
+ DefAnonRegion
249
+ } else {
250
+ self . unresolved_lifetime_ref ( lifetime_ref) ;
251
+ return ;
252
+ } ;
253
+
254
+ debug ! ( "lifetime_ref={:?} id={:?} resolved to {:?}" ,
255
+ lifetime_to_string( lifetime_ref) ,
256
+ lifetime_ref. id,
257
+ def) ;
258
+ self . named_region_map . insert ( lifetime_ref. id , def) ;
232
259
}
233
260
234
261
fn visit_generics ( & mut self , generics : & ast:: Generics ) {
@@ -478,6 +505,7 @@ impl<'a> LifetimeContext<'a> {
478
505
scope : & wrap_scope,
479
506
def_map : self . def_map ,
480
507
trait_ref_hack : self . trait_ref_hack ,
508
+ anon_lifetime_name : self . anon_lifetime_name ,
481
509
labels_in_fn : self . labels_in_fn . clone ( ) ,
482
510
} ;
483
511
debug ! ( "entering scope {:?}" , this. scope) ;
@@ -525,7 +553,8 @@ impl<'a> LifetimeContext<'a> {
525
553
} ) ;
526
554
}
527
555
528
- fn resolve_lifetime_ref ( & mut self , lifetime_ref : & ast:: Lifetime ) {
556
+ fn resolve_lifetime_ref ( & mut self , lifetime_ref : & ast:: Lifetime )
557
+ -> Result < DefRegion , ( ) > {
529
558
// Walk up the scope chain, tracking the number of fn scopes
530
559
// that we pass through, until we find a lifetime with the
531
560
// given name or we run out of scopes. If we encounter a code
@@ -548,9 +577,7 @@ impl<'a> LifetimeContext<'a> {
548
577
match search_lifetimes ( lifetimes, lifetime_ref) {
549
578
Some ( ( index, lifetime_def) ) => {
550
579
let decl_id = lifetime_def. id ;
551
- let def = DefEarlyBoundRegion ( space, index, decl_id) ;
552
- self . insert_lifetime ( lifetime_ref, def) ;
553
- return ;
580
+ return Ok ( DefEarlyBoundRegion ( space, index, decl_id) ) ;
554
581
}
555
582
None => {
556
583
scope = s;
@@ -563,9 +590,7 @@ impl<'a> LifetimeContext<'a> {
563
590
Some ( ( _index, lifetime_def) ) => {
564
591
let decl_id = lifetime_def. id ;
565
592
let debruijn = ty:: DebruijnIndex :: new ( late_depth + 1 ) ;
566
- let def = DefLateBoundRegion ( debruijn, decl_id) ;
567
- self . insert_lifetime ( lifetime_ref, def) ;
568
- return ;
593
+ return Ok ( DefLateBoundRegion ( debruijn, decl_id) ) ;
569
594
}
570
595
571
596
None => {
@@ -577,13 +602,13 @@ impl<'a> LifetimeContext<'a> {
577
602
}
578
603
}
579
604
580
- self . unresolved_lifetime_ref ( lifetime_ref ) ;
605
+ Err ( ( ) )
581
606
}
582
607
583
608
fn resolve_free_lifetime_ref ( & mut self ,
584
609
scope_data : region:: DestructionScopeData ,
585
610
lifetime_ref : & ast:: Lifetime ,
586
- scope : Scope ) {
611
+ scope : Scope ) -> Result < DefRegion , ( ) > {
587
612
debug ! ( "resolve_free_lifetime_ref \
588
613
scope_data: {:?} lifetime_ref: {:?} scope: {:?}",
589
614
scope_data, lifetime_ref, scope) ;
@@ -621,13 +646,10 @@ impl<'a> LifetimeContext<'a> {
621
646
622
647
match search_result {
623
648
Some ( ( _depth, lifetime) ) => {
624
- let def = DefFreeRegion ( scope_data, lifetime. id ) ;
625
- self . insert_lifetime ( lifetime_ref, def) ;
649
+ Ok ( DefFreeRegion ( scope_data, lifetime. id ) )
626
650
}
627
651
628
- None => {
629
- self . unresolved_lifetime_ref ( lifetime_ref) ;
630
- }
652
+ None => Err ( ( ) )
631
653
}
632
654
633
655
}
@@ -667,7 +689,7 @@ impl<'a> LifetimeContext<'a> {
667
689
self . check_lifetime_def_for_shadowing ( old_scope, & lifetime_i. lifetime ) ;
668
690
669
691
for bound in & lifetime_i. bounds {
670
- self . resolve_lifetime_ref ( bound) ;
692
+ self . visit_lifetime_ref ( bound) ;
671
693
}
672
694
}
673
695
}
@@ -713,22 +735,6 @@ impl<'a> LifetimeContext<'a> {
713
735
}
714
736
}
715
737
}
716
-
717
- fn insert_lifetime ( & mut self ,
718
- lifetime_ref : & ast:: Lifetime ,
719
- def : DefRegion ) {
720
- if lifetime_ref. id == ast:: DUMMY_NODE_ID {
721
- self . sess . span_bug ( lifetime_ref. span ,
722
- "lifetime reference not renumbered, \
723
- probably a bug in syntax::fold") ;
724
- }
725
-
726
- debug ! ( "lifetime_ref={:?} id={:?} resolved to {:?}" ,
727
- lifetime_to_string( lifetime_ref) ,
728
- lifetime_ref. id,
729
- def) ;
730
- self . named_region_map . insert ( lifetime_ref. id , def) ;
731
- }
732
738
}
733
739
734
740
fn search_lifetimes < ' a > ( lifetimes : & ' a Vec < ast:: LifetimeDef > ,
0 commit comments