Skip to content

Commit

Permalink
Issue #3511 - Rationalize temporary lifetimes.
Browse files Browse the repository at this point in the history
Major changes:

- Define temporary scopes in a syntax-based way that basically defaults
  to the innermost statement or conditional block, except for in
  a `let` initializer, where we default to the innermost block. Rules
  are documented in the code, but not in the manual (yet).
  See new test run-pass/cleanup-value-scopes.rs for examples.
- Refactors Datum to better define cleanup roles.
- Refactor cleanup scopes to not be tied to basic blocks, permitting
  us to have a very large number of scopes (one per AST node).
- Introduce nascent documentation in trans/doc.rs covering datums and
  cleanup in a more comprehensive way.
  • Loading branch information
nikomatsakis committed Jan 15, 2014
1 parent 149fc76 commit 419ac4a
Show file tree
Hide file tree
Showing 64 changed files with 4,797 additions and 3,662 deletions.
7 changes: 5 additions & 2 deletions src/librustc/lib/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1698,6 +1698,7 @@ pub mod llvm {

pub fn LLVMDICompositeTypeSetTypeArray(CompositeType: ValueRef, TypeArray: ValueRef);
pub fn LLVMTypeToString(Type: TypeRef) -> *c_char;
pub fn LLVMValueToString(value_ref: ValueRef) -> *c_char;

pub fn LLVMIsAArgument(value_ref: ValueRef) -> ValueRef;

Expand Down Expand Up @@ -1847,8 +1848,10 @@ impl TypeNames {

pub fn val_to_str(&self, val: ValueRef) -> ~str {
unsafe {
let ty = Type::from_ref(llvm::LLVMTypeOf(val));
self.type_to_str(ty)
let s = llvm::LLVMValueToString(val);
let ret = from_c_str(s);
free(s as *c_void);
ret
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@
use c = metadata::common;
use cstore = metadata::cstore;
use driver::session::Session;
use e = metadata::encoder;
use metadata::decoder;
use e = metadata::encoder;
use middle::freevars::freevar_entry;
use middle::region;
use metadata::tydecode;
use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter,
RegionParameter};
use metadata::tyencode;
use middle::freevars::freevar_entry;
use middle::typeck::{method_origin, method_map_entry};
use middle::{ty, typeck, moves};
use middle;
Expand Down Expand Up @@ -146,6 +147,7 @@ pub fn decode_inlined_item(cdata: @cstore::crate_metadata,
debug!("< Decoded inlined fn: {}::{}",
ast_map::path_to_str(path, token::get_ident_interner()),
tcx.sess.str_of(ident));
region::resolve_inlined_item(tcx.sess, &tcx.region_maps, &ii);
decode_side_tables(xcx, ast_doc);
match ii {
ast::IIItem(i) => {
Expand Down
19 changes: 4 additions & 15 deletions src/librustc/middle/borrowck/gather_loans/lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ impl<'a> GuaranteeLifetimeContext<'a> {

// If inside of a match arm, expand the rooting to the entire
// match. See the detailed discussion in `check()` above.
let mut root_scope = match discr_scope {
let root_scope = match discr_scope {
None => root_scope,
Some(id) => {
if self.bccx.is_subscope_of(root_scope, id) {
Expand All @@ -231,17 +231,6 @@ impl<'a> GuaranteeLifetimeContext<'a> {
}
};

// FIXME(#3511) grow to the nearest cleanup scope---this can
// cause observable errors if freezing!
if !self.bccx.tcx.region_maps.is_cleanup_scope(root_scope) {
debug!("{:?} is not a cleanup scope, adjusting", root_scope);

let cleanup_scope =
self.bccx.tcx.region_maps.cleanup_scope(root_scope);

root_scope = cleanup_scope;
}

// Add a record of what is required
let rm_key = root_map_key {id: cmt_deref.id, derefs: derefs};
let root_info = RootInfo {scope: root_scope};
Expand Down Expand Up @@ -301,8 +290,8 @@ impl<'a> GuaranteeLifetimeContext<'a> {
// See the SCOPE(LV) function in doc.rs

match cmt.cat {
mc::cat_rvalue(cleanup_scope_id) => {
ty::ReScope(cleanup_scope_id)
mc::cat_rvalue(temp_scope) => {
temp_scope
}
mc::cat_copied_upvar(_) => {
ty::ReScope(self.item_scope_id)
Expand All @@ -313,7 +302,7 @@ impl<'a> GuaranteeLifetimeContext<'a> {
mc::cat_local(local_id) |
mc::cat_arg(local_id) |
mc::cat_self(local_id) => {
self.bccx.tcx.region_maps.encl_region(local_id)
ty::ReScope(self.bccx.tcx.region_maps.var_scope(local_id))
}
mc::cat_deref(_, _, mc::unsafe_ptr(..)) => {
ty::ReStatic
Expand Down
7 changes: 4 additions & 3 deletions src/librustc/middle/borrowck/gather_loans/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -662,8 +662,9 @@ impl<'a> GatherLoanCtxt<'a> {
//! with immutable `&` pointers, because borrows of such pointers
//! do not require restrictions and hence do not cause a loan.

let lexical_scope = self.bccx.tcx.region_maps.encl_scope(lp.node_id());
if self.bccx.tcx.region_maps.is_subscope_of(lexical_scope, loan_scope) {
let rm = &self.bccx.tcx.region_maps;
let lexical_scope = rm.var_scope(lp.node_id());
if rm.is_subscope_of(lexical_scope, loan_scope) {
lexical_scope
} else {
assert!(self.bccx.tcx.region_maps.is_subscope_of(loan_scope, lexical_scope));
Expand All @@ -688,7 +689,7 @@ impl<'a> GatherLoanCtxt<'a> {
let arg_cmt = mc_ctxt.cat_rvalue(
arg.id,
arg.pat.span,
body.id, // Arguments live only as long as the fn body.
ty::ReScope(body.id), // Args live only as long as the fn body.
arg_ty);

self.gather_pat(arg_cmt, arg.pat, None);
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/borrowck/move_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ impl MoveData {
for path in paths.get().iter() {
match *path.loan_path {
LpVar(id) => {
let kill_id = tcx.region_maps.encl_scope(id);
let kill_id = tcx.region_maps.var_scope(id);
let path = {
let path_map = self.path_map.borrow();
*path_map.get().get(&path.loan_path)
Expand All @@ -490,7 +490,7 @@ impl MoveData {
var_assignments.get().iter().enumerate() {
match *self.path_loan_path(assignment.path) {
LpVar(id) => {
let kill_id = tcx.region_maps.encl_scope(id);
let kill_id = tcx.region_maps.var_scope(id);
dfcx_assign.add_kill(kill_id, assignment_index);
}
LpExtend(..) => {
Expand Down
19 changes: 12 additions & 7 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ use syntax::parse::token;

#[deriving(Eq)]
pub enum categorization {
cat_rvalue(ast::NodeId), // temporary val, argument is its scope
cat_rvalue(ty::Region), // temporary val, argument is its scope
cat_static_item,
cat_copied_upvar(CopiedUpvar), // upvar copied into @fn or ~fn env
cat_stack_upvar(cmt), // by ref upvar from ||
Expand Down Expand Up @@ -585,21 +585,26 @@ impl mem_categorization_ctxt {
pub fn cat_rvalue_node<N:ast_node>(&self,
node: &N,
expr_ty: ty::t) -> cmt {
self.cat_rvalue(node.id(),
node.span(),
self.tcx.region_maps.cleanup_scope(node.id()),
expr_ty)
match self.tcx.region_maps.temporary_scope(node.id()) {
Some(scope) => {
self.cat_rvalue(node.id(), node.span(),
ty::ReScope(scope), expr_ty)
}
None => {
self.cat_rvalue(node.id(), node.span(), ty::ReStatic, expr_ty)
}
}
}

pub fn cat_rvalue(&self,
cmt_id: ast::NodeId,
span: Span,
cleanup_scope_id: ast::NodeId,
temp_scope: ty::Region,
expr_ty: ty::t) -> cmt {
@cmt_ {
id:cmt_id,
span:span,
cat:cat_rvalue(cleanup_scope_id),
cat:cat_rvalue(temp_scope),
mutbl:McDeclared,
ty:expr_ty
}
Expand Down
11 changes: 11 additions & 0 deletions src/librustc/middle/pat_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,14 @@ pub fn pat_contains_bindings(dm: resolve::DefMap, pat: &Pat) -> bool {
});
contains_bindings
}

pub fn simple_identifier<'a>(pat: &'a Pat) -> Option<&'a Path> {
match pat.node {
PatIdent(BindByValue(_), ref path, None) => {
Some(path)
}
_ => {
None
}
}
}
Loading

0 comments on commit 419ac4a

Please sign in to comment.