Skip to content

Commit 279fe0f

Browse files
committed
Treat unary struct and enum variants as rvalues
Closes #11681
1 parent 1d80a9a commit 279fe0f

File tree

2 files changed

+51
-17
lines changed

2 files changed

+51
-17
lines changed

src/librustc/middle/mem_categorization.rs

+19-17
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() {
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() {}

0 commit comments

Comments
 (0)