diff options
| author | Jakub Wieczorek <jakub@jakub.cc> | 2014-09-16 20:11:16 +0200 |
|---|---|---|
| committer | Jakub Wieczorek <jakub@jakub.cc> | 2014-09-16 20:34:16 +0200 |
| commit | bdd9ee3cc7f49008fd5d0ea11c16d681910d291e (patch) | |
| tree | 6b342dc8e9e8c7d2a4fb3020cfc4a1d53a4036f0 | |
| parent | 946654a721d6fd5eeb91e93293cdc2cba83c78b9 (diff) | |
| download | rust-bdd9ee3cc7f49008fd5d0ea11c16d681910d291e.tar.gz rust-bdd9ee3cc7f49008fd5d0ea11c16d681910d291e.zip | |
Run cleanup for base struct in functional struct update expressions
Fixes #17302.
| -rw-r--r-- | src/librustc/middle/trans/expr.rs | 12 | ||||
| -rw-r--r-- | src/test/run-pass/issue-17302.rs | 34 |
2 files changed, 40 insertions, 6 deletions
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index af57d49d9d8..77712570185 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -1380,7 +1380,11 @@ pub fn trans_adt<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, assert_eq!(discr, 0); match ty::expr_kind(bcx.tcx(), &*base.expr) { - ty::LvalueExpr => { + ty::RvalueDpsExpr | ty::RvalueDatumExpr if !ty::type_needs_drop(bcx.tcx(), ty) => { + bcx = trans_into(bcx, &*base.expr, SaveIn(addr)); + }, + ty::RvalueStmtExpr => bcx.tcx().sess.bug("unexpected expr kind for struct base expr"), + _ => { let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, &*base.expr, "base")); for &(i, t) in base.fields.iter() { let datum = base_datum.get_element( @@ -1389,11 +1393,7 @@ pub fn trans_adt<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, let dest = adt::trans_field_ptr(bcx, &*repr, addr, discr, i); bcx = datum.store_to(bcx, dest); } - }, - ty::RvalueDpsExpr | ty::RvalueDatumExpr => { - bcx = trans_into(bcx, &*base.expr, SaveIn(addr)); - }, - ty::RvalueStmtExpr => bcx.tcx().sess.bug("unexpected expr kind for struct base expr") + } } } diff --git a/src/test/run-pass/issue-17302.rs b/src/test/run-pass/issue-17302.rs new file mode 100644 index 00000000000..50583c7d127 --- /dev/null +++ b/src/test/run-pass/issue-17302.rs @@ -0,0 +1,34 @@ +// 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. + +static mut DROPPED: [bool, ..2] = [false, false]; + +struct A(uint); +struct Foo { _a: A, _b: int } + +impl Drop for A { + fn drop(&mut self) { + let A(i) = *self; + unsafe { DROPPED[i] = true; } + } +} + +fn main() { + { + Foo { + _a: A(0), + ..Foo { _a: A(1), _b: 2 } + }; + } + unsafe { + assert!(DROPPED[0]); + assert!(DROPPED[1]); + } +} |
