auto merge of #11776 : FlaPer87/rust/issue-11681-static-lifetime, r=nikomatsakis

Closes #11681
Closes #11854
This commit is contained in:
bors 2014-01-29 15:01:43 -08:00
commit f84b7291e7
4 changed files with 69 additions and 21 deletions

View File

@ -356,7 +356,7 @@ impl mem_categorization_ctxt {
// Convert a bare fn to a closure by adding NULL env.
// Result is an rvalue.
let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
self.cat_rvalue_node(expr, expr_ty)
self.cat_rvalue_node(expr.id(), expr.span(), expr_ty)
}
ty::AutoDerefRef(ty::AutoDerefRef {
@ -365,7 +365,7 @@ impl mem_categorization_ctxt {
// Equivalent to &*expr or something similar.
// Result is an rvalue.
let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
self.cat_rvalue_node(expr, expr_ty)
self.cat_rvalue_node(expr.id(), expr.span(), expr_ty)
}
ty::AutoDerefRef(ty::AutoDerefRef {
@ -398,7 +398,7 @@ impl mem_categorization_ctxt {
ast::ExprUnary(_, ast::UnDeref, e_base) => {
let method_map = self.method_map.borrow();
if method_map.get().contains_key(&expr.id) {
return self.cat_rvalue_node(expr, expr_ty);
return self.cat_rvalue_node(expr.id(), expr.span(), expr_ty);
}
let base_cmt = self.cat_expr(e_base);
@ -418,7 +418,7 @@ impl mem_categorization_ctxt {
ast::ExprIndex(_, base, _) => {
let method_map = self.method_map.borrow();
if method_map.get().contains_key(&expr.id) {
return self.cat_rvalue_node(expr, expr_ty);
return self.cat_rvalue_node(expr.id(), expr.span(), expr_ty);
}
let base_cmt = self.cat_expr(base);
@ -444,7 +444,7 @@ impl mem_categorization_ctxt {
ast::ExprLit(..) | ast::ExprBreak(..) | ast::ExprMac(..) |
ast::ExprAgain(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) |
ast::ExprInlineAsm(..) | ast::ExprBox(..) => {
return self.cat_rvalue_node(expr, expr_ty);
return self.cat_rvalue_node(expr.id(), expr.span(), expr_ty);
}
ast::ExprForLoop(..) => fail!("non-desugared expr_for_loop")
@ -457,13 +457,18 @@ impl mem_categorization_ctxt {
expr_ty: ty::t,
def: ast::Def)
-> cmt {
debug!("cat_def: id={} expr={}",
id, ty_to_str(self.tcx, expr_ty));
match def {
ast::DefStruct(..) | ast::DefVariant(..) => {
self.cat_rvalue_node(id, span, expr_ty)
}
ast::DefFn(..) | ast::DefStaticMethod(..) | ast::DefMod(_) |
ast::DefForeignMod(_) | ast::DefStatic(_, false) |
ast::DefUse(_) | ast::DefVariant(..) |
ast::DefTrait(_) | ast::DefTy(_) | ast::DefPrimTy(_) |
ast::DefTyParam(..) | ast::DefStruct(..) |
ast::DefTyParamBinder(..) | ast::DefRegion(_) |
ast::DefUse(_) | ast::DefTrait(_) | ast::DefTy(_) | ast::DefPrimTy(_) |
ast::DefTyParam(..) | ast::DefTyParamBinder(..) | ast::DefRegion(_) |
ast::DefLabel(_) | ast::DefSelfTy(..) | ast::DefMethod(..) => {
@cmt_ {
id:id,
@ -571,16 +576,13 @@ impl mem_categorization_ctxt {
}
}
pub fn cat_rvalue_node<N:ast_node>(&self,
node: &N,
expr_ty: ty::t) -> cmt {
match self.tcx.region_maps.temporary_scope(node.id()) {
pub fn cat_rvalue_node(&self, id: ast::NodeId, span: Span, expr_ty: ty::t) -> cmt {
match self.tcx.region_maps.temporary_scope(id) {
Some(scope) => {
self.cat_rvalue(node.id(), node.span(),
ty::ReScope(scope), expr_ty)
self.cat_rvalue(id, span, ty::ReScope(scope), expr_ty)
}
None => {
self.cat_rvalue(node.id(), node.span(), ty::ReStatic, expr_ty)
self.cat_rvalue(id, span, ty::ReStatic, expr_ty)
}
}
}
@ -986,7 +988,7 @@ impl mem_categorization_ctxt {
}
for &slice_pat in slice.iter() {
let slice_ty = self.pat_ty(slice_pat);
let slice_cmt = self.cat_rvalue_node(pat, slice_ty);
let slice_cmt = self.cat_rvalue_node(pat.id(), pat.span(), slice_ty);
self.cat_pattern(slice_cmt, slice_pat, |x,y| op(x,y));
}
for &after_pat in after.iter() {

View File

@ -172,7 +172,14 @@ impl RegionMaps {
}
// else, locate the innermost terminating scope
let mut id = self.encl_scope(expr_id);
// if there's one. Static items, for instance, won't
// have an enclusing scope, hence no scope will be
// returned.
let mut id = match self.opt_encl_scope(expr_id) {
Some(i) => i,
None => { return None; }
};
let terminating_scopes = self.terminating_scopes.borrow();
while !terminating_scopes.get().contains(&id) {
match self.opt_encl_scope(id) {

View File

@ -0,0 +1,32 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// This tests verifies that unary structs and enum variants
// are treated as rvalues and their lifetime is not bounded to
// the static scope.
struct Test;
enum MyEnum {
Variant1
}
fn structLifetime() -> &Test {
let testValue = &Test; //~ ERROR borrowed value does not live long enough
testValue
}
fn variantLifetime() -> &MyEnum {
let testValue = &Variant1; //~ ERROR borrowed value does not live long enough
testValue
}
fn main() {}

View File

@ -1,4 +1,4 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -8,6 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// This test verifies that temporary lifetime is correctly computed
// for static objects in enclosing scopes.
extern mod extra;
use std::cmp::Eq;
@ -15,7 +18,11 @@ fn f<T:Eq>(o: &mut Option<T>) {
assert!(*o == None);
}
fn main() {
pub fn main() {
mod t {
enum E {V=1, A=0}
static C: E = V;
}
f::<int>(&mut None);
//~^ ERROR cannot borrow
}