Skip to content

Commit c8c3579

Browse files
committed
Fix closure arguments which are immediate because of field reordering.
While building immediates goes through type_of::type_of, extracting them must account for field reorderings.
1 parent cf5f80c commit c8c3579

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

src/librustc_trans/mir/block.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use llvm::{self, ValueRef};
1212
use rustc_const_eval::{ErrKind, ConstEvalErr, note_const_eval_err};
1313
use rustc::middle::lang_items;
14-
use rustc::ty;
14+
use rustc::ty::{self, layout};
1515
use rustc::mir;
1616
use abi::{Abi, FnType, ArgType};
1717
use adt;
@@ -722,8 +722,14 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
722722

723723
}
724724
Immediate(llval) => {
725+
let l = bcx.ccx().layout_of(tuple.ty);
726+
let v = if let layout::Univariant { ref variant, .. } = *l {
727+
variant
728+
} else {
729+
bug!("Not a tuple.");
730+
};
725731
for (n, &ty) in arg_types.iter().enumerate() {
726-
let mut elem = bcx.extract_value(llval, n);
732+
let mut elem = bcx.extract_value(llval, v.memory_index[n] as usize);
727733
// Truncate bools to i1, if needed
728734
if ty.is_bool() && common::val_ty(elem) != Type::i1(bcx.ccx()) {
729735
elem = bcx.trunc(elem, Type::i1(bcx.ccx()));
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2012 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+
12+
// After the work to reoptimize structs, it became possible for immediate logic to fail.
13+
// This test verifies that it actually works.
14+
15+
fn main() {
16+
let c = |a: u8, b: u16, c: u8| {
17+
assert_eq!(a, 1);
18+
assert_eq!(b, 2);
19+
assert_eq!(c, 3);
20+
};
21+
c(1, 2, 3);
22+
}

0 commit comments

Comments
 (0)