about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/middle/trans/expr.rs2
-rw-r--r--src/librustc/middle/trans/glue.rs3
-rw-r--r--src/test/run-pass/issue-9382.rs53
3 files changed, 55 insertions, 3 deletions
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index 2c3a9e040c9..212b65f7bc6 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -1293,7 +1293,7 @@ fn trans_adt(bcx: @mut Block, repr: &adt::Repr, discr: ty::Disr,
     adt::trans_start_init(bcx, repr, addr, discr);
     for &(i, e) in fields.iter() {
         let dest = adt::trans_field_ptr(bcx, repr, addr, discr, i);
-        let e_ty = expr_ty(bcx, e);
+        let e_ty = expr_ty_adjusted(bcx, e);
         bcx = trans_into(bcx, e, SaveIn(dest));
         add_clean_temp_mem(bcx, dest, e_ty);
         temp_cleanups.push(dest);
diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs
index 4e796fd21b3..b7c51810996 100644
--- a/src/librustc/middle/trans/glue.rs
+++ b/src/librustc/middle/trans/glue.rs
@@ -274,8 +274,7 @@ pub fn call_tydesc_glue_full(bcx: @mut Block,
     let ccx = bcx.ccx();
     // NB: Don't short-circuit even if this block is unreachable because
     // GC-based cleanup needs to the see that the roots are live.
-    let no_lpads =
-        ccx.sess.opts.debugging_opts & session::no_landing_pads != 0;
+    let no_lpads = ccx.sess.opts.debugging_opts & session::no_landing_pads != 0;
     if bcx.unreachable && !no_lpads { return; }
 
     let static_glue_fn = match static_ti {
diff --git a/src/test/run-pass/issue-9382.rs b/src/test/run-pass/issue-9382.rs
new file mode 100644
index 00000000000..4b79760956c
--- /dev/null
+++ b/src/test/run-pass/issue-9382.rs
@@ -0,0 +1,53 @@
+ // Copyright 2013 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.
+
+#[allow(unnecessary_allocation)];
+
+// Tests for a previous bug that occured due to an interaction
+// between struct field initialization and the auto-coercion
+// from a vector to a slice. The drop glue was being invoked on
+// the temporary slice with a wrong type, triggering an LLVM assert.
+
+struct Thing1<'self> {
+    baz: &'self [~int],
+    bar: ~u64,
+}
+
+struct Thing2<'self> {
+    baz: &'self [~int],
+    bar: u64,
+}
+
+pub fn main() {
+    let _t1_fixed = Thing1 {
+        baz: [],
+        bar: ~32,
+    };
+    let _t1_uniq = Thing1 {
+        baz: ~[],
+        bar: ~32,
+    };
+    let _t1_at = Thing1 {
+        baz: @[],
+        bar: ~32,
+    };
+    let _t2_fixed = Thing2 {
+        baz: [],
+        bar: 32,
+    };
+    let _t2_uniq = Thing2 {
+        baz: ~[],
+        bar: 32,
+    };
+    let _t2_at = Thing2 {
+        baz: @[],
+        bar: 32,
+    };
+}