Skip to content

Commit f84b729

Browse files
committed
auto merge of #11776 : FlaPer87/rust/issue-11681-static-lifetime, r=nikomatsakis
Closes #11681 Closes #11854
2 parents 1e23c5c + cb5d723 commit f84b729

File tree

4 files changed

+69
-21
lines changed

4 files changed

+69
-21
lines changed

src/librustc/middle/mem_categorization.rs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ impl mem_categorization_ctxt {
356356
// Convert a bare fn to a closure by adding NULL env.
357357
// Result is an rvalue.
358358
let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
359-
self.cat_rvalue_node(expr, expr_ty)
359+
self.cat_rvalue_node(expr.id(), expr.span(), expr_ty)
360360
}
361361

362362
ty::AutoDerefRef(ty::AutoDerefRef {
@@ -365,7 +365,7 @@ impl mem_categorization_ctxt {
365365
// Equivalent to &*expr or something similar.
366366
// Result is an rvalue.
367367
let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
368-
self.cat_rvalue_node(expr, expr_ty)
368+
self.cat_rvalue_node(expr.id(), expr.span(), expr_ty)
369369
}
370370

371371
ty::AutoDerefRef(ty::AutoDerefRef {
@@ -398,7 +398,7 @@ impl mem_categorization_ctxt {
398398
ast::ExprUnary(_, ast::UnDeref, e_base) => {
399399
let method_map = self.method_map.borrow();
400400
if method_map.get().contains_key(&expr.id) {
401-
return self.cat_rvalue_node(expr, expr_ty);
401+
return self.cat_rvalue_node(expr.id(), expr.span(), expr_ty);
402402
}
403403

404404
let base_cmt = self.cat_expr(e_base);
@@ -418,7 +418,7 @@ impl mem_categorization_ctxt {
418418
ast::ExprIndex(_, base, _) => {
419419
let method_map = self.method_map.borrow();
420420
if method_map.get().contains_key(&expr.id) {
421-
return self.cat_rvalue_node(expr, expr_ty);
421+
return self.cat_rvalue_node(expr.id(), expr.span(), expr_ty);
422422
}
423423

424424
let base_cmt = self.cat_expr(base);
@@ -444,7 +444,7 @@ impl mem_categorization_ctxt {
444444
ast::ExprLit(..) | ast::ExprBreak(..) | ast::ExprMac(..) |
445445
ast::ExprAgain(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) |
446446
ast::ExprInlineAsm(..) | ast::ExprBox(..) => {
447-
return self.cat_rvalue_node(expr, expr_ty);
447+
return self.cat_rvalue_node(expr.id(), expr.span(), expr_ty);
448448
}
449449

450450
ast::ExprForLoop(..) => fail!("non-desugared expr_for_loop")
@@ -457,13 +457,18 @@ impl mem_categorization_ctxt {
457457
expr_ty: ty::t,
458458
def: ast::Def)
459459
-> cmt {
460+
debug!("cat_def: id={} expr={}",
461+
id, ty_to_str(self.tcx, expr_ty));
462+
463+
460464
match def {
465+
ast::DefStruct(..) | ast::DefVariant(..) => {
466+
self.cat_rvalue_node(id, span, expr_ty)
467+
}
461468
ast::DefFn(..) | ast::DefStaticMethod(..) | ast::DefMod(_) |
462469
ast::DefForeignMod(_) | ast::DefStatic(_, false) |
463-
ast::DefUse(_) | ast::DefVariant(..) |
464-
ast::DefTrait(_) | ast::DefTy(_) | ast::DefPrimTy(_) |
465-
ast::DefTyParam(..) | ast::DefStruct(..) |
466-
ast::DefTyParamBinder(..) | ast::DefRegion(_) |
470+
ast::DefUse(_) | ast::DefTrait(_) | ast::DefTy(_) | ast::DefPrimTy(_) |
471+
ast::DefTyParam(..) | ast::DefTyParamBinder(..) | ast::DefRegion(_) |
467472
ast::DefLabel(_) | ast::DefSelfTy(..) | ast::DefMethod(..) => {
468473
@cmt_ {
469474
id:id,
@@ -571,16 +576,13 @@ impl mem_categorization_ctxt {
571576
}
572577
}
573578

574-
pub fn cat_rvalue_node<N:ast_node>(&self,
575-
node: &N,
576-
expr_ty: ty::t) -> cmt {
577-
match self.tcx.region_maps.temporary_scope(node.id()) {
579+
pub fn cat_rvalue_node(&self, id: ast::NodeId, span: Span, expr_ty: ty::t) -> cmt {
580+
match self.tcx.region_maps.temporary_scope(id) {
578581
Some(scope) => {
579-
self.cat_rvalue(node.id(), node.span(),
580-
ty::ReScope(scope), expr_ty)
582+
self.cat_rvalue(id, span, ty::ReScope(scope), expr_ty)
581583
}
582584
None => {
583-
self.cat_rvalue(node.id(), node.span(), ty::ReStatic, expr_ty)
585+
self.cat_rvalue(id, span, ty::ReStatic, expr_ty)
584586
}
585587
}
586588
}
@@ -986,7 +988,7 @@ impl mem_categorization_ctxt {
986988
}
987989
for &slice_pat in slice.iter() {
988990
let slice_ty = self.pat_ty(slice_pat);
989-
let slice_cmt = self.cat_rvalue_node(pat, slice_ty);
991+
let slice_cmt = self.cat_rvalue_node(pat.id(), pat.span(), slice_ty);
990992
self.cat_pattern(slice_cmt, slice_pat, |x,y| op(x,y));
991993
}
992994
for &after_pat in after.iter() {

src/librustc/middle/region.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,14 @@ impl RegionMaps {
172172
}
173173

174174
// else, locate the innermost terminating scope
175-
let mut id = self.encl_scope(expr_id);
175+
// if there's one. Static items, for instance, won't
176+
// have an enclusing scope, hence no scope will be
177+
// returned.
178+
let mut id = match self.opt_encl_scope(expr_id) {
179+
Some(i) => i,
180+
None => { return None; }
181+
};
182+
176183
let terminating_scopes = self.terminating_scopes.borrow();
177184
while !terminating_scopes.get().contains(&id) {
178185
match self.opt_encl_scope(id) {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// This tests verifies that unary structs and enum variants
12+
// are treated as rvalues and their lifetime is not bounded to
13+
// the static scope.
14+
15+
struct Test;
16+
17+
enum MyEnum {
18+
Variant1
19+
}
20+
21+
fn structLifetime() -> &Test {
22+
let testValue = &Test; //~ ERROR borrowed value does not live long enough
23+
testValue
24+
}
25+
26+
fn variantLifetime() -> &MyEnum {
27+
let testValue = &Variant1; //~ ERROR borrowed value does not live long enough
28+
testValue
29+
}
30+
31+
32+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -8,14 +8,21 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
// This test verifies that temporary lifetime is correctly computed
12+
// for static objects in enclosing scopes.
13+
1114
extern mod extra;
1215
use std::cmp::Eq;
1316

1417
fn f<T:Eq>(o: &mut Option<T>) {
1518
assert!(*o == None);
1619
}
1720

18-
fn main() {
21+
pub fn main() {
22+
mod t {
23+
enum E {V=1, A=0}
24+
static C: E = V;
25+
}
26+
1927
f::<int>(&mut None);
20-
//~^ ERROR cannot borrow
2128
}

0 commit comments

Comments
 (0)