@@ -95,7 +95,15 @@ use syntax::visit::{Visitor, FnKind};
9595 RustcDecodable , Debug , Copy ) ]
9696pub enum CodeExtent {
9797 Misc ( ast:: NodeId ) ,
98- DestructionScope ( ast:: NodeId ) , // extent of destructors for temporaries of node-id
98+
99+ // extent of parameters passed to a function or closure (they
100+ // outlive its body)
101+ ParameterScope { fn_id : ast:: NodeId , body_id : ast:: NodeId } ,
102+
103+ // extent of destructors for temporaries of node-id
104+ DestructionScope ( ast:: NodeId ) ,
105+
106+ // extent of code following a `let id = expr;` binding in a block
99107 Remainder ( BlockRemainder )
100108}
101109
@@ -153,15 +161,19 @@ impl CodeExtent {
153161 pub fn node_id ( & self ) -> ast:: NodeId {
154162 match * self {
155163 CodeExtent :: Misc ( node_id) => node_id,
164+
165+ // These cases all return rough approximations to the
166+ // precise extent denoted by `self`.
156167 CodeExtent :: Remainder ( br) => br. block ,
157168 CodeExtent :: DestructionScope ( node_id) => node_id,
169+ CodeExtent :: ParameterScope { fn_id : _, body_id } => body_id,
158170 }
159171 }
160172
161173 /// Maps this scope to a potentially new one according to the
162174 /// NodeId transformer `f_id`.
163175 pub fn map_id < F > ( & self , f_id : F ) -> CodeExtent where
164- F : FnOnce ( ast:: NodeId ) -> ast:: NodeId ,
176+ F : Fn ( ast:: NodeId ) -> ast:: NodeId ,
165177 {
166178 match * self {
167179 CodeExtent :: Misc ( node_id) => CodeExtent :: Misc ( f_id ( node_id) ) ,
@@ -170,6 +182,8 @@ impl CodeExtent {
170182 block : f_id ( br. block ) , first_statement_index : br. first_statement_index } ) ,
171183 CodeExtent :: DestructionScope ( node_id) =>
172184 CodeExtent :: DestructionScope ( f_id ( node_id) ) ,
185+ CodeExtent :: ParameterScope { fn_id, body_id } =>
186+ CodeExtent :: ParameterScope { fn_id : f_id ( fn_id) , body_id : f_id ( body_id) } ,
173187 }
174188 }
175189
@@ -180,6 +194,7 @@ impl CodeExtent {
180194 match ast_map. find ( self . node_id ( ) ) {
181195 Some ( ast_map:: NodeBlock ( ref blk) ) => {
182196 match * self {
197+ CodeExtent :: ParameterScope { .. } |
183198 CodeExtent :: Misc ( _) |
184199 CodeExtent :: DestructionScope ( _) => Some ( blk. span ) ,
185200
@@ -277,6 +292,7 @@ enum InnermostDeclaringBlock {
277292 Block ( ast:: NodeId ) ,
278293 Statement ( DeclaringStatementContext ) ,
279294 Match ( ast:: NodeId ) ,
295+ FnDecl { fn_id : ast:: NodeId , body_id : ast:: NodeId } ,
280296}
281297
282298impl InnermostDeclaringBlock {
@@ -285,6 +301,8 @@ impl InnermostDeclaringBlock {
285301 InnermostDeclaringBlock :: None => {
286302 return Option :: None ;
287303 }
304+ InnermostDeclaringBlock :: FnDecl { fn_id, body_id } =>
305+ CodeExtent :: ParameterScope { fn_id : fn_id, body_id : body_id } ,
288306 InnermostDeclaringBlock :: Block ( id) |
289307 InnermostDeclaringBlock :: Match ( id) => CodeExtent :: from_node_id ( id) ,
290308 InnermostDeclaringBlock :: Statement ( s) => s. to_code_extent ( ) ,
@@ -1198,25 +1216,34 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor,
11981216 body. id,
11991217 visitor. cx. parent) ;
12001218
1219+ // This scope covers the function body, which includes the
1220+ // bindings introduced by let statements as well as temporaries
1221+ // created by the fn's tail expression (if any). It does *not*
1222+ // include the fn parameters (see below).
12011223 let body_scope = CodeExtent :: from_node_id ( body. id ) ;
12021224 visitor. region_maps . mark_as_terminating_scope ( body_scope) ;
12031225
12041226 let dtor_scope = CodeExtent :: DestructionScope ( body. id ) ;
12051227 visitor. region_maps . record_encl_scope ( body_scope, dtor_scope) ;
12061228
1207- record_superlifetime ( visitor, dtor_scope, body. span ) ;
1229+ let fn_decl_scope = CodeExtent :: ParameterScope { fn_id : id, body_id : body. id } ;
1230+ visitor. region_maps . record_encl_scope ( dtor_scope, fn_decl_scope) ;
1231+
1232+ record_superlifetime ( visitor, fn_decl_scope, body. span ) ;
12081233
12091234 if let Some ( root_id) = visitor. cx . root_id {
12101235 visitor. region_maps . record_fn_parent ( body. id , root_id) ;
12111236 }
12121237
12131238 let outer_cx = visitor. cx ;
12141239
1215- // The arguments and `self` are parented to the body of the fn.
1240+ // The arguments and `self` are parented to the fn.
12161241 visitor. cx = Context {
12171242 root_id : Some ( body. id ) ,
1218- parent : InnermostEnclosingExpr :: Some ( body. id ) ,
1219- var_parent : InnermostDeclaringBlock :: Block ( body. id )
1243+ parent : InnermostEnclosingExpr :: None ,
1244+ var_parent : InnermostDeclaringBlock :: FnDecl {
1245+ fn_id : id, body_id : body. id
1246+ } ,
12201247 } ;
12211248 visit:: walk_fn_decl ( visitor, decl) ;
12221249
0 commit comments