]> git.lizzy.rs Git - rust.git/commitdiff
region -- Improve comments in region.rs
authorNiko Matsakis <niko@alum.mit.edu>
Fri, 7 Feb 2014 15:09:46 +0000 (10:09 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Tue, 11 Feb 2014 21:55:24 +0000 (16:55 -0500)
src/librustc/middle/region.rs

index 232b35bb82afce3412d2215a3e143e228a3521f8..fcda7cd79e4219e9da4b3ecef466fecbc0f3f040 100644 (file)
 /**
 The region maps encode information about region relationships.
 
-- `scope_map` maps from:
-  - an expression to the expression or block encoding the maximum
-    (static) lifetime of a value produced by that expression.  This is
-    generally the innermost call, statement, match, or block.
-  - a variable or binding id to the block in which that variable is declared.
-- `free_region_map` maps from:
-  - a free region `a` to a list of free regions `bs` such that
-    `a <= b for all b in bs`
+- `scope_map` maps from a scope id to the enclosing scope id; this is
+  usually corresponding to the lexical nesting, though in the case of
+  closures the parent scope is the innermost conditinal expression or repeating
+  block
+
+- `var_map` maps from a variable or binding id to the block in which
+  that variable is declared.
+
+- `free_region_map` maps from a free region `a` to a list of free
+  regions `bs` such that `a <= b for all b in bs`
   - the free region map is populated during type check as we check
     each function. See the function `relate_free_regions` for
     more information.
-- `temporary_scopes` includes scopes where cleanups for temporaries occur.
-  These are statements and loop/fn bodies.
+
+- `rvalue_scopes` includes entries for those expressions whose cleanup
+  scope is larger than the default. The map goes from the expression
+  id to the cleanup scope id. For rvalues not present in this table,
+  the appropriate cleanup scope is the innermost enclosing statement,
+  conditional expression, or repeating block (see `terminating_scopes`).
+
+- `terminating_scopes` is a set containing the ids of each statement,
+  or conditional/repeating expression. These scopes are calling "terminating
+  scopes" because, when attempting to find the scope of a temporary, by
+  default we search up the enclosing scopes until we encounter the
+  terminating scope. A conditional/repeating
+  expression is one which is not guaranteed to execute exactly once
+  upon entering the parent scope. This could be because the expression
+  only executes conditionally, such as the expression `b` in `a && b`,
+  or because the expression may execute many times, such as a loop
+  body. The reason that we distinguish such expressions is that, upon
+  exiting the parent scope, we cannot statically know how many times
+  the expression executed, and thus if the expression creates
+  temporaries we cannot know statically how many such temporaries we
+  would have to cleanup. Therefore we ensure that the temporaries never
+  outlast the conditional/repeating expression, preventing the need
+  for dynamic checks and/or arbitrary amounts of stack space.
 */
 pub struct RegionMaps {
     priv scope_map: RefCell<HashMap<ast::NodeId, ast::NodeId>>,
@@ -840,7 +863,16 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor,
         visit::FkItemFn(..) | visit::FkMethod(..) => {
             Context {parent: None, var_parent: None, ..cx}
         }
-        visit::FkFnBlock(..) => cx
+        visit::FkFnBlock(..) => {
+            // FIXME(#3696) -- at present we are place the closure body
+            // within the region hierarchy exactly where it appears lexically.
+            // This is wrong because the closure may live longer
+            // than the enclosing expression. We should probably fix this,
+            // but the correct fix is a bit subtle, and I am also not sure
+            // that the present approach is unsound -- it may not permit
+            // any illegal programs. See issue for more details.
+            cx
+        }
     };
     visitor.visit_block(body, body_cx);
 }