@@ -39,8 +39,7 @@ pub enum DefRegion {
39
39
DefEarlyBoundRegion ( /* space */ subst:: ParamSpace ,
40
40
/* index */ uint ,
41
41
/* lifetime decl */ ast:: NodeId ) ,
42
- DefLateBoundRegion ( /* binder_id */ ast:: NodeId ,
43
- /* depth */ uint ,
42
+ DefLateBoundRegion ( ty:: DebruijnIndex ,
44
43
/* lifetime decl */ ast:: NodeId ) ,
45
44
DefFreeRegion ( /* block scope */ ast:: NodeId ,
46
45
/* lifetime decl */ ast:: NodeId ) ,
@@ -60,9 +59,9 @@ enum ScopeChain<'a> {
60
59
/// EarlyScope(i, ['a, 'b, ...], s) extends s with early-bound
61
60
/// lifetimes, assigning indexes 'a => i, 'b => i+1, ... etc.
62
61
EarlyScope ( subst:: ParamSpace , & ' a Vec < ast:: LifetimeDef > , Scope < ' a > ) ,
63
- /// LateScope(binder_id, ['a, 'b, ...], s) extends s with late-bound
62
+ /// LateScope(['a, 'b, ...], s) extends s with late-bound
64
63
/// lifetimes introduced by the declaration binder_id.
65
- LateScope ( ast :: NodeId , & ' a Vec < ast:: LifetimeDef > , Scope < ' a > ) ,
64
+ LateScope ( & ' a Vec < ast:: LifetimeDef > , Scope < ' a > ) ,
66
65
/// lifetimes introduced by items within a code block are scoped
67
66
/// to that block.
68
67
BlockScope ( ast:: NodeId , Scope < ' a > ) ,
@@ -115,12 +114,12 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
115
114
}
116
115
117
116
fn visit_fn ( & mut self , fk : visit:: FnKind < ' v > , fd : & ' v ast:: FnDecl ,
118
- b : & ' v ast:: Block , s : Span , n : ast:: NodeId ) {
117
+ b : & ' v ast:: Block , s : Span , _ : ast:: NodeId ) {
119
118
match fk {
120
119
visit:: FkItemFn ( _, generics, _, _) |
121
120
visit:: FkMethod ( _, generics, _) => {
122
121
self . visit_early_late (
123
- subst:: FnSpace , n , generics,
122
+ subst:: FnSpace , generics,
124
123
|this| visit:: walk_fn ( this, fk, fd, b, s) )
125
124
}
126
125
visit:: FkFnBlock ( ..) => {
@@ -130,21 +129,37 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
130
129
}
131
130
132
131
fn visit_ty ( & mut self , ty : & ast:: Ty ) {
133
- let lifetimes = match ty. node {
134
- ast:: TyClosure ( ref c) | ast:: TyProc ( ref c) => & c. lifetimes ,
135
- ast:: TyBareFn ( ref c) => & c. lifetimes ,
136
- _ => return visit:: walk_ty ( self , ty)
137
- } ;
138
-
139
- self . with ( LateScope ( ty. id , lifetimes, self . scope ) , |this| {
140
- this. check_lifetime_defs ( lifetimes) ;
141
- visit:: walk_ty ( this, ty) ;
142
- } ) ;
132
+ match ty. node {
133
+ ast:: TyClosure ( ref c) | ast:: TyProc ( ref c) => {
134
+ // Careful, the bounds on a closure/proc are *not* within its binder.
135
+ visit:: walk_ty_param_bounds_helper ( self , & c. bounds ) ;
136
+ visit:: walk_lifetime_decls_helper ( self , & c. lifetimes ) ;
137
+ self . with ( LateScope ( & c. lifetimes , self . scope ) , |this| {
138
+ this. check_lifetime_defs ( & c. lifetimes ) ;
139
+ for argument in c. decl . inputs . iter ( ) {
140
+ this. visit_ty ( & * argument. ty )
141
+ }
142
+ visit:: walk_fn_ret_ty ( this, & c. decl . output ) ;
143
+ } ) ;
144
+ }
145
+ ast:: TyBareFn ( ref c) => {
146
+ visit:: walk_lifetime_decls_helper ( self , & c. lifetimes ) ;
147
+ self . with ( LateScope ( & c. lifetimes , self . scope ) , |this| {
148
+ // a bare fn has no bounds, so everything
149
+ // contained within is scoped within its binder.
150
+ this. check_lifetime_defs ( & c. lifetimes ) ;
151
+ visit:: walk_ty ( this, ty) ;
152
+ } ) ;
153
+ }
154
+ _ => {
155
+ visit:: walk_ty ( self , ty)
156
+ }
157
+ }
143
158
}
144
159
145
160
fn visit_ty_method ( & mut self , m : & ast:: TypeMethod ) {
146
161
self . visit_early_late (
147
- subst:: FnSpace , m . id , & m. generics ,
162
+ subst:: FnSpace , & m. generics ,
148
163
|this| visit:: walk_ty_method ( this, m) )
149
164
}
150
165
@@ -216,11 +231,25 @@ impl<'a> LifetimeContext<'a> {
216
231
fn visit_trait_ref ( & mut self , trait_ref : & ast:: TraitRef ) {
217
232
self . visit_path ( & trait_ref. path , trait_ref. ref_id ) ;
218
233
}
234
+ }
235
+
236
+ impl < ' a > LifetimeContext < ' a > {
237
+ fn with ( & mut self , wrap_scope : ScopeChain , f: |& mut LifetimeContext |) {
238
+ let LifetimeContext { sess, ref mut named_region_map, ..} = * self ;
239
+ let mut this = LifetimeContext {
240
+ sess : sess,
241
+ named_region_map : * named_region_map,
242
+ scope : & wrap_scope,
243
+ def_map : self . def_map ,
244
+ } ;
245
+ debug ! ( "entering scope {}" , this. scope) ;
246
+ f ( & mut this) ;
247
+ debug ! ( "exiting scope {}" , this. scope) ;
248
+ }
219
249
220
250
/// Visits self by adding a scope and handling recursive walk over the contents with `walk`.
221
251
fn visit_early_late ( & mut self ,
222
252
early_space : subst:: ParamSpace ,
223
- binder_id : ast:: NodeId ,
224
253
generics : & ast:: Generics ,
225
254
walk: |& mut LifetimeContext |) {
226
255
/*!
@@ -249,15 +278,14 @@ impl<'a> LifetimeContext<'a> {
249
278
250
279
let referenced_idents = early_bound_lifetime_names ( generics) ;
251
280
252
- debug ! ( "visit_early_late: binder_id={} referenced_idents={}" ,
253
- binder_id,
281
+ debug ! ( "visit_early_late: referenced_idents={}" ,
254
282
referenced_idents) ;
255
283
256
284
let ( early, late) = generics. lifetimes . clone ( ) . partition (
257
285
|l| referenced_idents. iter ( ) . any ( |& i| i == l. lifetime . name ) ) ;
258
286
259
287
self . with ( EarlyScope ( early_space, & early, self . scope ) , |this| {
260
- this. with ( LateScope ( binder_id , & late, this. scope ) , |this| {
288
+ this. with ( LateScope ( & late, this. scope ) , |this| {
261
289
this. check_lifetime_defs ( & generics. lifetimes ) ;
262
290
walk ( this) ;
263
291
} ) ;
@@ -271,7 +299,7 @@ impl<'a> LifetimeContext<'a> {
271
299
// block, then the lifetime is not bound but free, so switch
272
300
// over to `resolve_free_lifetime_ref()` to complete the
273
301
// search.
274
- let mut depth = 0 ;
302
+ let mut late_depth = 0 ;
275
303
let mut scope = self . scope ;
276
304
loop {
277
305
match * scope {
@@ -291,22 +319,22 @@ impl<'a> LifetimeContext<'a> {
291
319
return ;
292
320
}
293
321
None => {
294
- depth += 1 ;
295
322
scope = s;
296
323
}
297
324
}
298
325
}
299
326
300
- LateScope ( binder_id , lifetimes, s) => {
327
+ LateScope ( lifetimes, s) => {
301
328
match search_lifetimes ( lifetimes, lifetime_ref) {
302
329
Some ( ( _index, decl_id) ) => {
303
- let def = DefLateBoundRegion ( binder_id, depth, decl_id) ;
330
+ let debruijn = ty:: DebruijnIndex :: new ( late_depth + 1 ) ;
331
+ let def = DefLateBoundRegion ( debruijn, decl_id) ;
304
332
self . insert_lifetime ( lifetime_ref, def) ;
305
333
return ;
306
334
}
307
335
308
336
None => {
309
- depth += 1 ;
337
+ late_depth += 1 ;
310
338
scope = s;
311
339
}
312
340
}
@@ -339,7 +367,7 @@ impl<'a> LifetimeContext<'a> {
339
367
}
340
368
341
369
EarlyScope ( _, lifetimes, s) |
342
- LateScope ( _ , lifetimes, s) => {
370
+ LateScope ( lifetimes, s) => {
343
371
search_result = search_lifetimes ( lifetimes, lifetime_ref) ;
344
372
if search_result. is_some ( ) {
345
373
break ;
@@ -517,7 +545,7 @@ impl<'a> fmt::Show for ScopeChain<'a> {
517
545
fn fmt ( & self , fmt : & mut fmt:: Formatter ) -> fmt:: Result {
518
546
match * self {
519
547
EarlyScope ( space, defs, _) => write ! ( fmt, "EarlyScope({}, {})" , space, defs) ,
520
- LateScope ( id , defs, _) => write ! ( fmt, "LateScope({}, {})" , id , defs) ,
548
+ LateScope ( defs, _) => write ! ( fmt, "LateScope({})" , defs) ,
521
549
BlockScope ( id, _) => write ! ( fmt, "BlockScope({})" , id) ,
522
550
RootScope => write ! ( fmt, "RootScope" ) ,
523
551
}
0 commit comments