about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBjörn Steinbrink <bsteinbr@gmail.com>2015-07-03 12:19:36 +0200
committerBjörn Steinbrink <bsteinbr@gmail.com>2015-07-03 14:44:51 +0200
commiteaeede21269b52e0a060d363744d10fb817adec3 (patch)
tree552c7e5bfe5fe01dcd73b95650763caf3d0ed29f
parent4c246ecb64d147a2853747dedf1db76d06094891 (diff)
downloadrust-eaeede21269b52e0a060d363744d10fb817adec3.tar.gz
rust-eaeede21269b52e0a060d363744d10fb817adec3.zip
Fix ICE caused by Drop implementations for unsized types
Fixes #26709
-rw-r--r--src/librustc_trans/trans/glue.rs9
-rw-r--r--src/test/run-pass/issue-26709.rs26
2 files changed, 33 insertions, 2 deletions
diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs
index 3bcdcd89c47..e530eb0de59 100644
--- a/src/librustc_trans/trans/glue.rs
+++ b/src/librustc_trans/trans/glue.rs
@@ -355,7 +355,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         let ty = Type::from_ref(llvm::LLVMTypeOf(dtor_addr));
         ty.element_type().func_params()
     };
-    assert_eq!(params.len(), 1);
+    assert_eq!(params.len(), if type_is_sized(bcx.tcx(), t) { 1 } else { 2 });
 
     // Be sure to put the contents into a scope so we can use an invoke
     // instruction to call the user destructor but still call the field
@@ -371,7 +371,12 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     let glue_type = get_drop_glue_type(bcx.ccx(), t);
     let dtor_ty = bcx.tcx().mk_ctor_fn(class_did, &[glue_type], bcx.tcx().mk_nil());
-    let (_, bcx) = invoke(bcx, dtor_addr, &[v0], dtor_ty, DebugLoc::None);
+    let (_, bcx) = if type_is_sized(bcx.tcx(), t) {
+        invoke(bcx, dtor_addr, &[v0], dtor_ty, DebugLoc::None)
+    } else {
+        let args = [Load(bcx, expr::get_dataptr(bcx, v0)), Load(bcx, expr::get_len(bcx, v0))];
+        invoke(bcx, dtor_addr, &args, dtor_ty, DebugLoc::None)
+    };
 
     bcx.fcx.pop_and_trans_custom_cleanup_scope(bcx, contents_scope)
 }
diff --git a/src/test/run-pass/issue-26709.rs b/src/test/run-pass/issue-26709.rs
new file mode 100644
index 00000000000..62626d75865
--- /dev/null
+++ b/src/test/run-pass/issue-26709.rs
@@ -0,0 +1,26 @@
+// Copyright 2015 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.
+
+struct Wrapper<'a, T: ?Sized>(&'a mut i32, T);
+
+impl<'a, T: ?Sized> Drop for Wrapper<'a, T> {
+    fn drop(&mut self) {
+        *self.0 = 432;
+    }
+}
+
+fn main() {
+    let mut x = 0;
+    {
+        let wrapper = Box::new(Wrapper(&mut x, 123));
+        let _: Box<Wrapper<Send>> = wrapper;
+    }
+    assert_eq!(432, x)
+}