Skip to content

Commit bdd9ee3

Browse files
author
Jakub Wieczorek
committed
Run cleanup for base struct in functional struct update expressions
Fixes #17302.
1 parent 946654a commit bdd9ee3

File tree

2 files changed

+40
-6
lines changed

2 files changed

+40
-6
lines changed

src/librustc/middle/trans/expr.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1380,7 +1380,11 @@ pub fn trans_adt<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
13801380
assert_eq!(discr, 0);
13811381

13821382
match ty::expr_kind(bcx.tcx(), &*base.expr) {
1383-
ty::LvalueExpr => {
1383+
ty::RvalueDpsExpr | ty::RvalueDatumExpr if !ty::type_needs_drop(bcx.tcx(), ty) => {
1384+
bcx = trans_into(bcx, &*base.expr, SaveIn(addr));
1385+
},
1386+
ty::RvalueStmtExpr => bcx.tcx().sess.bug("unexpected expr kind for struct base expr"),
1387+
_ => {
13841388
let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, &*base.expr, "base"));
13851389
for &(i, t) in base.fields.iter() {
13861390
let datum = base_datum.get_element(
@@ -1389,11 +1393,7 @@ pub fn trans_adt<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
13891393
let dest = adt::trans_field_ptr(bcx, &*repr, addr, discr, i);
13901394
bcx = datum.store_to(bcx, dest);
13911395
}
1392-
},
1393-
ty::RvalueDpsExpr | ty::RvalueDatumExpr => {
1394-
bcx = trans_into(bcx, &*base.expr, SaveIn(addr));
1395-
},
1396-
ty::RvalueStmtExpr => bcx.tcx().sess.bug("unexpected expr kind for struct base expr")
1396+
}
13971397
}
13981398
}
13991399

src/test/run-pass/issue-17302.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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+
static mut DROPPED: [bool, ..2] = [false, false];
12+
13+
struct A(uint);
14+
struct Foo { _a: A, _b: int }
15+
16+
impl Drop for A {
17+
fn drop(&mut self) {
18+
let A(i) = *self;
19+
unsafe { DROPPED[i] = true; }
20+
}
21+
}
22+
23+
fn main() {
24+
{
25+
Foo {
26+
_a: A(0),
27+
..Foo { _a: A(1), _b: 2 }
28+
};
29+
}
30+
unsafe {
31+
assert!(DROPPED[0]);
32+
assert!(DROPPED[1]);
33+
}
34+
}

0 commit comments

Comments
 (0)