Struct rustc_trans::middle::region::RegionMapsExperimental
[-]
[+]
[src]
pub struct RegionMaps { // some fields omitted }
The region maps encode information about region relationships.
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 conditional expression or repeating blockvar_map
maps from a variable or binding id to the block in which that variable is declared.free_region_map
maps from a free regiona
to a list of free regionsbs
such thata <= 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.
- the free region map is populated during type check as we check
each function. See the function
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 (seeterminating_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 expressionb
ina && 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.
Methods
impl RegionMaps
fn relate_free_regions(&self, sub: FreeRegion, sup: FreeRegion)
fn record_encl_scope(&self, sub: CodeExtent, sup: CodeExtent)
fn record_var_scope(&self, var: u32, lifetime: CodeExtent)
fn record_rvalue_scope(&self, var: u32, lifetime: CodeExtent)
fn mark_as_terminating_scope(&self, scope_id: CodeExtent)
Records that a scope is a TERMINATING SCOPE. Whenever we create automatic temporaries --
e.g. by an expression like a().f
-- they will be freed within the innermost terminating
scope.
fn opt_encl_scope(&self, id: CodeExtent) -> Option<CodeExtent>
Returns the narrowest scope that encloses id
, if any.
fn encl_scope(&self, id: CodeExtent) -> CodeExtent
Returns the narrowest scope that encloses id
, if any.
fn var_scope(&self, var_id: u32) -> CodeExtent
Returns the lifetime of the local variable var_id
fn temporary_scope(&self, expr_id: u32) -> Option<CodeExtent>
Returns the scope when temp created by expr_id will be cleaned up
fn var_region(&self, id: u32) -> Region
Returns the lifetime of the variable id
.
fn scopes_intersect(&self, scope1: CodeExtent, scope2: CodeExtent) -> bool
fn is_subscope_of(&self, subscope: CodeExtent, superscope: CodeExtent) -> bool
Returns true if subscope
is equal to or is lexically nested inside superscope
and false
otherwise.
fn sub_free_region(&self, sub: FreeRegion, sup: FreeRegion) -> bool
Determines whether two free regions have a subregion relationship
by walking the graph encoded in free_region_map
. Note that
it is possible that sub != sup
and sub <= sup
and sup <= sub
(that is, the user can give two different names to the same lifetime).
fn is_subregion_of(&self, sub_region: Region, super_region: Region) -> bool
Determines whether one region is a subregion of another. This is intended to run after inference and sadly the logic is somewhat duplicated with the code in infer.rs.
fn nearest_common_ancestor(&self, scope_a: CodeExtent, scope_b: CodeExtent) -> Option<CodeExtent>
Finds the nearest common ancestor (if any) of two scopes. That is, finds the smallest
scope which is greater than or equal to both scope_a
and scope_b
.