Skip to content

Commit

Permalink
auto merge of #11776 : FlaPer87/rust/issue-11681-static-lifetime, r=n…
Browse files Browse the repository at this point in the history
…ikomatsakis

Closes #11681
Closes #11854
  • Loading branch information
bors committed Jan 29, 2014
2 parents 1e23c5c + cb5d723 commit f84b729
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 21 deletions.
36 changes: 19 additions & 17 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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")
Expand All @@ -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,
Expand Down Expand Up @@ -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)
}
}
}
Expand Down Expand Up @@ -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() {
Expand Down
9 changes: 8 additions & 1 deletion src/librustc/middle/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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.
//
Expand All @@ -8,14 +8,21 @@
// 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;

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
}

0 comments on commit f84b729

Please sign in to comment.