]> git.lizzy.rs Git - rust.git/commitdiff
Rebasing changes
authorNick Cameron <ncameron@mozilla.com>
Wed, 6 Aug 2014 09:59:40 +0000 (11:59 +0200)
committerNick Cameron <ncameron@mozilla.com>
Tue, 26 Aug 2014 04:07:32 +0000 (16:07 +1200)
80 files changed:
src/libcollections/ringbuf.rs
src/libcollections/str.rs
src/libcollections/string.rs
src/libcore/cmp.rs
src/libcore/option.rs
src/libcore/raw.rs
src/libcore/slice.rs
src/libcoretest/iter.rs
src/libdebug/reflect.rs
src/libdebug/repr.rs
src/liblibc/lib.rs
src/librbml/io.rs
src/librlibc/lib.rs
src/librustc/diagnostics.rs
src/librustc/front/test.rs
src/librustc/lint/builtin.rs
src/librustc/middle/astencode.rs
src/librustc/middle/check_const.rs
src/librustc/middle/intrinsicck.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/subst.rs
src/librustc/middle/trans/_match.rs
src/librustc/middle/trans/adt.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/callee.rs
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/consts.rs
src/librustc/middle/trans/controlflow.rs
src/librustc/middle/trans/datum.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/glue.rs
src/librustc/middle/trans/intrinsic.rs
src/librustc/middle/trans/meth.rs
src/librustc/middle/trans/reflect.rs
src/librustc/middle/trans/tvec.rs
src/librustc/middle/trans/type_of.rs
src/librustc/middle/ty.rs
src/librustc/middle/ty_fold.rs
src/librustc/middle/typeck/check/method.rs
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/vtable.rs
src/librustc/middle/typeck/infer/coercion.rs
src/librustc/util/ppaux.rs
src/libserialize/serialize.rs
src/libsyntax/parse/parser.rs
src/libtime/lib.rs
src/libunicode/u_str.rs
src/liburl/lib.rs
src/rt/rust_builtin.c
src/test/compile-fail/const-cast-different-types.rs
src/test/compile-fail/dst-bad-assign-2.rs
src/test/compile-fail/dst-bad-assign.rs
src/test/compile-fail/dst-bad-coerce1.rs
src/test/compile-fail/dst-bad-coerce2.rs
src/test/compile-fail/dst-bad-coerce3.rs
src/test/compile-fail/dst-bad-coerce4.rs
src/test/compile-fail/dst-bad-deep.rs
src/test/compile-fail/issue-3907-2.rs
src/test/compile-fail/issue-4972.rs
src/test/compile-fail/issue-5035-2.rs
src/test/compile-fail/issue-5883.rs
src/test/compile-fail/issue-7013.rs
src/test/compile-fail/tuple-arity-mismatch.rs
src/test/pretty/issue-4264.pp
src/test/run-make/graphviz-flowgraph/f15.dot-expected.dot
src/test/run-make/graphviz-flowgraph/f16.dot-expected.dot
src/test/run-pass/dst-dtor-1.rs [new file with mode: 0644]
src/test/run-pass/dst-dtor-2.rs [new file with mode: 0644]
src/test/run-pass/dst-struct-reflect.rs
src/test/run-pass/dst-struct-sole.rs
src/test/run-pass/dst-struct.rs
src/test/run-pass/dst-trait.rs
src/test/run-pass/gc-vec.rs
src/test/run-pass/issue-14936.rs
src/test/run-pass/issue-15080.rs
src/test/run-pass/match-vec-alternatives.rs
src/test/run-pass/order-drop-with-match.rs
src/test/run-pass/vec-matching.rs
src/test/run-pass/vec-to_str.rs

index d2cfb510bc058ee0da306fff53f7f50934bfab0f..2f0fbfadb17f3c0b9a3243156e8958b216db43c3 100644 (file)
@@ -243,7 +243,8 @@ pub fn reserve(&mut self, n: uint) {
     /// buf.push(5i);
     /// buf.push(3);
     /// buf.push(4);
-    /// assert_eq!(buf.iter().collect::<Vec<&int>>().as_slice(), &[&5, &3, &4]);
+    /// let b: &[_] = &[&5, &3, &4];
+    /// assert_eq!(buf.iter().collect::<Vec<&int>>().as_slice(), b);
     /// ```
     pub fn iter<'a>(&'a self) -> Items<'a, T> {
         Items{index: 0, rindex: self.nelts, lo: self.lo, elts: self.elts.as_slice()}
@@ -263,7 +264,8 @@ pub fn iter<'a>(&'a self) -> Items<'a, T> {
     /// for num in buf.mut_iter() {
     ///     *num = *num - 2;
     /// }
-    /// assert_eq!(buf.mut_iter().collect::<Vec<&mut int>>().as_slice(), &[&mut 3, &mut 1, &mut 2]);
+    /// let b: &[_] = &[&mut 3, &mut 1, &mut 2];
+    /// assert_eq!(buf.mut_iter().collect::<Vec<&mut int>>().as_slice(), b);
     /// ```
     pub fn mut_iter<'a>(&'a mut self) -> MutItems<'a, T> {
         let start_index = raw_index(self.lo, self.elts.len(), 0);
index 1145e1f3573198b3b6232c53a7a2fd1842a48e6d..3f9a179872e147725f6a9c4687a8197a8d899245 100644 (file)
@@ -1971,7 +1971,7 @@ fn test_graphemes() {
         use std::iter::order;
         // official Unicode test data
         // from http://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakTest.txt
-        let test_same = [
+        let test_same: [(_, &[_]), .. 325] = [
             ("\u0020\u0020", &["\u0020", "\u0020"]), ("\u0020\u0308\u0020", &["\u0020\u0308",
             "\u0020"]), ("\u0020\u000D", &["\u0020", "\u000D"]), ("\u0020\u0308\u000D",
             &["\u0020\u0308", "\u000D"]), ("\u0020\u000A", &["\u0020", "\u000A"]),
@@ -2180,7 +2180,7 @@ fn test_graphemes() {
             ("\u0646\u200D\u0020", &["\u0646\u200D", "\u0020"]),
         ];
 
-        let test_diff = [
+        let test_diff: [(_, &[_], &[_]), .. 23] = [
             ("\u0020\u0903", &["\u0020\u0903"], &["\u0020", "\u0903"]), ("\u0020\u0308\u0903",
             &["\u0020\u0308\u0903"], &["\u0020\u0308", "\u0903"]), ("\u000D\u0308\u0903",
             &["\u000D", "\u0308\u0903"], &["\u000D", "\u0308", "\u0903"]), ("\u000A\u0308\u0903",
@@ -2229,9 +2229,11 @@ fn test_graphemes() {
         // test the indices iterators
         let s = "a̐éö̲\r\n";
         let gr_inds = s.grapheme_indices(true).collect::<Vec<(uint, &str)>>();
-        assert_eq!(gr_inds.as_slice(), &[(0u, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")]);
+        let b: &[_] = &[(0u, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")];
+        assert_eq!(gr_inds.as_slice(), b);
         let gr_inds = s.grapheme_indices(true).rev().collect::<Vec<(uint, &str)>>();
-        assert_eq!(gr_inds.as_slice(), &[(11, "\r\n"), (6, "ö̲"), (3, "é"), (0u, "a̐")]);
+        let b: &[_] = &[(11, "\r\n"), (6, "ö̲"), (3, "é"), (0u, "a̐")];
+        assert_eq!(gr_inds.as_slice(), b);
         let mut gr_inds = s.grapheme_indices(true);
         let e1 = gr_inds.size_hint();
         assert_eq!(e1, (1, Some(13)));
@@ -2243,7 +2245,8 @@ fn test_graphemes() {
         // make sure the reverse iterator does the right thing with "\n" at beginning of string
         let s = "\n\r\n\r";
         let gr = s.graphemes(true).rev().collect::<Vec<&str>>();
-        assert_eq!(gr.as_slice(), &["\r", "\r\n", "\n"]);
+        let b: &[_] = &["\r", "\r\n", "\n"];
+        assert_eq!(gr.as_slice(), b);
     }
 
     #[test]
index 89fdc4d42fb88dd9daad84487d36542aebc0c762..05d91a7504150589d80b4e26bc0f8f58e88b94ff 100644 (file)
@@ -531,7 +531,8 @@ pub unsafe fn push_bytes(&mut self, bytes: &[u8]) {
     ///
     /// ```
     /// let s = String::from_str("hello");
-    /// assert_eq!(s.as_bytes(), &[104, 101, 108, 108, 111]);
+    /// let b: &[_] = &[104, 101, 108, 108, 111];
+    /// assert_eq!(s.as_bytes(), b);
     /// ```
     #[inline]
     pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
@@ -552,7 +553,8 @@ pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
     ///     bytes[1] = 51;
     ///     bytes[4] = 48;
     /// }
-    /// assert_eq!(s.as_bytes(), &[104, 51, 108, 108, 48]);
+    /// let b: &[_] = &[104, 51, 108, 108, 48];
+    /// assert_eq!(s.as_bytes(), b);
     /// assert_eq!(s.as_slice(), "h3ll0")
     /// ```
     #[inline]
index bfd10c835e2061a64b71e5d3bfa13f8172bd894a..b90c6daf9ebaec834c67af7459d7ae368af07f94 100644 (file)
@@ -112,12 +112,13 @@ impl Ordering {
     /// assert_eq!(Greater.reverse(), Less);
     ///
     ///
-    /// let mut data = &mut [2u, 10, 5, 8];
+    /// let mut data: &mut [_] = &mut [2u, 10, 5, 8];
     ///
     /// // sort the array from largest to smallest.
     /// data.sort_by(|a, b| a.cmp(b).reverse());
     ///
-    /// assert_eq!(data, &mut [10u, 8, 5, 2]);
+    /// let b: &mut [_] = &mut [10u, 8, 5, 2];
+    /// assert!(data == b);
     /// ```
     #[inline]
     #[experimental]
index 47df8ae68cdd2d2cb8ed472b0787296182b44e45..7773e03416e9e61bfda18d4dab35963421c81f00 100644 (file)
@@ -530,7 +530,10 @@ impl<T> Slice<T> for Option<T> {
     fn as_slice<'a>(&'a self) -> &'a [T] {
         match *self {
             Some(ref x) => slice::ref_slice(x),
-            None => &[]
+            None => {
+                let result: &[_] = &[];
+                result
+            }
         }
     }
 }
index aa8a4976867a67e9c6460fbe749f20016dc4738c..5daa693c77400267221036f4dbf2faf0a0029b13 100644 (file)
@@ -58,8 +58,8 @@ pub struct TraitObject {
 }
 #[cfg(not(stage0))]
 pub struct TraitObject {
-    pub data: *(),
-    pub vtable: *(),
+    pub data: *mut (),
+    pub vtable: *mut (),
 }
 
 /// This trait is meant to map equivalences between raw structs and their
index 8c55662f16395063dccb4c96df7a4f0e6bb3018b..475c2e94ec778a47f220e7ac78364eba3cbc4ec4 100644 (file)
@@ -1648,6 +1648,27 @@ impl<'a,T:PartialEq, V: Slice<T>> Equiv<V> for &'a [T] {
     fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
 }
 
+#[unstable = "waiting for DST"]
+impl<'a,T:PartialEq> PartialEq for &'a mut [T] {
+    fn eq(&self, other: & &'a mut [T]) -> bool {
+        self.len() == other.len() &&
+        order::eq(self.iter(), other.iter())
+    }
+    fn ne(&self, other: & &'a mut [T]) -> bool {
+        self.len() != other.len() ||
+        order::ne(self.iter(), other.iter())
+    }
+}
+
+#[unstable = "waiting for DST"]
+impl<'a,T:Eq> Eq for &'a mut [T] {}
+
+#[unstable = "waiting for DST"]
+impl<'a,T:PartialEq, V: Slice<T>> Equiv<V> for &'a mut [T] {
+    #[inline]
+    fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
+}
+
 #[unstable = "waiting for DST"]
 impl<'a,T:Ord> Ord for &'a [T] {
     fn cmp(&self, other: & &'a [T]) -> Ordering {
index d25ffb5b84c8a6aa926bc34e540a1bdfc9e0f214..99ac7cfed027f744708c0f69a404710170d2a70b 100644 (file)
@@ -368,7 +368,7 @@ fn test_collect() {
 
 #[test]
 fn test_all() {
-    let v: Box<&[int]> = box &[1i, 2, 3, 4, 5];
+    let v: Box<[int]> = box [1i, 2, 3, 4, 5];
     assert!(v.iter().all(|&x| x < 10));
     assert!(!v.iter().all(|&x| x % 2 == 0));
     assert!(!v.iter().all(|&x| x > 100));
@@ -377,7 +377,7 @@ fn test_all() {
 
 #[test]
 fn test_any() {
-    let v: Box<&[int]> = box &[1i, 2, 3, 4, 5];
+    let v: Box<[int]> = box [1i, 2, 3, 4, 5];
     assert!(v.iter().any(|&x| x < 10));
     assert!(v.iter().any(|&x| x % 2 == 0));
     assert!(!v.iter().any(|&x| x > 100));
index 0d7209b599970321fa0d7ba5df3f9e57d4f4d8d0..b89ea4d373ddc9b1bea52cb56373fb2a4ccc62ff 100644 (file)
@@ -251,7 +251,7 @@ fn visit_evec_fixed(&mut self, n: uint, sz: uint, align: uint,
     }
     #[cfg(not(stage0))]
     fn visit_evec_fixed(&mut self, n: uint, sz: uint, align: uint,
-                        inner: *TyDesc) -> bool {
+                        inner: *const TyDesc) -> bool {
         self.align(align);
         if ! self.inner.visit_evec_fixed(n, sz, align, inner) {
             return false;
index c810e1f64737f5f8c27ed017760ef696e677dcfd..20f96d24a5f5f14939b727db61b0f8962039504c 100644 (file)
@@ -342,7 +342,7 @@ fn visit_evec_fixed(&mut self, n: uint, sz: uint, _align: uint,
 
     #[cfg(not(stage0))]
     fn visit_evec_fixed(&mut self, n: uint, sz: uint, _align: uint,
-                        inner: *TyDesc) -> bool {
+                        inner: *const TyDesc) -> bool {
         let assumed_size = if sz == 0 { n } else { sz };
         self.get::<()>(|this, b| {
             this.write_vec_range(b, assumed_size, inner)
index 265d1e37ec3892568628b420c65541ed0eb42c3a..949dd08eaa343cc098db121f0f9aae587bea5f56 100644 (file)
 /// A wrapper for a nullable pointer. Don't use this except for interacting
 /// with libc. Basically Option, but without the dependence on libstd.
 // If/when libprim happens, this can be removed in favor of that
-pub enum Nullable<type T> {
+pub enum Nullable<T> {
     Null,
     NotNull(T)
 }
index 9ab163c5f474055fdb80ecc54ff25205111e0c88..443bf4d34ffa159918db047a6c07bca7fb54a980 100644 (file)
@@ -96,7 +96,8 @@ fn write(&mut self, buf: &[u8]) -> IoResult<()> {
             let (left, right) = if cap <= buf.len() {
                 (buf.slice_to(cap), buf.slice_from(cap))
             } else {
-                (buf, &[])
+                let result: (_, &[_]) = (buf, &[]);
+                result
             };
 
             // Do the necessary writes
@@ -142,24 +143,29 @@ fn test_seekable_mem_writer() {
         writer.write([1, 2, 3]).unwrap();
         writer.write([4, 5, 6, 7]).unwrap();
         assert_eq!(writer.tell(), Ok(8));
-        assert_eq!(writer.get_ref(), &[0, 1, 2, 3, 4, 5, 6, 7]);
+        let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
+        assert_eq!(writer.get_ref(), b);
 
         writer.seek(0, io::SeekSet).unwrap();
         assert_eq!(writer.tell(), Ok(0));
         writer.write([3, 4]).unwrap();
-        assert_eq!(writer.get_ref(), &[3, 4, 2, 3, 4, 5, 6, 7]);
+        let b: &[_] = &[3, 4, 2, 3, 4, 5, 6, 7];
+        assert_eq!(writer.get_ref(), b);
 
         writer.seek(1, io::SeekCur).unwrap();
         writer.write([0, 1]).unwrap();
-        assert_eq!(writer.get_ref(), &[3, 4, 2, 0, 1, 5, 6, 7]);
+        let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 7];
+        assert_eq!(writer.get_ref(), b);
 
         writer.seek(-1, io::SeekEnd).unwrap();
         writer.write([1, 2]).unwrap();
-        assert_eq!(writer.get_ref(), &[3, 4, 2, 0, 1, 5, 6, 1, 2]);
+        let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2];
+        assert_eq!(writer.get_ref(), b);
 
         writer.seek(1, io::SeekEnd).unwrap();
         writer.write([1]).unwrap();
-        assert_eq!(writer.get_ref(), &[3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1]);
+        let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1];
+        assert_eq!(writer.get_ref(), b);
     }
 
     #[test]
index b43ad1eabf90c9c690bc1bc2470a50149df1084a..739ec2cf43ffe9564ecfcdf12d40ef0de2270062 100644 (file)
@@ -49,7 +49,7 @@
 // implementations below. If pointer arithmetic is done through integers the
 // optimizations start to break down.
 extern "rust-intrinsic" {
-    fn offset<type T>(dst: *const T, offset: int) -> *const T;
+    fn offset<T>(dst: *const T, offset: int) -> *const T;
 }
 
 #[no_mangle]
index a789049d4de8c08cd5a276845aeef66c674b0d6f..77e73c46c402cf2f6ac23962b2dc4d80124759be 100644 (file)
@@ -34,7 +34,6 @@
     E0015,
     E0016,
     E0017,
-    E0018,
     E0019,
     E0020,
     E0021,
@@ -53,7 +52,6 @@
     E0034,
     E0035,
     E0036,
-    E0037,
     E0038,
     E0039,
     E0040,
@@ -80,8 +78,6 @@
     E0061,
     E0062,
     E0063,
-    E0064,
-    E0065,
     E0066,
     E0067,
     E0068,
     E0108,
     E0109,
     E0110,
-    E0111,
-    E0112,
     E0113,
     E0114,
     E0115,
index 9984aba8d08ab145d8126bcff240371e8a3df58c..5f26a966f97e7e556258ff929e904ec63d567b24 100644 (file)
@@ -477,10 +477,10 @@ fn mk_test_descs(cx: &TestCtxt) -> Gc<ast::Expr> {
 
     box(GC) ast::Expr {
         id: ast::DUMMY_NODE_ID,
-        node: ast::ExprAddrOf(box(GC) ast::MutImmutable,
+        node: ast::ExprAddrOf(ast::MutImmutable,
             box(GC) ast::Expr {
                 id: ast::DUMMY_NODE_ID,
-                node: ast::ExprVec(cx.testfns.borrow().iter().map(|test| {
+                node: ast::ExprVec(cx.testfns.iter().map(|test| {
                     mk_test_desc_and_fn_rec(cx, test)
             }).collect()),
             span: DUMMY_SP,
index 6cc1c6a7b37dfac992bd341c49e059cf9275e27a..214401b17a1bb52956d747f68183054b9dcfa245 100644 (file)
@@ -1556,6 +1556,9 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
 declare_lint!(pub VARIANT_SIZE_DIFFERENCE, Allow,
               "detects enums with widely varying variant sizes")
 
+declare_lint!(pub TRANSMUTE_FAT_PTR, Allow,
+              "detects transmutes of fat pointers")
+
 /// Does nothing as a lint pass, but registers some `Lint`s
 /// which are used by other parts of the compiler.
 pub struct HardwiredLints;
index 260e38f20708fa97ccc5aefe4e0cedc72ab07f01..6a8ee2675425f37edd7c39dd7777f918b948c5f9 100644 (file)
@@ -1029,6 +1029,8 @@ fn emit_auto_adjustment(&mut self, ecx: &e::EncodeContext, adj: &ty::AutoAdjustm
     }
 
     fn emit_autoref(&mut self, ecx: &e::EncodeContext, autoref: &ty::AutoRef) {
+        use serialize::Encoder;
+
         self.emit_enum("AutoRef", |this| {
             match autoref {
                 &ty::AutoPtr(r, m, None) => {
@@ -1067,6 +1069,8 @@ fn emit_autoref(&mut self, ecx: &e::EncodeContext, autoref: &ty::AutoRef) {
     }
 
     fn emit_auto_deref_ref(&mut self, ecx: &e::EncodeContext, auto_deref_ref: &ty::AutoDerefRef) {
+        use serialize::Encoder;
+
         self.emit_struct("AutoDerefRef", 2, |this| {
             this.emit_struct_field("autoderefs", 0, |this| auto_deref_ref.autoderefs.encode(this));
             this.emit_struct_field("autoref", 1, |this| {
@@ -1081,6 +1085,8 @@ fn emit_auto_deref_ref(&mut self, ecx: &e::EncodeContext, auto_deref_ref: &ty::A
     }
 
     fn emit_unsize_kind(&mut self, ecx: &e::EncodeContext, uk: &ty::UnsizeKind) {
+        use serialize::Encoder;
+
         self.emit_enum("UnsizeKind", |this| {
             match *uk {
                 ty::UnsizeLength(len) => {
@@ -1286,7 +1292,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
             _ if ty::adjust_is_object(adjustment) => {
                 let method_call = MethodCall::autoobject(id);
                 for &method in tcx.method_map.borrow().find(&method_call).iter() {
-                    rbml_w.tag(c::tag_table_method_map, |ebml_w| {
+                    rbml_w.tag(c::tag_table_method_map, |rbml_w| {
                         rbml_w.id(id);
                         rbml_w.tag(c::tag_table_val, |rbml_w| {
                             encode_method_callee(ecx, rbml_w, method_call.adjustment, method)
@@ -1297,7 +1303,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
                 for &dr in tcx.vtable_map.borrow().find(&method_call).iter() {
                     rbml_w.tag(c::tag_table_vtable_map, |rbml_w| {
                         rbml_w.id(id);
-                        rbml_w.tag(c::tag_table_val, |ebml_w| {
+                        rbml_w.tag(c::tag_table_val, |rbml_w| {
                             encode_vtable_res_with_key(ecx, rbml_w, method_call.adjustment, dr);
                         })
                     })
@@ -1336,7 +1342,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
         rbml_w.tag(c::tag_table_adjustments, |rbml_w| {
             rbml_w.id(id);
             rbml_w.tag(c::tag_table_val, |rbml_w| {
-                rbml_w.emit_auto_adjustment(ecx, adj);
+                rbml_w.emit_auto_adjustment(ecx, adjustment);
             })
         })
     }
index b0b2fe89c3f0fa9a834619e650b82cf21e7bb3ec..629aba8092c27b45ad795b2c7f52084c62fee73b 100644 (file)
@@ -182,7 +182,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
                     // Mutable slices are allowed.
                     ExprVec(_) => {}
                     _ => span_err!(v.tcx.sess, e.span, E0017,
-                                   "references in constants may only refer to immutable values");
+                                   "references in constants may only refer to immutable values")
 
                 }
           },
index 6669147b0dcacebf70cd721a5ebaf8faa8169dfe..639f89dc3cceddbfef8d0551915dabf9e3a63cb3 100644 (file)
@@ -92,7 +92,7 @@ fn def_id_is_transmute(&self, def_id: DefId) -> bool {
         }
     }
 
-    fn check_transmute(&self, span: Span, from: ty::t, to: ty::t) {
+    fn check_transmute(&self, span: Span, from: ty::t, to: ty::t, id: ast::NodeId) {
         if type_size_is_affected_by_type_parameters(self.tcx, from) {
             span_err!(self.tcx.sess, span, E0139,
                       "cannot transmute from a type that contains type parameters");
@@ -106,6 +106,7 @@ fn check_transmute(&self, span: Span, from: ty::t, to: ty::t) {
             span: span,
             from: from,
             to: to,
+            id: id,
         };
         self.tcx.transmute_restrictions.borrow_mut().push(restriction);
     }
@@ -123,7 +124,7 @@ fn visit_expr(&mut self, expr: &ast::Expr, (): ()) {
                                     if bare_fn_ty.abi == RustIntrinsic => {
                                 let from = *bare_fn_ty.sig.inputs.get(0);
                                 let to = bare_fn_ty.sig.output;
-                                self.check_transmute(expr.span, from, to);
+                                self.check_transmute(expr.span, from, to, expr.id);
                             }
                             _ => {
                                 self.tcx
index 155b69d0a84c2749118c500c5939ea8c296dc7f5..2d052feb6720f03974dca1234145901767315217 100644 (file)
@@ -214,7 +214,7 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
 }
 
 pub fn deref_kind(tcx: &ty::ctxt, t: ty::t) -> deref_kind {
-    debug!("deref_kind {}", ty_to_str(tcx, t));
+    debug!("deref_kind {}", ty_to_string(tcx, t));
     match opt_deref_kind(t) {
       Some(k) => k,
       None => {
index 673872103af60977c3ea6dfa76ed81201f03a21a..ccc4dbb21e019df9609baa663d45e5c5a4f308b7 100644 (file)
@@ -403,7 +403,7 @@ pub fn get_slice<'a>(&'a self, space: ParamSpace) -> &'a [T] {
         self.content.slice(start, limit)
     }
 
-    fn get_mut_slice<'a>(&'a mut self, space: ParamSpace) -> &'a mut [T] {
+    pub fn get_mut_slice<'a>(&'a mut self, space: ParamSpace) -> &'a mut [T] {
         let (start, limit) = self.limits(space);
         self.content.mut_slice(start, limit)
     }
index 4a26d4f800210e7d02e7cf612a8c2230919eeec2..28f396c8bf795821c6d1bbc05b90be058826621e 100644 (file)
@@ -280,7 +280,7 @@ fn trans_opt<'a>(mut bcx: &'a Block<'a>, o: &Opt) -> opt_result<'a> {
     match *o {
         lit(lit_expr) => {
             let lit_ty = ty::node_id_to_type(bcx.tcx(), lit_expr.id);
-            let (llval, _) = consts::const_expr(ccx, &*lit_expr, true);
+            let (llval, _, _) = consts::const_expr(ccx, &*lit_expr, true);
             let lit_datum = immediate_rvalue(llval, lit_ty);
             let lit_datum = unpack_datum!(bcx, lit_datum.to_appropriate_datum(bcx));
             return single_result(Result::new(bcx, lit_datum.val));
index 3bcefe7ec9dbbf9285cabf795c151e7abb6aaef4..f3f4a88fdee4fa9c32106499091758c91a3d42f1 100644 (file)
@@ -127,11 +127,11 @@ pub enum Repr {
 
 /// For structs, and struct-like parts of anything fancier.
 pub struct Struct {
-    // If the struct is DST, then we will not know its size. We must be careful
-    // never to use such a struct when a fixed size is required (e.g., stack
-    // allocation).
-    pub size: Option<u64>,
-    pub align: Option<u64>,
+    // If the struct is DST, then the size and alignment do not take into
+    // account the unsized fields of the struct.
+    pub size: u64,
+    pub align: u64,
+    pub sized: bool,
     pub packed: bool,
     pub fields: Vec<ty::t>
 }
@@ -269,7 +269,7 @@ fn represent_type_uncached(cx: &CrateContext, t: ty::t) -> Repr {
             }).collect(), dtor);
         }
         _ => cx.sess().bug(format!("adt::represent_type called on non-ADT type: {}",
-                           ty_to_str(cx.tcx(), t)).as_slice())
+                           ty_to_string(cx.tcx(), t)).as_slice())
     }
 }
 
@@ -288,7 +288,7 @@ pub enum PointerField {
 
 impl Case {
     fn is_zerolen(&self, cx: &CrateContext) -> bool {
-        mk_struct(cx, self.tys.as_slice(), false).size.unwrap() == 0
+        mk_struct(cx, self.tys.as_slice(), false).size == 0
     }
 
     fn find_ptr(&self) -> Option<PointerField> {
@@ -310,7 +310,7 @@ fn find_ptr(&self) -> Option<PointerField> {
 
                 // Box<T> could either be a thin or fat pointer depending on T
                 ty::ty_uniq(t) => match ty::get(t).sty {
-                    ty::ty_vec(_, None) | return Some(FatPointer(i, slice_elt_base)),
+                    ty::ty_vec(_, None) => return Some(FatPointer(i, slice_elt_base)),
 
                     // Box<Trait> is a pair of pointers: the actual object and a vtable
                     ty::ty_trait(..) => return Some(FatPointer(i, trt_field_box)),
@@ -351,18 +351,24 @@ fn mk_struct(cx: &CrateContext, tys: &[ty::t], packed: bool) -> Struct {
         let lltys = tys.iter().map(|&ty| type_of::sizing_type_of(cx, ty)).collect::<Vec<_>>();
         let llty_rec = Type::struct_(cx, lltys.as_slice(), packed);
         Struct {
-            size: Some(machine::llsize_of_alloc(cx, llty_rec) /*bad*/as u64),
-            align: Some(machine::llalign_of_min(cx, llty_rec) /*bad*/as u64),
+            size: machine::llsize_of_alloc(cx, llty_rec),
+            align: machine::llalign_of_min(cx, llty_rec),
+            sized: true,
             packed: packed,
             fields: Vec::from_slice(tys),
         }
     } else {
+        // Ignore any dynamically sized fields.
+        let lltys = tys.iter().filter(|&ty| ty::type_is_sized(cx.tcx(), *ty))
+            .map(|&ty| type_of::sizing_type_of(cx, ty)).collect::<Vec<_>>();
+        let llty_rec = Type::struct_(cx, lltys.as_slice(), packed);
         Struct {
-            size: None,
-            align: None,
+            size: machine::llsize_of_alloc(cx, llty_rec),
+            align: machine::llalign_of_min(cx, llty_rec),
+            sized: false,
             packed: packed,
             fields: Vec::from_slice(tys),
-        }        
+        }
     }
 }
 
@@ -467,31 +473,38 @@ pub fn ty_of_inttype(ity: IntType) -> ty::t {
  * unbounded recursion; see also the comments in `trans::type_of`.
  */
 pub fn type_of(cx: &CrateContext, r: &Repr) -> Type {
-    generic_type_of(cx, r, None, false)
+    generic_type_of(cx, r, None, false, false)
 }
-pub fn sizing_type_of(cx: &CrateContext, r: &Repr) -> Type {
-    generic_type_of(cx, r, None, true)
+// Pass dst=true if the type you are passing is a DST. Yes, we could figure
+// this out, but if you call this on an unsized type without realising it, you
+// are going to get the wrong type (it will not include the unsized parts of it).
+pub fn sizing_type_of(cx: &CrateContext, r: &Repr, dst: bool) -> Type {
+    generic_type_of(cx, r, None, true, dst)
 }
 pub fn incomplete_type_of(cx: &CrateContext, r: &Repr, name: &str) -> Type {
-    generic_type_of(cx, r, Some(name), false)
+    generic_type_of(cx, r, Some(name), false, false)
 }
 pub fn finish_type_of(cx: &CrateContext, r: &Repr, llty: &mut Type) {
     match *r {
         CEnum(..) | General(..) | RawNullablePointer { .. } => { }
         Univariant(ref st, _) | StructWrappedNullablePointer { nonnull: ref st, .. } =>
-            llty.set_struct_body(struct_llfields(cx, st, false).as_slice(),
+            llty.set_struct_body(struct_llfields(cx, st, false, false).as_slice(),
                                  st.packed)
     }
 }
 
-fn generic_type_of(cx: &CrateContext, r: &Repr, name: Option<&str>, sizing: bool) -> Type {
+fn generic_type_of(cx: &CrateContext,
+                   r: &Repr,
+                   name: Option<&str>,
+                   sizing: bool,
+                   dst: bool) -> Type {
     match *r {
         CEnum(ity, _, _) => ll_inttype(cx, ity),
         RawNullablePointer { nnty, .. } => type_of::sizing_type_of(cx, nnty),
         Univariant(ref st, _) | StructWrappedNullablePointer { nonnull: ref st, .. } => {
             match name {
                 None => {
-                    Type::struct_(cx, struct_llfields(cx, st, sizing).as_slice(),
+                    Type::struct_(cx, struct_llfields(cx, st, sizing, dst).as_slice(),
                                   st.packed)
                 }
                 Some(name) => { assert_eq!(sizing, false); Type::named_struct(cx, name) }
@@ -510,9 +523,9 @@ fn generic_type_of(cx: &CrateContext, r: &Repr, name: Option<&str>, sizing: bool
             // of the size.
             //
             // FIXME #10604: this breaks when vector types are present.
-            let size = sts.iter().map(|st| st.size.unwrap()).max().unwrap();
-            let most_aligned = sts.iter().max_by(|st| st.align.unwrap()).unwrap();
-            let align = most_aligned.align.unwrap();
+            let size = sts.iter().map(|st| st.size).max().unwrap();
+            let most_aligned = sts.iter().max_by(|st| st.align).unwrap();
+            let align = most_aligned.align;
             let discr_ty = ll_inttype(cx, ity);
             let discr_size = machine::llsize_of_alloc(cx, discr_ty) as u64;
             let align_units = (size + align - 1) / align - 1;
@@ -543,9 +556,10 @@ fn generic_type_of(cx: &CrateContext, r: &Repr, name: Option<&str>, sizing: bool
     }
 }
 
-fn struct_llfields(cx: &CrateContext, st: &Struct, sizing: bool) -> Vec<Type> {
+fn struct_llfields(cx: &CrateContext, st: &Struct, sizing: bool, dst: bool) -> Vec<Type> {
     if sizing {
-        st.fields.iter().map(|&ty| type_of::sizing_type_of(cx, ty)).collect()
+        st.fields.iter().filter(|&ty| !dst || ty::type_is_sized(cx.tcx(), *ty))
+            .map(|&ty| type_of::sizing_type_of(cx, ty)).collect()
     } else {
         st.fields.iter().map(|&ty| type_of::type_of(cx, ty)).collect()
     }
@@ -906,12 +920,12 @@ pub fn trans_const(ccx: &CrateContext, r: &Repr, discr: Disr,
         }
         General(ity, ref cases, _) => {
             let case = cases.get(discr as uint);
-            let max_sz = cases.iter().map(|x| x.size.unwrap()).max().unwrap();
+            let max_sz = cases.iter().map(|x| x.size).max().unwrap();
             let lldiscr = C_integral(ll_inttype(ccx, ity), discr as u64, true);
             let contents = build_const_struct(ccx,
                                               case,
                                               (vec!(lldiscr)).append(vals).as_slice());
-            C_struct(ccx, contents.append([padding(ccx, max_sz - case.size.unwrap())]).as_slice(),
+            C_struct(ccx, contents.append([padding(ccx, max_sz - case.size)]).as_slice(),
                      false)
         }
         Univariant(ref st, _dro) => {
@@ -958,7 +972,7 @@ fn compute_struct_field_offsets(ccx: &CrateContext, st: &Struct) -> Vec<u64> {
     for &ty in st.fields.iter() {
         let llty = type_of::sizing_type_of(ccx, ty);
         if !st.packed {
-            let type_align = machine::llalign_of_min(ccx, llty) as u64;
+            let type_align = type_of::align_of(ccx, ty) as u64;
             offset = roundup(offset, type_align);
         }
         offsets.push(offset);
@@ -1002,9 +1016,9 @@ fn build_const_struct(ccx: &CrateContext, st: &Struct, vals: &[ValueRef])
         offset += machine::llsize_of_alloc(ccx, val_ty(val)) as u64;
     }
 
-    assert!(offset <= st.size.unwrap());
-    if offset != st.size.unwrap() {
-        cfields.push(padding(ccx, st.size.unwrap() - offset));
+    assert!(st.sized && offset <= st.size);
+    if offset != st.size {
+        cfields.push(padding(ccx, st.size - offset));
     }
 
     cfields
index b27afdb864b977dbc938bd5669c8b91f4f7d0328..8968c8cc2599f5d443b7af554c50bc964d693b4a 100644 (file)
@@ -65,7 +65,7 @@
 use middle::trans::inline;
 use middle::trans::intrinsic;
 use middle::trans::machine;
-use middle::trans::machine::{llalign_of_min, llsize_of, llsize_of_real};
+use middle::trans::machine::{llsize_of, llsize_of_real};
 use middle::trans::meth;
 use middle::trans::monomorphize;
 use middle::trans::tvec;
@@ -394,7 +394,7 @@ pub fn malloc_raw_dyn_managed<'a>(
     // Grab the TypeRef type of box_ptr_ty.
     let box_ptr_ty = ty::mk_box(bcx.tcx(), t);
     let llty = type_of(ccx, box_ptr_ty);
-    let llalign = C_uint(ccx, llalign_of_min(ccx, llty) as uint);
+    let llalign = C_uint(ccx, type_of::align_of(ccx, box_ptr_ty) as uint);
 
     // Allocate space:
     let drop_glue = glue::get_drop_glue(ccx, t);
@@ -710,14 +710,33 @@ fn iter_variant<'r,
         return cx;
     }
 
+    let (data_ptr, info) = if ty::type_is_sized(cx.tcx(), t) {
+        (av, None)
+    } else {
+        let data = GEPi(cx, av, [0, abi::slice_elt_base]);
+        let info = GEPi(cx, av, [0, abi::slice_elt_len]);
+        (Load(cx, data), Some(Load(cx, info)))
+    };
+
     let mut cx = cx;
     match ty::get(t).sty {
       ty::ty_struct(..) => {
           let repr = adt::represent_type(cx.ccx(), t);
           expr::with_field_tys(cx.tcx(), t, None, |discr, field_tys| {
               for (i, field_ty) in field_tys.iter().enumerate() {
-                  let llfld_a = adt::trans_field_ptr(cx, &*repr, av, discr, i);
-                  cx = f(cx, llfld_a, field_ty.mt.ty);
+                  let field_ty = field_ty.mt.ty;
+                  let llfld_a = adt::trans_field_ptr(cx, &*repr, data_ptr, discr, i);
+
+                  let val = if ty::type_is_sized(cx.tcx(), field_ty) {
+                      llfld_a
+                  } else {
+                      let boxed_ty = ty::mk_open(cx.tcx(), field_ty);
+                      let scratch = datum::rvalue_scratch_datum(cx, boxed_ty, "__fat_ptr_iter");
+                      Store(cx, llfld_a, GEPi(cx, scratch.val, [0, abi::slice_elt_base]));
+                      Store(cx, info.unwrap(), GEPi(cx, scratch.val, [0, abi::slice_elt_len]));
+                      scratch.val
+                  };
+                  cx = f(cx, val, field_ty);
               }
           })
       }
@@ -725,19 +744,19 @@ fn iter_variant<'r,
           let repr = adt::represent_type(cx.ccx(), t);
           let upvars = ty::unboxed_closure_upvars(cx.tcx(), def_id);
           for (i, upvar) in upvars.iter().enumerate() {
-              let llupvar = adt::trans_field_ptr(cx, &*repr, av, 0, i);
+              let llupvar = adt::trans_field_ptr(cx, &*repr, data_ptr, 0, i);
               cx = f(cx, llupvar, upvar.ty);
           }
       }
       ty::ty_vec(_, Some(n)) => {
-        let (base, len) = tvec::get_fixed_base_and_len(cx, av, n);
+        let (base, len) = tvec::get_fixed_base_and_len(cx, data_ptr, n);
         let unit_ty = ty::sequence_element_type(cx.tcx(), t);
         cx = tvec::iter_vec_raw(cx, base, unit_ty, len, f);
       }
       ty::ty_tup(ref args) => {
           let repr = adt::represent_type(cx.ccx(), t);
           for (i, arg) in args.iter().enumerate() {
-              let llfld_a = adt::trans_field_ptr(cx, &*repr, av, 0, i);
+              let llfld_a = adt::trans_field_ptr(cx, &*repr, data_ptr, 0, i);
               cx = f(cx, llfld_a, *arg);
           }
       }
@@ -781,7 +800,7 @@ fn iter_variant<'r,
                       let variant_cx =
                           iter_variant(variant_cx,
                                        &*repr,
-                                       av,
+                                       data_ptr,
                                        &**variant,
                                        substs,
                                        |x,y,z| f(x,y,z));
@@ -968,7 +987,7 @@ pub fn invoke<'a>(
     // FIXME(15064) Lang item methods may (in the reflect case) not have proper
     // types, so doing an attribute lookup will fail.
     let attributes = if is_lang_item {
-        Vec::new()
+        llvm::AttrBuilder::new()
     } else {
         get_fn_llvm_attributes(bcx.ccx(), fn_ty)
     };
@@ -1158,7 +1177,7 @@ pub fn memcpy_ty(bcx: &Block, dst: ValueRef, src: ValueRef, t: ty::t) {
     if ty::type_is_structural(t) {
         let llty = type_of::type_of(ccx, t);
         let llsz = llsize_of(ccx, llty);
-        let llalign = llalign_of_min(ccx, llty);
+        let llalign = type_of::align_of(ccx, t);
         call_memcpy(bcx, dst, src, llsz, llalign as u32);
     } else {
         store_ty(bcx, Load(bcx, src), dst, t);
@@ -1169,9 +1188,7 @@ pub fn zero_mem(cx: &Block, llptr: ValueRef, t: ty::t) {
     if cx.unreachable.get() { return; }
     let _icx = push_ctxt("zero_mem");
     let bcx = cx;
-    let ccx = cx.ccx();
-    let llty = type_of::type_of(ccx, t);
-    memzero(&B(bcx), llptr, llty);
+    memzero(&B(bcx), llptr, t);
 }
 
 // Always use this function instead of storing a zero constant to the memory
@@ -1179,10 +1196,12 @@ pub fn zero_mem(cx: &Block, llptr: ValueRef, t: ty::t) {
 // allocation for large data structures, and the generated code will be
 // awful. (A telltale sign of this is large quantities of
 // `mov [byte ptr foo],0` in the generated code.)
-fn memzero(b: &Builder, llptr: ValueRef, ty: Type) {
+fn memzero(b: &Builder, llptr: ValueRef, ty: ty::t) {
     let _icx = push_ctxt("memzero");
     let ccx = b.ccx;
 
+    let llty = type_of::type_of(ccx, ty);
+
     let intrinsic_key = match ccx.sess().targ_cfg.arch {
         X86 | Arm | Mips | Mipsel => "llvm.memset.p0i8.i32",
         X86_64 => "llvm.memset.p0i8.i64"
@@ -1191,8 +1210,8 @@ fn memzero(b: &Builder, llptr: ValueRef, ty: Type) {
     let llintrinsicfn = ccx.get_intrinsic(&intrinsic_key);
     let llptr = b.pointercast(llptr, Type::i8(ccx).ptr_to());
     let llzeroval = C_u8(ccx, 0);
-    let size = machine::llsize_of(ccx, ty);
-    let align = C_i32(ccx, llalign_of_min(ccx, ty) as i32);
+    let size = machine::llsize_of(ccx, llty);
+    let align = C_i32(ccx, type_of::align_of(ccx, ty) as i32);
     let volatile = C_bool(ccx, false);
     b.call(llintrinsicfn, [llptr, llzeroval, size, align, volatile], None);
 }
@@ -1223,13 +1242,14 @@ pub fn alloca_no_lifetime(cx: &Block, ty: Type, name: &str) -> ValueRef {
     Alloca(cx, ty, name)
 }
 
-pub fn alloca_zeroed(cx: &Block, ty: Type, name: &str) -> ValueRef {
+pub fn alloca_zeroed(cx: &Block, ty: ty::t, name: &str) -> ValueRef {
+    let llty = type_of::type_of(cx.ccx(), ty);
     if cx.unreachable.get() {
         unsafe {
-            return llvm::LLVMGetUndef(ty.ptr_to().to_ref());
+            return llvm::LLVMGetUndef(llty.ptr_to().to_ref());
         }
     }
-    let p = alloca_no_lifetime(cx, ty, name);
+    let p = alloca_no_lifetime(cx, llty, name);
     let b = cx.fcx.ccx.builder();
     b.position_before(cx.fcx.alloca_insert_pt.get().unwrap());
     memzero(&b, p, ty);
@@ -1648,7 +1668,8 @@ fn copy_unboxed_closure_args_to_allocas<'a>(
     for j in range(0, args.len()) {
         let tuple_element_type = untupled_arg_types[j];
         let tuple_element_datum =
-            tuple_datum.get_element(tuple_element_type,
+            tuple_datum.get_element(bcx,
+                                    tuple_element_type,
                                     |llval| GEPi(bcx, llval, [0, j]));
         let tuple_element_datum = tuple_element_datum.to_expr_datum();
         let tuple_element_datum =
index 1283cc19528a622d07960ef106185c9a261d95b2..7566cfbac56c4a6268187649e354150d446f1c9a 100644 (file)
@@ -970,6 +970,7 @@ fn trans_args_under_call_abi<'a>(
             let repr_ptr = &*repr;
             for i in range(0, field_types.len()) {
                 let arg_datum = tuple_lvalue_datum.get_element(
+                    bcx,
                     *field_types.get(i),
                     |srcval| {
                         adt::trans_field_ptr(bcx, repr_ptr, srcval, 0, i)
index f0876442ff5ae950a6b8070cb4c7f6a49dcde498..05528d2b3d88e60876ff07de8f1d48cbe06e05bc 100644 (file)
@@ -74,6 +74,9 @@ pub fn type_is_immediate(ccx: &CrateContext, ty: ty::t) -> bool {
     if simple && !ty::type_is_fat_ptr(tcx, ty) {
         return true;
     }
+    if !ty::type_is_sized(tcx, ty) {
+        return false;
+    }
     match ty::get(ty).sty {
         ty::ty_bot => true,
         ty::ty_struct(..) | ty::ty_enum(..) | ty::ty_tup(..) |
index e65a10b3bb243f319ba4d1071a346ba97e76238d..b3798c9f84dd41ab6d2625f1b0864302e95b33dc 100644 (file)
@@ -116,7 +116,7 @@ fn const_vec(cx: &CrateContext, e: &ast::Expr,
     (v, llunitty, inlineable.iter().fold(true, |a, &b| a && b))
 }
 
-pub fn const_addr_of(cx: &CrateContext, cv: ValueRef) -> ValueRef {
+pub fn const_addr_of(cx: &CrateContext, cv: ValueRef, mutbl: ast::Mutability) -> ValueRef {
     unsafe {
         let gv = "const".with_c_str(|name| {
             llvm::LLVMAddGlobal(cx.llmod, val_ty(cv).to_ref(), name)
@@ -279,7 +279,7 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
                                         }
                                         _ => cx.sess().span_bug(e.span,
                                             format!("unimplemented type in const unsize: {}",
-                                                    ty_to_str(cx.tcx(), ty)).as_slice())
+                                                    ty_to_string(cx.tcx(), ty)).as_slice())
                                     }
                                 }
                                 _ => {
@@ -455,7 +455,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
                       _ => cx.sess().span_bug(base.span,
                                               format!("index-expr base must be a vector \
                                                        or string type, found {}",
-                                                      ty_to_str(cx.tcx(), bt)).as_slice())
+                                                      ty_to_string(cx.tcx(), bt)).as_slice())
                   },
                   ty::ty_rptr(_, mt) => match ty::get(mt.ty).sty {
                       ty::ty_vec(_, Some(u)) => {
@@ -464,12 +464,12 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
                       _ => cx.sess().span_bug(base.span,
                                               format!("index-expr base must be a vector \
                                                        or string type, found {}",
-                                                      ty_to_str(cx.tcx(), bt)).as_slice())
+                                                      ty_to_string(cx.tcx(), bt)).as_slice())
                   },
                   _ => cx.sess().span_bug(base.span,
                                           format!("index-expr base must be a vector \
                                                    or string type, found {}",
-                                                  ty_to_str(cx.tcx(), bt)).as_slice())
+                                                  ty_to_string(cx.tcx(), bt)).as_slice())
               };
 
               let len = llvm::LLVMConstIntGetZExtValue(len) as u64;
index 7a1864448e26be6cdc9aaa8b3fabfef321aa17d0..9ec52341348170f3a6e5cc5f07c3744444bea46e 100644 (file)
@@ -497,7 +497,7 @@ pub fn trans_fail<'a>(
     let filename = C_str_slice(ccx, filename);
     let line = C_int(ccx, loc.line as int);
     let expr_file_line_const = C_struct(ccx, &[v_str, filename, line], false);
-    let expr_file_line = consts::const_addr_of(ccx, expr_file_line_const);
+    let expr_file_line = consts::const_addr_of(ccx, expr_file_line_const, ast::MutImmutable);
     let args = vec!(expr_file_line);
     let did = langcall(bcx, Some(sp), "", FailFnLangItem);
     let bcx = callee::trans_lang_call(bcx,
@@ -525,7 +525,7 @@ pub fn trans_fail_bounds_check<'a>(
     let filename = C_str_slice(ccx,  filename);
     let line = C_int(ccx, loc.line as int);
     let file_line_const = C_struct(ccx, &[filename, line], false);
-    let file_line = consts::const_addr_of(ccx, file_line_const);
+    let file_line = consts::const_addr_of(ccx, file_line_const, ast::MutImmutable);
     let args = vec!(file_line, index, len);
     let did = langcall(bcx, Some(sp), "", FailBoundsCheckFnLangItem);
     let bcx = callee::trans_lang_call(bcx,
index b7803d404b5bc68b7f89161555f1727a6f756073..2882eaf10be2f0977f6ceb45cdc6ccf4186dec0e 100644 (file)
@@ -15,6 +15,7 @@
 
 use llvm::ValueRef;
 use middle::trans::base::*;
+use middle::trans::build::Load;
 use middle::trans::common::*;
 use middle::trans::cleanup;
 use middle::trans::cleanup::CleanupMethods;
@@ -119,10 +120,10 @@ pub fn lvalue_scratch_datum<'a, A>(bcx: &'a Block<'a>,
      * does not dominate the end of `scope`.
      */
 
-    let llty = type_of::type_of(bcx.ccx(), ty);
     let scratch = if zero {
-        alloca_zeroed(bcx, llty, name)
+        alloca_zeroed(bcx, ty, name)
     } else {
+        let llty = type_of::type_of(bcx.ccx(), ty);
         alloca(bcx, llty, name)
     };
 
@@ -524,7 +525,7 @@ pub fn get_element<'a>(&self,
             }
             _ => bcx.tcx().sess.bug(
                 format!("Unexpected unsized type in get_element: {}",
-                        bcx.ty_to_str(self.ty)).as_slice())
+                        bcx.ty_to_string(self.ty)).as_slice())
         };
         Datum {
             val: val,
index 31b31224464938d60141ca8caf46af9905258e1b..566f71220b05f50613d7bcc77dd931fd2501dbb7 100644 (file)
 ## Recursive Types
 
 Some kinds of types, such as structs and enums can be recursive. That means that
-the type definition of some type X refers to some other type which in turn (transitively)
-refers to X. This introduces cycles into the type referral graph. A naive algorithm doing
-an on-demand, depth-first traversal of this graph when describing types, can get trapped
-in an endless loop when it reaches such a cycle.
+the type definition of some type X refers to some other type which in turn
+(transitively) refers to X. This introduces cycles into the type referral graph.
+A naive algorithm doing an on-demand, depth-first traversal of this graph when
+describing types, can get trapped in an endless loop when it reaches such a
+cycle.
 
 For example, the following simple type for a singly-linked list...
 
@@ -2798,25 +2799,33 @@ fn subroutine_type_metadata(cx: &CrateContext,
         false);
 }
 
+// FIXME(1563) This is all a bit of a hack because 'trait pointer' is an ill-
+// defined concept. For the case of an actual trait pointer (i.e., Box<Trait>,
+// &Trait), trait_object_type should be the whole thing (e.g, Box<Trait>) and
+// trait_type should be the actual trait (e.g., Trait). Where the trait is part
+// of a DST struct, there is no trait_object_type and the results of this
+// function will be a little bit weird.
 fn trait_pointer_metadata(cx: &CrateContext,
-                          trait_object_type: ty::t,
+                          trait_type: ty::t,
+                          trait_object_type: Option<ty::t>,
                           unique_type_id: UniqueTypeId)
                        -> DIType {
     // The implementation provided here is a stub. It makes sure that the trait
     // type is assigned the correct name, size, namespace, and source location.
     // But it does not describe the trait's methods.
 
-    let def_id = match ty::get(trait_object_type).sty {
+    let def_id = match ty::get(trait_type).sty {
         ty::ty_trait(box ty::TyTrait { def_id, .. }) => def_id,
         _ => {
-            let pp_type_name = ppaux::ty_to_string(cx.tcx(), trait_object_type);
+            let pp_type_name = ppaux::ty_to_string(cx.tcx(), trait_type);
             cx.sess().bug(format!("debuginfo: Unexpected trait-object type in \
                                    trait_pointer_metadata(): {}",
                                    pp_type_name.as_slice()).as_slice());
         }
     };
 
-    let trait_pointer_type_name =
+    let trait_object_type = trait_object_type.unwrap_or(trait_type);
+    let trait_type_name =
         compute_debuginfo_type_name(cx, trait_object_type, false);
 
     let (containing_scope, _) = get_namespace_and_span_for_item(cx, def_id);
@@ -2824,8 +2833,8 @@ fn trait_pointer_metadata(cx: &CrateContext,
     let trait_llvm_type = type_of::type_of(cx, trait_object_type);
 
     composite_type_metadata(cx,
-                            trait_pointer_llvm_type,
-                            trait_pointer_type_name.as_slice(),
+                            trait_llvm_type,
+                            trait_type_name.as_slice(),
                             unique_type_id,
                             [],
                             containing_scope,
@@ -2897,7 +2906,7 @@ fn type_metadata(cx: &CrateContext,
         ty::ty_str => fixed_vec_metadata(cx, unique_type_id, ty::mk_i8(), 0, usage_site_span),
         ty::ty_trait(..) => {
             MetadataCreationResult::new(
-                        trait_pointer_metadata(cx, t, unique_type_id),
+                        trait_pointer_metadata(cx, t, None, unique_type_id),
             false)
         }
         ty::ty_uniq(ty) | ty::ty_ptr(ty::mt{ty, ..}) | ty::ty_rptr(_, ty::mt{ty, ..}) => {
@@ -2910,7 +2919,7 @@ fn type_metadata(cx: &CrateContext,
                 }
                 ty::ty_trait(..) => {
                     MetadataCreationResult::new(
-                        trait_pointer_metadata(cx, ty, unique_type_id),
+                        trait_pointer_metadata(cx, ty, Some(t), unique_type_id),
                         false)
                 }
                 _ => {
@@ -3698,7 +3707,7 @@ fn push_debuginfo_type_name(cx: &CrateContext,
 
             push_debuginfo_type_name(cx, inner_type, true, output);
         },
-        ty::ty_vec(ty::mt { ty: inner_type, .. }, optional_length) => {
+        ty::ty_vec(inner_type, optional_length) => {
             output.push_char('[');
             push_debuginfo_type_name(cx, inner_type, true, output);
 
@@ -3811,6 +3820,7 @@ fn push_debuginfo_type_name(cx: &CrateContext,
         }
         ty::ty_err      |
         ty::ty_infer(_) |
+        ty::ty_open(_) |
         ty::ty_param(_) => {
             cx.sess().bug(format!("debuginfo: Trying to create type name for \
                 unexpected type: {}", ppaux::ty_to_string(cx.tcx(), t)).as_slice());
index 657cd72c2554340c18d1e8208fe62770caecab82..5f9788d707ac5102ab7cfb0bd3349cdab1e9af6b 100644 (file)
@@ -71,7 +71,7 @@
 use util::common::indenter;
 use util::ppaux::Repr;
 use util::nodemap::NodeMap;
-use middle::trans::machine::{llalign_of_min, llsize_of, llsize_of_alloc};
+use middle::trans::machine::{llsize_of, llsize_of_alloc};
 use middle::trans::type_::Type;
 
 use syntax::ast;
@@ -202,8 +202,11 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>,
             };
 
             if autoderefs > 0 {
+                let lval = unpack_datum!(bcx,
+                                         datum.to_lvalue_datum(bcx, "auto_deref", expr.id));
+
                 datum = unpack_datum!(
-                    bcx, deref_multiple(bcx, expr, datum, autoderefs));
+                    bcx, deref_multiple(bcx, expr, lval.to_expr_datum(), autoderefs));
             }
 
             match adj.autoref {
@@ -266,35 +269,42 @@ fn ref_ptr<'a>(bcx: &'a Block<'a>,
                    -> DatumBlock<'a, Expr> {
         if !ty::type_is_sized(bcx.tcx(), datum.ty) {
             debug!("Taking address of unsized type {}",
-                   bcx.ty_to_str(datum.ty));
+                   bcx.ty_to_string(datum.ty));
             ref_fat_ptr(bcx, expr, datum)
         } else {
             debug!("Taking address of sized type {}",
-                   bcx.ty_to_str(datum.ty));
+                   bcx.ty_to_string(datum.ty));
             auto_ref(bcx, datum, expr)
         }
     }
 
     // Retrieve the information we are losing (making dynamic) in an unsizing
     // adjustment.
+    // When making a dtor, we need to do different things depending on the
+    // ownership of the object.. mk_ty is a function for turning unsized_type
+    // into a type to be destructed. If we want to end up with a Box pointer,
+    // then mk_ty should make a Box pointer (T -> Box<T>), if we want a
+    // borrowed reference then it should be T -> &T.
     fn unsized_info<'a>(bcx: &'a Block<'a>,
                         kind: &ty::UnsizeKind,
                         id: ast::NodeId,
-                        sized_ty: ty::t) -> ValueRef {
+                        unsized_ty: ty::t,
+                        mk_ty: |ty::t| -> ty::t) -> ValueRef {
         match kind {
             &ty::UnsizeLength(len) => C_uint(bcx.ccx(), len),
-            &ty::UnsizeStruct(box ref k, tp_index) => match ty::get(sized_ty).sty {
+            &ty::UnsizeStruct(box ref k, tp_index) => match ty::get(unsized_ty).sty {
                 ty::ty_struct(_, ref substs) => {
-                    let ty_substs = substs.types.get_vec(subst::TypeSpace);
-                    let sized_ty = ty_substs.get(tp_index);
-                    unsized_info(bcx, k, id, *sized_ty)
+                    let ty_substs = substs.types.get_slice(subst::TypeSpace);
+                    // The dtor for a field treats it like a value, so mk_ty
+                    // should just be the identity function.
+                    unsized_info(bcx, k, id, ty_substs[tp_index], |t| t)
                 }
                 _ => bcx.sess().bug(format!("UnsizeStruct with bad sty: {}",
-                                          bcx.ty_to_str(sized_ty)).as_slice())
+                                          bcx.ty_to_string(unsized_ty)).as_slice())
             },
             &ty::UnsizeVtable(..) =>
                 PointerCast(bcx,
-                            meth::vtable_ptr(bcx, id, sized_ty),
+                            meth::vtable_ptr(bcx, id, mk_ty(unsized_ty)),
                             Type::vtable_ptr(bcx.ccx()))
         }
     }
@@ -320,7 +330,16 @@ fn unsize_expr<'a>(bcx: &'a Block<'a>,
             &ty::UnsizeVtable(..) =>
                 |_bcx, val| PointerCast(bcx, val, Type::i8p(bcx.ccx()))
         };
-        let info = |bcx, _val| unsized_info(bcx, k, expr.id, datum_ty);
+        let info = |bcx, _val| unsized_info(bcx,
+                                            k,
+                                            expr.id,
+                                            ty::deref_or_dont(datum_ty),
+                                            |t| ty::mk_rptr(tcx,
+                                                            ty::ReStatic,
+                                                            ty::mt{
+                                                                ty: t,
+                                                                mutbl: ast::MutImmutable
+                                                            }));
         into_fat_ptr(bcx, expr, datum, dest_ty, base, info)
     }
 
@@ -415,21 +434,26 @@ fn unsize_unique_expr<'a>(bcx: &'a Block<'a>,
         let unboxed_ty = match ty::get(datum_ty).sty {
             ty::ty_uniq(t) => t,
             _ => bcx.sess().bug(format!("Expected ty_uniq, found {}",
-                                        bcx.ty_to_str(datum_ty)).as_slice())
+                                        bcx.ty_to_string(datum_ty)).as_slice())
         };
         let result_ty = ty::mk_uniq(tcx, ty::unsize_ty(tcx, unboxed_ty, k, expr.span));
 
         let lval = unpack_datum!(bcx,
                                  datum.to_lvalue_datum(bcx, "unsize_unique_expr", expr.id));
 
-        let scratch = rvalue_scratch_datum(bcx, result_ty, "__fat_ptr");
+        let scratch = rvalue_scratch_datum(bcx, result_ty, "__uniq_fat_ptr");
         let llbox_ty = type_of::type_of(bcx.ccx(), datum_ty);
         let base = PointerCast(bcx, get_dataptr(bcx, scratch.val), llbox_ty.ptr_to());
         bcx = lval.store_to(bcx, base);
 
-        let info = unsized_info(bcx, k, expr.id, unboxed_ty);
+        let info = unsized_info(bcx, k, expr.id, unboxed_ty, |t| ty::mk_uniq(tcx, t));
         Store(bcx, info, get_len(bcx, scratch.val));
 
+        let scratch = unpack_datum!(bcx,
+                                    scratch.to_expr_datum().to_lvalue_datum(bcx,
+                                                                            "fresh_uniq_fat_ptr",
+                                                                            expr.id));
+
         DatumBlock::new(bcx, scratch.to_expr_datum())
     }
 
@@ -550,8 +574,8 @@ fn trans_datum_unadjusted<'a>(bcx: &'a Block<'a>,
         ast::ExprField(ref base, ident, _) => {
             trans_rec_field(bcx, &**base, ident.node)
         }
-        ast::ExprIndex(base, idx) => {
-            trans_index(bcx, expr.span, &**base, &**idx, MethodCall::expr(expr.id))
+        ast::ExprIndex(ref base, ref idx) => {
+            trans_index(bcx, expr, &**base, &**idx, MethodCall::expr(expr.id))
         }
         ast::ExprBox(_, ref contents) => {
             // Special case for `Box<T>` and `Gc<T>`
@@ -559,18 +583,24 @@ fn trans_datum_unadjusted<'a>(bcx: &'a Block<'a>,
             let contents_ty = expr_ty(bcx, &**contents);
             match ty::get(box_ty).sty {
                 ty::ty_uniq(..) => {
-                    match contents.node {
-                        ast::ExprRepeat(..) | ast::ExprVec(..) => {
-                            // Special case for owned vectors.
-                            fcx.push_ast_cleanup_scope(contents.id);
-                            let datum = unpack_datum!(
-                                bcx, tvec::trans_uniq_vec(bcx, expr, &**contents));
-                            bcx = fcx.pop_and_trans_ast_cleanup_scope(bcx, contents.id);
-                            DatumBlock::new(bcx, datum)
-                        }
-                        _ => {
-                            trans_uniq_expr(bcx, box_ty, &**contents, contents_ty)
-                        }
+                    let is_vec = match contents.node {
+                        ast::ExprRepeat(..) | ast::ExprVec(..) => true,
+                        ast::ExprLit(lit) => match lit.node {
+                            ast::LitStr(..) => true,
+                            _ => false
+                        },
+                        _ => false
+                    };
+
+                    if is_vec {
+                        // Special case for owned vectors.
+                        fcx.push_ast_cleanup_scope(contents.id);
+                        let datum = unpack_datum!(
+                            bcx, tvec::trans_uniq_vec(bcx, expr, &**contents));
+                        bcx = fcx.pop_and_trans_ast_cleanup_scope(bcx, contents.id);
+                        DatumBlock::new(bcx, datum)
+                    } else {
+                        trans_uniq_expr(bcx, box_ty, &**contents, contents_ty)
                     }
                 }
                 ty::ty_box(..) => {
@@ -639,7 +669,6 @@ fn trans_rec_field<'a>(bcx: &'a Block<'a>,
         if ty::type_is_sized(bcx.tcx(), d.ty) {
             DatumBlock { datum: d.to_expr_datum(), bcx: bcx }
         } else {
-            debug!("nrc: {}", bcx.ty_to_str(d.ty))
             let scratch = rvalue_scratch_datum(bcx, ty::mk_open(bcx.tcx(), d.ty), "");
             Store(bcx, d.val, get_dataptr(bcx, scratch.val));
             let info = Load(bcx, get_len(bcx, base_datum.val));
@@ -652,7 +681,7 @@ fn trans_rec_field<'a>(bcx: &'a Block<'a>,
 }
 
 fn trans_index<'a>(bcx: &'a Block<'a>,
-                   sp: codemap::Span,
+                   index_expr: &ast::Expr,
                    base: &ast::Expr,
                    idx: &ast::Expr,
                    method_call: MethodCall)
@@ -1326,7 +1355,8 @@ pub fn trans_adt<'a>(mut bcx: &'a Block<'a>,
                 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(
-                            t, |srcval| adt::trans_field_ptr(bcx, &*repr, srcval, discr, i));
+                            bcx, t, |srcval| adt::trans_field_ptr(bcx, &*repr, srcval, discr, i));
+                    assert!(ty::type_is_sized(bcx.tcx(), datum.ty));
                     let dest = adt::trans_field_ptr(bcx, &*repr, addr, discr, i);
                     bcx = datum.store_to(bcx, dest);
                 }
@@ -1348,21 +1378,6 @@ pub fn trans_adt<'a>(mut bcx: &'a Block<'a>,
         fcx.schedule_drop_mem(scope, dest, e_ty);
     }
 
-    for base in optbase.iter() {
-        // FIXME #6573: is it sound to use the destination's repr on the base?
-        // And, would it ever be reasonable to be here with discr != 0?
-        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(
-                bcx,
-                t,
-                |srcval| adt::trans_field_ptr(bcx, repr, srcval, discr, i));
-            assert!(ty::type_is_sized(bcx.tcx(), datum.ty));
-            let dest = adt::trans_field_ptr(bcx, repr, addr, discr, i);
-            bcx = datum.store_to(bcx, dest);
-        }
-    }
-
     adt::trans_set_discr(bcx, &*repr, addr, discr);
 
     fcx.pop_custom_cleanup_scope(custom_cleanup_scope);
@@ -1448,9 +1463,10 @@ fn trans_uniq_expr<'a>(bcx: &'a Block<'a>,
                         -> DatumBlock<'a, Expr> {
     let _icx = push_ctxt("trans_uniq_expr");
     let fcx = bcx.fcx;
+    assert!(ty::type_is_sized(bcx.tcx(), contents_ty));
     let llty = type_of::type_of(bcx.ccx(), contents_ty);
     let size = llsize_of(bcx.ccx(), llty);
-    let align = C_uint(bcx.ccx(), llalign_of_min(bcx.ccx(), llty) as uint);
+    let align = C_uint(bcx.ccx(), type_of::align_of(bcx.ccx(), contents_ty) as uint);
     let llty_ptr = llty.ptr_to();
     let Result { bcx, val } = malloc_raw_dyn(bcx, llty_ptr, box_ty, size, align);
     // Unique boxes do not allocate for zero-size types. The standard library
@@ -1499,7 +1515,7 @@ fn trans_addr_of<'a>(bcx: &'a Block<'a>,
     match ty::get(sub_datum.ty).sty {
         ty::ty_open(_) => {
             // Opened DST value, close to a fat pointer
-            debug!("Closing fat pointer {}", bcx.ty_to_str(sub_datum.ty));
+            debug!("Closing fat pointer {}", bcx.ty_to_string(sub_datum.ty));
 
             let scratch = rvalue_scratch_datum(bcx,
                                                ty::close_type(bcx.tcx(), sub_datum.ty),
index 2994378f91caf15476946ca5ff8f37e897f191d7..56841cd4044b626d297a7197e5911ebed55bb14b 100644 (file)
@@ -19,6 +19,7 @@
 use llvm;
 use middle::lang_items::{FreeFnLangItem, ExchangeFreeFnLangItem};
 use middle::subst;
+use middle::subst::Subst;
 use middle::trans::adt;
 use middle::trans::base::*;
 use middle::trans::build::*;
 use middle::trans::cleanup;
 use middle::trans::cleanup::CleanupMethods;
 use middle::trans::common::*;
+use middle::trans::datum;
 use middle::trans::expr;
 use middle::trans::machine::*;
 use middle::trans::reflect;
 use middle::trans::tvec;
 use middle::trans::type_::Type;
-use middle::trans::type_of::{type_of, sizing_type_of};
+use middle::trans::type_of::{type_of, sizing_type_of, align_of};
 use middle::ty;
 use util::ppaux::ty_to_short_str;
 use util::ppaux;
@@ -51,24 +53,33 @@ pub fn trans_free<'a>(cx: &'a Block<'a>, v: ValueRef) -> &'a Block<'a> {
         Some(expr::Ignore)).bcx
 }
 
-pub fn trans_exchange_free<'a>(cx: &'a Block<'a>, v: ValueRef, size: u64,
-                               align: u64) -> &'a Block<'a> {
+fn trans_exchange_free_internal<'a>(cx: &'a Block<'a>, v: ValueRef, size: ValueRef,
+                               align: ValueRef) -> &'a Block<'a> {
     let _icx = push_ctxt("trans_exchange_free");
     let ccx = cx.ccx();
     callee::trans_lang_call(cx,
         langcall(cx, None, "", ExchangeFreeFnLangItem),
-        [PointerCast(cx, v, Type::i8p(ccx)), C_uint(ccx, size as uint), C_uint(ccx, align as uint)],
+        [PointerCast(cx, v, Type::i8p(ccx)), size, align],
         Some(expr::Ignore)).bcx
 }
 
+pub fn trans_exchange_free<'a>(cx: &'a Block<'a>, v: ValueRef, size: u64,
+                               align: u64) -> &'a Block<'a> {
+    trans_exchange_free_internal(cx,
+                                 v,
+                                 C_uint(cx.ccx(), size as uint),
+                                 C_uint(cx.ccx(), align as uint))
+}
+
 pub fn trans_exchange_free_ty<'a>(bcx: &'a Block<'a>, ptr: ValueRef,
                                   content_ty: ty::t) -> &'a Block<'a> {
+    assert!(ty::type_is_sized(bcx.ccx().tcx(), content_ty));
     let sizing_type = sizing_type_of(bcx.ccx(), content_ty);
     let content_size = llsize_of_alloc(bcx.ccx(), sizing_type);
 
     // `Box<ZeroSizeType>` does not allocate.
     if content_size != 0 {
-        let content_align = llalign_of_min(bcx.ccx(), sizing_type);
+        let content_align = align_of(bcx.ccx(), content_ty);
         trans_exchange_free(bcx, ptr, content_size, content_align)
     } else {
         bcx
@@ -91,6 +102,11 @@ pub fn take_ty<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
 
 pub fn get_drop_glue_type(ccx: &CrateContext, t: ty::t) -> ty::t {
     let tcx = ccx.tcx();
+    // Even if there is no dtor for t, there might be one deeper down and we
+    // might need to pass in the vtable ptr.
+    if !ty::type_is_sized(tcx, t) {
+        return t
+    }
     if !ty::type_needs_drop(tcx, t) {
         return ty::mk_i8();
     }
@@ -139,13 +155,21 @@ pub fn drop_ty_immediate<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
 }
 
 pub fn get_drop_glue(ccx: &CrateContext, t: ty::t) -> ValueRef {
+    debug!("make drop glue for {}", ppaux::ty_to_string(ccx.tcx(), t));
     let t = get_drop_glue_type(ccx, t);
+    debug!("drop glue type {}", ppaux::ty_to_string(ccx.tcx(), t));
     match ccx.drop_glues.borrow().find(&t) {
         Some(&glue) => return glue,
         _ => { }
     }
 
-    let llfnty = Type::glue_fn(ccx, type_of(ccx, t).ptr_to());
+    let llty = if ty::type_is_sized(ccx.tcx(), t) {
+        type_of(ccx, t).ptr_to()
+    } else {
+        type_of(ccx, ty::mk_uniq(ccx.tcx(), t)).ptr_to()
+    };
+
+    let llfnty = Type::glue_fn(ccx, llty);
     let glue = declare_generic_glue(ccx, t, llfnty, "drop");
 
     ccx.drop_glues.borrow_mut().insert(t, glue);
@@ -208,7 +232,13 @@ fn trans_struct_drop_flag<'a>(mut bcx: &'a Block<'a>,
                               substs: &subst::Substs)
                               -> &'a Block<'a> {
     let repr = adt::represent_type(bcx.ccx(), t);
-    let drop_flag = unpack_datum!(bcx, adt::trans_drop_flag_ptr(bcx, &*repr, v0));
+    let struct_data = if ty::type_is_sized(bcx.tcx(), t) {
+        v0
+    } else {
+        let llval = GEPi(bcx, v0, [0, abi::slice_elt_base]);
+        Load(bcx, llval)
+    };
+    let drop_flag = unpack_datum!(bcx, adt::trans_drop_flag_ptr(bcx, &*repr, struct_data));
     with_cond(bcx, load_ty(bcx, drop_flag.val, ty::mk_bool()), |cx| {
         trans_struct_drop(cx, t, v0, dtor_did, class_did, substs)
     })
@@ -227,13 +257,31 @@ fn trans_struct_drop<'a>(bcx: &'a Block<'a>,
     let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did, t,
                                  class_did, substs);
 
-    // The second argument is the "self" argument for drop
+    // The first argument is the "self" argument for drop
     let params = unsafe {
         let ty = Type::from_ref(llvm::LLVMTypeOf(dtor_addr));
         ty.element_type().func_params()
     };
 
-    adt::fold_variants(bcx, &*repr, v0, |variant_cx, st, value| {
+    let fty = ty::lookup_item_type(bcx.tcx(), dtor_did).ty.subst(bcx.tcx(), substs);
+    let self_ty = match ty::get(fty).sty {
+        ty::ty_bare_fn(ref f) => {
+            assert!(f.sig.inputs.len() == 1);
+            f.sig.inputs[0]
+        }
+        _ => bcx.sess().bug(format!("Expected function type, found {}",
+                                    bcx.ty_to_string(fty)).as_slice())
+    };
+
+    let (struct_data, info) = if ty::type_is_sized(bcx.tcx(), t) {
+        (v0, None)
+    } else {
+        let data = GEPi(bcx, v0, [0, abi::slice_elt_base]);
+        let info = GEPi(bcx, v0, [0, abi::slice_elt_len]);
+        (Load(bcx, data), Some(Load(bcx, info)))
+    };
+
+    adt::fold_variants(bcx, &*repr, struct_data, |variant_cx, st, value| {
         // Be sure to put all of the fields into a scope so we can use an invoke
         // instruction to call the user destructor but still call the field
         // destructors if the user destructor fails.
@@ -242,7 +290,22 @@ fn trans_struct_drop<'a>(bcx: &'a Block<'a>,
         // Class dtors have no explicit args, so the params should
         // just consist of the environment (self).
         assert_eq!(params.len(), 1);
-        let self_arg = PointerCast(variant_cx, value, *params.get(0));
+        let self_arg = if ty::type_is_fat_ptr(bcx.tcx(), self_ty) {
+            // The dtor expects a fat pointer, so make one, even if we have to fake it.
+            let boxed_ty = ty::mk_open(bcx.tcx(), t);
+            let scratch = datum::rvalue_scratch_datum(bcx, boxed_ty, "__fat_ptr_drop_self");
+            Store(bcx, value, GEPi(bcx, scratch.val, [0, abi::slice_elt_base]));
+            Store(bcx,
+                  // If we just had a thin pointer, make a fat pointer by sticking
+                  // null where we put the unsizing info. This works because t
+                  // is a sized type, so we will only unpack the fat pointer, never
+                  // use the fake info.
+                  info.unwrap_or(C_null(Type::i8p(bcx.ccx()))),
+                  GEPi(bcx, scratch.val, [0, abi::slice_elt_len]));
+            PointerCast(variant_cx, scratch.val, *params.get(0))
+        } else {
+            PointerCast(variant_cx, value, *params.get(0))
+        };
         let args = vec!(self_arg);
 
         // Add all the fields as a value which needs to be cleaned at the end of
@@ -250,19 +313,84 @@ fn trans_struct_drop<'a>(bcx: &'a Block<'a>,
         // the order in which fields get dropped.
         for (i, ty) in st.fields.iter().enumerate().rev() {
             let llfld_a = adt::struct_field_ptr(variant_cx, &*st, value, i, false);
+
+            let val = if ty::type_is_sized(bcx.tcx(), *ty) {
+                llfld_a
+            } else {
+                let boxed_ty = ty::mk_open(bcx.tcx(), *ty);
+                let scratch = datum::rvalue_scratch_datum(bcx, boxed_ty, "__fat_ptr_drop_field");
+                Store(bcx, llfld_a, GEPi(bcx, scratch.val, [0, abi::slice_elt_base]));
+                Store(bcx, info.unwrap(), GEPi(bcx, scratch.val, [0, abi::slice_elt_len]));
+                scratch.val
+            };
             variant_cx.fcx.schedule_drop_mem(cleanup::CustomScope(field_scope),
-                                             llfld_a, *ty);
+                                             val, *ty);
         }
 
         let dtor_ty = ty::mk_ctor_fn(variant_cx.tcx(), ast::DUMMY_NODE_ID,
                                      [get_drop_glue_type(bcx.ccx(), t)], ty::mk_nil());
-        let (_, variant_cx) = invoke(variant_cx, dtor_addr, args, dtor_ty, None);
+        let (_, variant_cx) = invoke(variant_cx, dtor_addr, args, dtor_ty, None, false);
 
         variant_cx.fcx.pop_and_trans_custom_cleanup_scope(variant_cx, field_scope);
         variant_cx
     })
 }
 
+fn size_and_align_of_dst<'a>(bcx: &'a Block<'a>, t :ty::t, info: ValueRef) -> (ValueRef, ValueRef) {
+    debug!("calculate size of DST: {}; with lost info: {}",
+           bcx.ty_to_string(t), bcx.val_to_string(info));
+    if ty::type_is_sized(bcx.tcx(), t) {
+        let sizing_type = sizing_type_of(bcx.ccx(), t);
+        let size = C_uint(bcx.ccx(), llsize_of_alloc(bcx.ccx(), sizing_type) as uint);
+        let align = C_uint(bcx.ccx(), align_of(bcx.ccx(), t) as uint);
+        return (size, align);
+    }
+    match ty::get(t).sty {
+        ty::ty_struct(id, ref substs) => {
+            let ccx = bcx.ccx();
+            // First get the size of all statically known fields.
+            // Don't use type_of::sizing_type_of because that expects t to be sized.
+            assert!(!ty::type_is_simd(bcx.tcx(), t));
+            let repr = adt::represent_type(ccx, t);
+            let sizing_type = adt::sizing_type_of(ccx, &*repr, true);
+            let sized_size = C_uint(ccx, llsize_of_alloc(ccx, sizing_type) as uint);
+            let sized_align = C_uint(ccx, llalign_of_min(ccx, sizing_type) as uint);
+
+            // Recurse to get the size of the dynamically sized field (must be
+            // the last field).
+            let fields = ty::struct_fields(bcx.tcx(), id, substs);
+            let last_field = fields[fields.len()-1];
+            let field_ty = last_field.mt.ty;
+            let (unsized_size, unsized_align) = size_and_align_of_dst(bcx, field_ty, info);
+
+            // Return the sum of sizes and max of aligns.
+            let size = Add(bcx, sized_size, unsized_size);
+            let align = Select(bcx,
+                               ICmp(bcx, llvm::IntULT, sized_align, unsized_align),
+                               sized_align,
+                               unsized_align);
+            (size, align)
+        }
+        ty::ty_trait(..) => {
+            // info points to the vtable and the second entry in the vtable is the
+            // dynamic size of the object.
+            let info = PointerCast(bcx, info, Type::int(bcx.ccx()).ptr_to());
+            let size_ptr = GEPi(bcx, info, [1u]);
+            let align_ptr = GEPi(bcx, info, [2u]);
+            (Load(bcx, size_ptr), Load(bcx, align_ptr))
+        }
+        ty::ty_vec(unit_ty, None) => {
+            // The info in this case is the length of the vec, so the size is that
+            // times the unit size.
+            let llunit_ty = sizing_type_of(bcx.ccx(), unit_ty);
+            let unit_size = llsize_of_alloc(bcx.ccx(), llunit_ty);
+            (Mul(bcx, info, C_uint(bcx.ccx(), unit_size as uint)), C_uint(bcx.ccx(), 8))
+        }
+        _ => bcx.sess().bug(format!("Unexpected unsized type, found {}",
+                                    bcx.ty_to_string(t)).as_slice())
+    }
+}
+
 fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'a> {
     // NB: v0 is an *alias* of type t here, not a direct value.
     let _icx = push_ctxt("make_drop_glue");
@@ -282,7 +410,8 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
                 ty::ty_trait(..) => {
                     let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]);
                     // Only drop the value when it is non-null
-                    with_cond(bcx, IsNotNull(bcx, Load(bcx, lluniquevalue)), |bcx| {
+                    let concrete_ptr = Load(bcx, lluniquevalue);
+                    with_cond(bcx, IsNotNull(bcx, concrete_ptr), |bcx| {
                         let dtor_ptr = Load(bcx, GEPi(bcx, v0, [0, abi::trt_field_vtable]));
                         let dtor = Load(bcx, dtor_ptr);
                         Call(bcx,
@@ -292,13 +421,21 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
                         bcx
                     })
                 }
+                ty::ty_struct(..) if !ty::type_is_sized(bcx.tcx(), content_ty) => {
+                    let llval = GEPi(bcx, v0, [0, abi::slice_elt_base]);
+                    let llbox = Load(bcx, llval);
+                    let not_null = IsNotNull(bcx, llbox);
+                    with_cond(bcx, not_null, |bcx| {
+                        let bcx = drop_ty(bcx, v0, content_ty);
+                        let info = GEPi(bcx, v0, [0, abi::slice_elt_len]);
+                        let info = Load(bcx, info);
+                        let (llsize, llalign) = size_and_align_of_dst(bcx, content_ty, info);
+                        trans_exchange_free_internal(bcx, llbox, llsize, llalign)
+                    })
+                }
                 _ => {
-                    let llval = if ty::type_is_sized(bcx.tcx(), content_ty) {
-                        v0
-                    } else {
-                        // The Box is a fat pointer
-                        GEPi(bcx, v0, [0, abi::trt_field_box])
-                    };
+                    assert!(ty::type_is_sized(bcx.tcx(), content_ty));
+                    let llval = v0;
                     let llbox = Load(bcx, llval);
                     let not_null = IsNotNull(bcx, llbox);
                     with_cond(bcx, not_null, |bcx| {
@@ -312,7 +449,21 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
             let tcx = bcx.tcx();
             match ty::ty_dtor(tcx, did) {
                 ty::TraitDtor(dtor, true) => {
-                    trans_struct_drop_flag(bcx, t, v0, dtor, did, substs)
+                    // FIXME(16758) Since the struct is unsized, it is hard to
+                    // find the drop flag (which is at the end of the struct).
+                    // Lets just ignore the flag and pretend everything will be
+                    // OK.
+                    if ty::type_is_sized(bcx.tcx(), t) {
+                        trans_struct_drop_flag(bcx, t, v0, dtor, did, substs)
+                    } else {
+                        // Give the user a heads up that we are doing something
+                        // stupid and dangerous.
+                        bcx.sess().warn(format!("Ignoring drop flag in destructor for {}\
+                                                 because the struct is unsized. See issue\
+                                                 #16758",
+                                                bcx.ty_to_string(t)).as_slice());
+                        trans_struct_drop(bcx, t, v0, dtor, did, substs)
+                    }
                 }
                 ty::TraitDtor(dtor, false) => {
                     trans_struct_drop(bcx, t, v0, dtor, did, substs)
@@ -340,7 +491,23 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
                 trans_exchange_free(bcx, env, 0, 8)
             })
         }
+        ty::ty_trait(..) => {
+            // No need to do a null check here (as opposed to the Box<trait case
+            // above), because this happens for a trait field in an unsized
+            // struct. If anything is null, it is the whole struct and we won't
+            // get here.
+            let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]);
+            let dtor_ptr = Load(bcx, GEPi(bcx, v0, [0, abi::trt_field_vtable]));
+            let dtor = Load(bcx, dtor_ptr);
+            Call(bcx,
+                 dtor,
+                 [PointerCast(bcx, Load(bcx, lluniquevalue), Type::i8p(bcx.ccx()))],
+                 None);
+            bcx
+        }
+        ty::ty_vec(ty, None) => tvec::make_drop_glue_unboxed(bcx, v0, ty),
         _ => {
+            assert!(ty::type_is_sized(bcx.tcx(), t));
             if ty::type_needs_drop(bcx.tcx(), t) &&
                 ty::type_is_structural(t) {
                 iter_structural_ty(bcx, v0, t, drop_ty)
@@ -439,7 +606,6 @@ fn declare_generic_glue(ccx: &CrateContext, t: ty::t, llfnty: Type,
         ccx,
         t,
         format!("glue_{}", name).as_slice());
-    debug!("{} is for type {}", fn_nm, ppaux::ty_to_string(ccx.tcx(), t));
     let llfn = decl_cdecl_fn(ccx, fn_nm.as_slice(), llfnty, ty::mk_nil());
     note_unique_llvm_symbol(ccx, fn_nm);
     return llfn;
index 359c8d24f72705c6ef0aa6098400c5680d8d3a38..7d8e4679ae302d2ff4f3e412c93d92a89dfc9c82 100644 (file)
@@ -119,6 +119,17 @@ pub fn check_intrinsics(ccx: &CrateContext) {
                             "s"
                         }).as_slice());
         }
+        if ty::type_is_fat_ptr(ccx.tcx(), transmute_restriction.to) ||
+           ty::type_is_fat_ptr(ccx.tcx(), transmute_restriction.from) {
+            ccx.sess()
+               .add_lint(::lint::builtin::TRANSMUTE_FAT_PTR,
+                         transmute_restriction.id,
+                         transmute_restriction.span,
+                         format!("Transmuting fat pointer types; {} to {}.\
+                                  Beware of relying on the compiler's representation",
+                                 ty_to_string(ccx.tcx(), transmute_restriction.from),
+                                 ty_to_string(ccx.tcx(), transmute_restriction.to)));
+        }
     }
     ccx.sess().abort_if_errors();
 }
@@ -227,8 +238,7 @@ pub fn trans_intrinsic_call<'a>(mut bcx: &'a Block<'a>, node: ast::NodeId,
         }
         (_, "min_align_of") => {
             let tp_ty = *substs.types.get(FnSpace, 0);
-            let lltp_ty = type_of::type_of(ccx, tp_ty);
-            C_uint(ccx, machine::llalign_of_min(ccx, lltp_ty) as uint)
+            C_uint(ccx, type_of::align_of(ccx, tp_ty) as uint)
         }
         (_, "pref_align_of") => {
             let tp_ty = *substs.types.get(FnSpace, 0);
@@ -542,7 +552,7 @@ fn copy_intrinsic(bcx: &Block, allow_overlap: bool, volatile: bool,
                   tp_ty: ty::t, dst: ValueRef, src: ValueRef, count: ValueRef) -> ValueRef {
     let ccx = bcx.ccx();
     let lltp_ty = type_of::type_of(ccx, tp_ty);
-    let align = C_i32(ccx, machine::llalign_of_min(ccx, lltp_ty) as i32);
+    let align = C_i32(ccx, type_of::align_of(ccx, tp_ty) as i32);
     let size = machine::llsize_of(ccx, lltp_ty);
     let int_size = machine::llbitsize_of_real(ccx, ccx.int_type);
     let name = if allow_overlap {
@@ -571,7 +581,7 @@ fn memset_intrinsic(bcx: &Block, volatile: bool, tp_ty: ty::t,
                     dst: ValueRef, val: ValueRef, count: ValueRef) -> ValueRef {
     let ccx = bcx.ccx();
     let lltp_ty = type_of::type_of(ccx, tp_ty);
-    let align = C_i32(ccx, machine::llalign_of_min(ccx, lltp_ty) as i32);
+    let align = C_i32(ccx, type_of::align_of(ccx, tp_ty) as i32);
     let size = machine::llsize_of(ccx, lltp_ty);
     let name = if machine::llbitsize_of_real(ccx, ccx.int_type) == 32 {
         "llvm.memset.p0i8.i32"
index 3dc0904041911806616ea7a33c2a2ffc79c591af..83bdcc9dead6473d6120dd07d6982a5ac914e239 100644 (file)
@@ -25,6 +25,7 @@
 use middle::trans::expr::{SaveIn, Ignore};
 use middle::trans::expr;
 use middle::trans::glue;
+use middle::trans::machine;
 use middle::trans::monomorphize;
 use middle::trans::type_::Type;
 use middle::trans::type_of::*;
@@ -40,6 +41,9 @@
 use syntax::{ast, ast_map, visit};
 use syntax::ast_util::PostExpansionMethod;
 
+// drop_glue pointer, size, align.
+static VTABLE_OFFSET: uint = 3;
+
 /**
 The main "translation" pass for methods.  Generates code
 for non-monomorphized methods only.  Other methods will
@@ -450,7 +454,7 @@ pub fn trans_trait_callee_from_llval<'a>(bcx: &'a Block<'a>,
                                     GEPi(bcx, llpair,
                                          [0u, abi::trt_field_vtable]),
                                     Type::vtable(ccx).ptr_to().ptr_to()));
-    let mptr = Load(bcx, GEPi(bcx, llvtable, [0u, n_method + 1]));
+    let mptr = Load(bcx, GEPi(bcx, llvtable, [0u, n_method + VTABLE_OFFSET]));
     let mptr = PointerCast(bcx, mptr, llcallee_ty.ptr_to());
 
     return Callee {
@@ -580,9 +584,15 @@ fn get_vtable(bcx: &Block,
         }
     });
 
+    let size_ty = sizing_type_of(ccx, self_ty);
+    let size = machine::llsize_of_alloc(ccx, size_ty);
+    let ll_size = C_uint(ccx, size as uint);
+    let align = align_of(ccx, self_ty);
+    let ll_align = C_uint(ccx, align as uint);
+
     // Generate a destructor for the vtable.
     let drop_glue = glue::get_drop_glue(ccx, self_ty);
-    let vtable = make_vtable(ccx, drop_glue, methods);
+    let vtable = make_vtable(ccx, drop_glue, ll_size, ll_align, methods);
 
     ccx.vtables.borrow_mut().insert(hash_id, vtable);
     vtable
@@ -591,11 +601,14 @@ fn get_vtable(bcx: &Block,
 /// Helper function to declare and initialize the vtable.
 pub fn make_vtable<I: Iterator<ValueRef>>(ccx: &CrateContext,
                                           drop_glue: ValueRef,
+                                          size: ValueRef,
+                                          align: ValueRef,
                                           ptrs: I)
                                           -> ValueRef {
     let _icx = push_ctxt("meth::make_vtable");
 
-    let components: Vec<_> = Some(drop_glue).move_iter().chain(ptrs).collect();
+    let head = vec![drop_glue, size, align];
+    let components: Vec<_> = head.move_iter().chain(ptrs).collect();
 
     unsafe {
         let tbl = C_struct(ccx, components.as_slice(), false);
index 7b6d3430ae0dcb9a2b4f726a4770f06ddeec1e18..11c641f2d75a245b8eda0762145972cf24850405 100644 (file)
@@ -66,7 +66,7 @@ pub fn c_slice(&mut self, s: InternedString) -> ValueRef {
     pub fn c_size_and_align(&mut self, t: ty::t) -> Vec<ValueRef> {
         let tr = type_of(self.bcx.ccx(), t);
         let s = machine::llsize_of_real(self.bcx.ccx(), tr);
-        let a = machine::llalign_of_min(self.bcx.ccx(), tr);
+        let a = align_of(self.bcx.ccx(), t);
         return vec!(self.c_uint(s as uint),
              self.c_uint(a as uint));
     }
@@ -94,7 +94,7 @@ pub fn visit(&mut self, ty_name: &str, args: &[ValueRef]) {
             ty::MethodTraitItem(ref method) => (*method).clone(),
         };
         let mth_ty = ty::mk_bare_fn(tcx, method.fty.clone());
-        debug!("Emit call visit method: visit_{}: {}", ty_name, ty_to_str(tcx, mth_ty));
+        debug!("Emit call visit method: visit_{}: {}", ty_name, ty_to_string(tcx, mth_ty));
         let v = self.visitor_val;
         debug!("passing {} args:", args.len());
         let mut bcx = self.bcx;
@@ -154,8 +154,11 @@ pub fn visit_ty(&mut self, t: ty::t) {
               // Unfortunately we can't do anything here because at runtime we
               // pass around the value by pointer (*u8). But unsized pointers are
               // fat and so we can't just cast them to *u8 and back. So we have
-              // to work with the pointer directly (see ty_rptr/ty_uniq). See
-              // ty_struct for where this causes issues.
+              // to work with the pointer directly (see ty_rptr/ty_uniq).
+              fail!("Can't reflect unsized type")
+          }
+          // FIXME(15049) Reflection for unsized structs.
+          ty::ty_struct(..) if !ty::type_is_sized(bcx.tcx(), t) => {
               fail!("Can't reflect unsized type")
           }
 
@@ -278,12 +281,7 @@ pub fn visit_ty(&mut self, t: ty::t) {
               // because we cannot reflect unsized types (see note above). We
               // just pretend the unsized field does not exist and print nothing.
               // This is sub-optimal.
-              let len = if ty::type_is_sized(tcx, t) {
-                  fields.len()
-              } else {
-                  assert!(fields.len() > 0);
-                  fields.len() - 1
-              };
+              let len = fields.len();
 
               let extra = (vec!(
                   self.c_slice(
@@ -294,14 +292,12 @@ pub fn visit_ty(&mut self, t: ty::t) {
               )).append(self.c_size_and_align(t).as_slice());
               self.bracketed("class", extra.as_slice(), |this| {
                   for (i, field) in fields.iter().enumerate() {
-                      if ty::type_is_sized(tcx, field.mt.ty) {
-                          let extra = (vec!(
-                            this.c_uint(i),
-                            this.c_slice(token::get_ident(field.ident)),
-                            this.c_bool(named_fields)
-                          )).append(this.c_mt(&field.mt).as_slice());
-                          this.visit("class_field", extra.as_slice());
-                      }
+                      let extra = (vec!(
+                        this.c_uint(i),
+                        this.c_slice(token::get_ident(field.ident)),
+                        this.c_bool(named_fields)
+                      )).append(this.c_mt(&field.mt).as_slice());
+                      this.visit("class_field", extra.as_slice());
                   }
               })
           }
index 0ec18977139ed59411627f2692866f40919fc4a7..94ca520c533f9348e8c05e6944a3dea95bccf83e 100644 (file)
@@ -17,6 +17,7 @@
 use middle::trans::base::*;
 use middle::trans::base;
 use middle::trans::build::*;
+use middle::trans::callee;
 use middle::trans::cleanup;
 use middle::trans::cleanup::CleanupMethods;
 use middle::trans::common::*;
@@ -162,7 +163,7 @@ pub fn trans_slice_vec<'a>(bcx: &'a Block<'a>,
     // Handle the &[...] case:
     let vt = vec_types_from_expr(bcx, content_expr);
     let count = elements_required(bcx, content_expr);
-    debug!("    vt={}, count={:?}", vt.to_str(ccx), count);
+    debug!("    vt={}, count={:?}", vt.to_string(ccx), count);
     let llcount = C_uint(ccx, count);
 
     let fixed_ty = ty::mk_vec(bcx.tcx(),
@@ -173,7 +174,8 @@ pub fn trans_slice_vec<'a>(bcx: &'a Block<'a>,
     let llfixed = if count == 0 {
         // Just create a zero-sized alloca to preserve
         // the non-null invariant of the inner slice ptr
-        base::arrayalloca(bcx, vt.llunit_ty, llcount)
+        let llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount);
+        BitCast(bcx, llfixed, llfixed_ty)
     } else {
         // Make a fixed-length backing array and allocate it on the stack.
         let llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount);
@@ -231,26 +233,55 @@ pub fn trans_uniq_vec<'a>(bcx: &'a Block<'a>,
                           content_expr: &ast::Expr)
                           -> DatumBlock<'a, Expr> {
     /*!
-     * ~[...] and "...".to_string() allocate boxes in the exchange heap and write
+     * Box<[...]> and "...".to_string() allocate boxes in the exchange heap and write
      * the array elements into them.
      */
 
-    debug!("trans_uniq_vec(vstore_expr={})", bcx.expr_to_string(uniq_expr));
+    debug!("trans_uniq_vec(uniq_expr={})", bcx.expr_to_string(uniq_expr));
     let fcx = bcx.fcx;
     let ccx = fcx.ccx;
 
+    // Handle "".to_string().
+    match content_expr.node {
+        ast::ExprLit(lit) => {
+            match lit.node {
+                ast::LitStr(ref s, _) => {
+                    let llptrval = C_cstr(ccx, (*s).clone(), false);
+                    let llptrval = PointerCast(bcx, llptrval, Type::i8p(ccx));
+                    let llsizeval = C_uint(ccx, s.get().len());
+                    let typ = ty::mk_uniq(bcx.tcx(), ty::mk_str(bcx.tcx()));
+                    let lldestval = rvalue_scratch_datum(bcx,
+                                                         typ,
+                                                         "");
+                    let alloc_fn = langcall(bcx,
+                                            Some(lit.span),
+                                            "",
+                                            StrDupUniqFnLangItem);
+                    let bcx = callee::trans_lang_call(
+                        bcx,
+                        alloc_fn,
+                        [ llptrval, llsizeval ],
+                        Some(expr::SaveIn(lldestval.val))).bcx;
+                    return DatumBlock::new(bcx, lldestval).to_expr_datumblock();
+                }
+                _ => {}
+            }
+        }
+        _ => {}
+    }
+
     let vt = vec_types_from_expr(bcx, content_expr);
     let count = elements_required(bcx, content_expr);
-    debug!("    vt={}, count={:?}", vt.to_str(ccx), count);
+    debug!("    vt={}, count={:?}", vt.to_string(ccx), count);
     let vec_ty = node_id_type(bcx, uniq_expr.id);
 
     let unit_sz = nonzero_llsize_of(ccx, type_of::type_of(ccx, vt.unit_ty));
-    let fill = Mul(bcx, C_uint(ccx, count), unit_sz);
-    let alloc = if count < 4u {
-        Mul(bcx, C_int(ccx, 4), unit_sz)
+    let llcount = if count < 4u {
+        C_int(ccx, 4)
     } else {
-        fill
+        C_uint(ccx, count)
     };
+    let alloc = Mul(bcx, llcount, unit_sz);
     let llty_ptr = type_of::type_of(ccx, vt.unit_ty).ptr_to();
     let align = C_uint(ccx, 8);
     let Result { bcx: bcx, val: dataptr } = malloc_raw_dyn(bcx,
@@ -268,7 +299,7 @@ pub fn trans_uniq_vec<'a>(bcx: &'a Block<'a>,
                             dataptr, cleanup::HeapExchange, vt.unit_ty);
 
         debug!("    alloc_uniq_vec() returned dataptr={}, len={}",
-               bcx.val_to_str(dataptr), count);
+               bcx.val_to_string(dataptr), count);
 
         let bcx = write_content(bcx, &vt, uniq_expr,
                                 content_expr, SaveIn(dataptr));
index 9608672928d6186d3709ec33b3da3af7e4e4190f..83c792ecf8782b43c4ad0ad89f7d4d63812dbbd1 100644 (file)
@@ -14,6 +14,7 @@
 use middle::trans::adt;
 use middle::trans::common::*;
 use middle::trans::foreign;
+use middle::trans::machine;
 use middle::ty;
 use util::ppaux;
 use util::ppaux::Repr;
@@ -163,7 +164,7 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
     let llsizingty = match ty::get(t).sty {
         _ if !ty::lltype_is_sized(cx.tcx(), t) => {
             cx.sess().bug(format!("trying to take the sizing type of {}, an unsized type",
-                                  ppaux::ty_to_str(cx.tcx(), t)).as_slice())
+                                  ppaux::ty_to_string(cx.tcx(), t)).as_slice())
         }
 
         ty::ty_nil | ty::ty_bot => Type::nil(cx),
@@ -192,7 +193,7 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
 
         ty::ty_tup(..) | ty::ty_enum(..) | ty::ty_unboxed_closure(..) => {
             let repr = adt::represent_type(cx, t);
-            adt::sizing_type_of(cx, &*repr)
+            adt::sizing_type_of(cx, &*repr, false)
         }
 
         ty::ty_struct(..) => {
@@ -202,7 +203,7 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
                 Type::vector(&type_of(cx, et), n as u64)
             } else {
                 let repr = adt::represent_type(cx, t);
-                adt::sizing_type_of(cx, &*repr)
+                adt::sizing_type_of(cx, &*repr, false)
             }
         }
 
@@ -212,7 +213,7 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
 
         ty::ty_infer(..) | ty::ty_param(..) | ty::ty_err(..) => {
             cx.sess().bug(format!("fictitious type {} in sizing_type_of()",
-                                  ppaux::ty_to_str(cx.tcx(), t)).as_slice())
+                                  ppaux::ty_to_string(cx.tcx(), t)).as_slice())
         }
         ty::ty_vec(_, None) | ty::ty_trait(..) | ty::ty_str => fail!("unreachable")
     };
@@ -232,6 +233,14 @@ pub fn arg_type_of(cx: &CrateContext, t: ty::t) -> Type {
 // NB: If you update this, be sure to update `sizing_type_of()` as well.
 pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
     fn type_of_unsize_info(cx: &CrateContext, t: ty::t) -> Type {
+        // It is possible to end up here with a sized type. This happens with a
+        // struct which might be unsized, but is monomorphised to a sized type.
+        // In this case we'll fake a fat pointer with no unsize info (we use 0).
+        // However, its still a fat pointer, so we need some type use.
+        if ty::type_is_sized(cx.tcx(), t) {
+            return Type::i8p(cx);
+        }
+
         match ty::get(ty::unsized_part_of_type(cx.tcx(), t)).sty {
             ty::ty_str | ty::ty_vec(..) => Type::uint_from_ty(cx, ast::TyU),
             ty::ty_trait(_) => Type::vtable_ptr(cx),
@@ -367,7 +376,7 @@ fn type_of_unsize_info(cx: &CrateContext, t: ty::t) -> Type {
           }
           ty::ty_trait(..) => Type::opaque_trait(cx),
           _ => cx.sess().bug(format!("ty_open with sized type: {}",
-                                     ppaux::ty_to_str(cx.tcx(), t)).as_slice())
+                                     ppaux::ty_to_string(cx.tcx(), t)).as_slice())
       },
 
       ty::ty_infer(..) => cx.sess().bug("type_of with ty_infer"),
@@ -395,6 +404,11 @@ fn type_of_unsize_info(cx: &CrateContext, t: ty::t) -> Type {
     return llty;
 }
 
+pub fn align_of(cx: &CrateContext, t: ty::t) -> u64 {
+    let llty = sizing_type_of(cx, t);
+    machine::llalign_of_min(cx, llty)
+}
+
 // Want refinements! (Or case classes, I guess
 pub enum named_ty {
     a_struct,
index 486ed71457471a34da4dfa3e52bc2115c25ca121..2d3096d13eae078a08be9637beafc8ed3743f96e 100644 (file)
@@ -302,26 +302,23 @@ pub enum AutoRef {
     AutoUnsafe(ast::Mutability),
 }
 
-// Ugly little helper function. The bool in the returned tuple is true if there
-// is an 'unsize to trait object' adjustment at the bottom of the adjustment. If
-// that is surrounded by an AutoPtr, then we also return the region of the
-// AutoPtr (in the third argument). The second bool is true if the adjustment is
-// unique.
+// Ugly little helper function. The first bool in the returned tuple is true if
+// there is an 'unsize to trait object' adjustment at the bottom of the
+// adjustment. If that is surrounded by an AutoPtr, then we also return the
+// region of the AutoPtr (in the third argument). The second bool is true if the
+// adjustment is unique.
 fn autoref_object_region(autoref: &AutoRef) -> (bool, bool, Option<Region>) {
-    fn unsize_kind_region(k: &UnsizeKind) -> (bool, bool, Option<Region>) {
+    fn unsize_kind_is_object(k: &UnsizeKind) -> bool {
         match k {
-            &UnsizeVtable(..) => (true, false, None),
-            &UnsizeStruct(box ref k, _) => unsize_kind_region(k),
-            _ => (false, false, None)
+            &UnsizeVtable(..) => true,
+            &UnsizeStruct(box ref k, _) => unsize_kind_is_object(k),
+            _ => false
         }
     }
 
     match autoref {
-        &AutoUnsize(ref k) => unsize_kind_region(k),
-        &AutoUnsizeUniq(ref k) => match k {
-            &UnsizeVtable(..) => (true, true, None),
-            _ => (false, false, None)
-        },
+        &AutoUnsize(ref k) => (unsize_kind_is_object(k), false, None),
+        &AutoUnsizeUniq(ref k) => (unsize_kind_is_object(k), true, None),
         &AutoPtr(adj_r, _, Some(box ref autoref)) => {
             let (b, u, r) = autoref_object_region(autoref);
             if r.is_some() || u {
@@ -407,6 +404,8 @@ pub struct TransmuteRestriction {
     pub from: t,
     /// The type being transmuted to.
     pub to: t,
+    /// NodeIf of the transmute intrinsic.
+    pub id: ast::NodeId,
 }
 
 /// The data structure to keep track of all the information that typechecker
@@ -1765,7 +1764,7 @@ pub fn maybe_walk_ty(ty: t, f: |t| -> bool) {
     }
     match get(ty).sty {
         ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) |
-        ty_str | ty_infer(_) | ty_param(_) | ty_unboxed_closure(_) | ty_err => {}
+        ty_str | ty_infer(_) | ty_param(_) | ty_unboxed_closure(_, _) | ty_err => {}
         ty_box(ty) | ty_uniq(ty) | ty_vec(ty, _) | ty_open(ty) => maybe_walk_ty(ty, f),
         ty_ptr(ref tm) | ty_rptr(_, ref tm) => {
             maybe_walk_ty(tm.ty, f);
@@ -2941,12 +2940,12 @@ pub fn unsized_part_of_type(cx: &ctxt, ty: t) -> t {
         ty_str | ty_trait(..) | ty_vec(..) => ty,
         ty_struct(_, ref substs) => {
             // Exactly one of the type parameters must be unsized.
-            for tp in substs.types.get_vec(subst::TypeSpace).iter() {
+            for tp in substs.types.get_slice(subst::TypeSpace).iter() {
                 if !type_is_sized(cx, *tp) {
                     return unsized_part_of_type(cx, *tp);
                 }
             }
-            fail!("Unsized struct type with no unsized type params?");
+            fail!("Unsized struct type with no unsized type params? {}", ty_to_string(cx, ty));
         }
         _ => {
             assert!(type_is_sized(cx, ty),
@@ -2990,11 +2989,21 @@ pub fn deref(t: t, explicit: bool) -> Option<mt> {
     }
 }
 
+pub fn deref_or_dont(t: t) -> t {
+    match get(t).sty {
+        ty_box(ty) | ty_uniq(ty) => {
+            ty
+        },
+        ty_rptr(_, mt) | ty_ptr(mt) => mt.ty,
+        _ => t
+    }
+}
+
 pub fn close_type(cx: &ctxt, t: t) -> t {
     match get(t).sty {
         ty_open(t) => mk_rptr(cx, ReStatic, mt {ty: t, mutbl:ast::MutImmutable}),
         _ => cx.sess.bug(format!("Trying to close a non-open type {}",
-                                 ty_to_str(cx, t)).as_slice())
+                                 ty_to_string(cx, t)).as_slice())
     }
 }
 
@@ -3027,9 +3036,9 @@ pub fn index(ty: t) -> Option<t> {
 // This is exactly the same as the above, except it supports strings,
 // which can't actually be indexed.
 pub fn array_element_ty(t: t) -> Option<t> {
-    match get(ty).sty {
+    match get(t).sty {
         ty_vec(t, _) => Some(t),
-        ty_str => Some(ty: mk_u8()),
+        ty_str => Some(mk_u8()),
         _ => None
     }
 }
@@ -3361,20 +3370,19 @@ pub fn unsize_ty(cx: &ctxt,
             }
             _ => cx.sess.span_bug(span,
                                   format!("UnsizeLength with bad sty: {}",
-                                          ty_to_str(cx, ty)).as_slice())
+                                          ty_to_string(cx, ty)).as_slice())
         },
         &UnsizeStruct(box ref k, tp_index) => match get(ty).sty {
             ty_struct(did, ref substs) => {
-                let ty_substs = substs.types.get_vec(subst::TypeSpace);
-                let old_ty = ty_substs.get(tp_index);
-                let new_ty = unsize_ty(cx, *old_ty, k, span);
+                let ty_substs = substs.types.get_slice(subst::TypeSpace);
+                let new_ty = unsize_ty(cx, ty_substs[tp_index], k, span);
                 let mut unsized_substs = substs.clone();
-                *unsized_substs.types.get_mut_vec(subst::TypeSpace).get_mut(tp_index) = new_ty;
+                unsized_substs.types.get_mut_slice(subst::TypeSpace)[tp_index] = new_ty;
                 mk_struct(cx, did, unsized_substs)
             }
             _ => cx.sess.span_bug(span,
                                   format!("UnsizeStruct with bad sty: {}",
-                                          ty_to_str(cx, ty)).as_slice())
+                                          ty_to_string(cx, ty)).as_slice())
         },
         &UnsizeVtable(bounds, def_id, ref substs) => {
             mk_trait(cx, def_id, substs.clone(), bounds)
@@ -5333,6 +5341,7 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
             ty_tup(_) |
             ty_param(_) |
             ty_infer(_) |
+            ty_open(_) |
             ty_err => {}
         }
     })
index b246b5ce7a9528067515b631344e04d4e61c225e..2bfbc67bbeb0f93fd87acc8f301640ccc446462c 100644 (file)
@@ -273,6 +273,18 @@ fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> ty::Generics {
     }
 }
 
+impl TypeFoldable for ty::UnsizeKind {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> ty::UnsizeKind {
+        match *self {
+            ty::UnsizeLength(len) => ty::UnsizeLength(len),
+            ty::UnsizeStruct(box ref k, n) => ty::UnsizeStruct(box k.fold_with(folder), n),
+            ty::UnsizeVtable(bounds, def_id, ref substs) => {
+                ty::UnsizeVtable(bounds.fold_with(folder), def_id, substs.fold_with(folder))
+            }
+        }
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // "super" routines: these are the default implementations for TypeFolder.
 //
@@ -425,11 +437,11 @@ pub fn super_fold_autoref<T:TypeFolder>(this: &mut T,
     match *autoref {
         ty::AutoPtr(r, m, None) => ty::AutoPtr(this.fold_region(r), m, None),
         ty::AutoPtr(r, m, Some(ref a)) => {
-            ty::AutoPtr(this.fold_region(r), m, Some(box super_fold_autoref(this, a.clone())))
+            ty::AutoPtr(this.fold_region(r), m, Some(box super_fold_autoref(this, &**a)))
         }
         ty::AutoUnsafe(m) => ty::AutoUnsafe(m),
-        ty::AutoUnsize(ref k) => ty::AutoUnsize(k.clone()),
-        ty::AutoUnsizeUniq(ref k) => ty::AutoUnsizeUniq(k.clone()),
+        ty::AutoUnsize(ref k) => ty::AutoUnsize(k.fold_with(this)),
+        ty::AutoUnsizeUniq(ref k) => ty::AutoUnsizeUniq(k.fold_with(this)),
     }
 }
 
index f3b829e60ca60e10b3d08be261795413d38baa89..6bb17c90da2694350428356402e206e920d1da0b 100644 (file)
@@ -947,7 +947,7 @@ fn auto_slice_vec(&self, ty: ty::t, autoderefs: uint) -> Option<MethodCallee> {
     // [T, ..len] -> [T] or &[T] or &&[T]
     fn auto_unsize_vec(&self, ty: ty::t, autoderefs: uint, len: uint) -> Option<MethodCallee> {
         let tcx = self.tcx();
-        debug!("auto_unsize_vec {}", ppaux::ty_to_str(tcx, ty));
+        debug!("auto_unsize_vec {}", ppaux::ty_to_string(tcx, ty));
 
         // First try to borrow to an unsized vec.
         let entry = self.search_for_some_kind_of_autorefd_method(
@@ -1330,7 +1330,7 @@ fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
         match self.fcx.mk_subty(false, infer::Misc(span),
                                 rcvr_ty, transformed_self_ty) {
             Ok(_) => {}
-            Err(e) => {
+            Err(_) => {
                 self.bug(format!(
                         "{} was a subtype of {} but now is not?",
                         self.ty_to_string(rcvr_ty),
index 6d3e001a00b0fa4038d0734d13138632bd8682eb..02464e17bac84e41963d20e80538b7f0366d9b97 100644 (file)
@@ -1149,7 +1149,7 @@ fn check_cast(fcx: &FnCtxt,
     if ty::type_is_scalar(t_1) {
         // Supply the type as a hint so as to influence integer
         // literals and other things that might care.
-        check_expr_with_hint(fcx, e, t_1)
+        check_expr_with_expectation(fcx, e, ExpectCastableToType(t_1))
     } else {
         check_expr(fcx, e)
     }
@@ -2033,7 +2033,6 @@ fn check_argument_types(fcx: &FnCtxt,
                 }
 
                 check_expr_coercable_to_type(fcx, &**arg, formal_ty);
-
             }
         }
     }
@@ -2428,12 +2427,12 @@ fn check_then_else(fcx: &FnCtxt,
                 // 'else' branch.
                 let expected = match expected.only_has_type() {
                     ExpectHasType(ety) => {
-                        match infer::resolve_type(fcx.infcx(), ety, force_tvar) {
+                        match infer::resolve_type(fcx.infcx(), Some(sp), ety, force_tvar) {
                             Ok(rty) if !ty::type_is_ty_var(rty) => ExpectHasType(rty),
                             _ => NoExpectation
                         }
                     }
-                    None => None
+                    _ => NoExpectation
                 };
                 check_block_with_expected(fcx, then_blk, expected);
                 let then_ty = fcx.node_ty(then_blk.id);
@@ -3067,23 +3066,6 @@ fn check_struct_enum_variant(fcx: &FnCtxt,
 
     type ExprCheckerWithTy = fn(&FnCtxt, &ast::Expr, ty::t);
 
-    fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
-                                          expected: Expectation)
-                                         -> (ExprCheckerWithTy, ty::t) {
-        let tcx = fcx.ccx.tcx;
-        let (coerce, t) = match expected {
-            // If we're given an expected type, we can try to coerce to it
-            ExpectHasType(t) if ty::type_is_vec(t) => (true, ty::sequence_element_type(tcx, t)),
-            // Otherwise we just leave the type to be resolved later
-            _ => (false, fcx.infcx().next_ty_var())
-        };
-        if coerce {
-            (check_expr_coercable_to_type, t)
-        } else {
-            (check_expr_has_type, t)
-        }
-    }
-
     let tcx = fcx.ccx.tcx;
     let id = expr.id;
     match expr.node {
@@ -3157,7 +3139,6 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
         }
       }
       ast::ExprUnary(unop, ref oprnd) => {
-        let expected = expected.only_has_type();
         let expected_inner = expected.map(fcx, |sty| {
             match unop {
                 ast::UnBox | ast::UnUniq => match *sty {
@@ -3328,7 +3309,6 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
             }
           },
           Some(ref e) => {
-              //check_expr_has_type(fcx, e, ret_ty);
               check_expr_coercable_to_type(fcx, &**e, ret_ty);
           }
         }
@@ -3483,12 +3463,15 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
         check_cast(fcx, &**e, &**t, id, expr.span);
       }
       ast::ExprVec(ref args) => {
-        let uty = unpack_expected(
-            fcx, expected,
-            |sty| match *sty {
-                ty::ty_vec(ty, _) => Some(ty),
-                _ => None
-        });
+        let uty = match expected {
+            ExpectHasType(uty) => {
+                match ty::get(uty).sty {
+                        ty::ty_vec(ty, _) => Some(ty),
+                        _ => None
+                }
+            }
+            _ => None
+        };
 
         let typ = match uty {
             Some(uty) => {
@@ -3512,12 +3495,15 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
         check_expr_has_type(fcx, &**count_expr, ty::mk_uint());
         let count = ty::eval_repeat_count(fcx, &**count_expr);
 
-        let uty = unpack_expected(
-            fcx, expected,
-            |sty| match *sty {
-                ty::ty_vec(ty, _) => Some(ty),
-                _ => None
-        });
+        let uty = match expected {
+            ExpectHasType(uty) => {
+                match ty::get(uty).sty {
+                        ty::ty_vec(ty, _) => Some(ty),
+                        _ => None
+                }
+            }
+            _ => None
+        };
 
         let (element_ty, t) = match uty {
             Some(uty) => {
@@ -3552,17 +3538,14 @@ fn check_fn_for_vec_elements_expected(fcx: &FnCtxt,
         let mut err_field = false;
 
         let elt_ts = elts.iter().enumerate().map(|(i, e)| {
-            let opt_hint = match flds {
-                Some(ref fs) if i < fs.len() => ExpectHasType(*fs.get(i)),
-                _ => NoExpectation
-            };
-            let t = match opt_hint {
-                ExpectHasType(ety) => {
+            let t = match flds {
+                Some(ref fs) if i < fs.len() => {
+                    let ety = *fs.get(i);
                     check_expr_coercable_to_type(fcx, &**e, ety);
                     ety
                 }
                 _ => {
-                    check_expr_with_expectation(fcx, &**e, opt_hint);
+                    check_expr_with_expectation(fcx, &**e, NoExpectation);
                     fcx.expr_ty(&**e)
                 }
             };
@@ -3942,42 +3925,42 @@ fn check_block_with_expected(fcx: &FnCtxt,
         }
         match blk.expr {
             None => if any_err {
-                fcx.write_error(blk.id);
-            }
-            else if any_bot {
-                fcx.write_bot(blk.id);
-            }
-            else  {
-                fcx.write_nil(blk.id);
-            },
-          Some(e) => {
-            if any_bot && !warned {
-                fcx.ccx
-                   .tcx
-                   .sess
-                   .add_lint(lint::builtin::UNREACHABLE_CODE,
-                             e.id,
-                             e.span,
-                             "unreachable expression".to_string());
-            }
-            let ety = match expected {
-                ExpectHasType(ety) => {
-                    check_expr_coercable_to_type(fcx, &*e, ety);
-                    ety
+                    fcx.write_error(blk.id);
                 }
-                _ => {
-                    check_expr_with_expectation(fcx, &*e, expected);
-                    fcx.expr_ty(e)
+                else if any_bot {
+                    fcx.write_bot(blk.id);
                 }
-            };
+                else  {
+                    fcx.write_nil(blk.id);
+                },
+            Some(e) => {
+                if any_bot && !warned {
+                    fcx.ccx
+                       .tcx
+                       .sess
+                       .add_lint(lint::builtin::UNREACHABLE_CODE,
+                                 e.id,
+                                 e.span,
+                                 "unreachable expression".to_string());
+                }
+                let ety = match expected {
+                    ExpectHasType(ety) => {
+                        check_expr_coercable_to_type(fcx, &*e, ety);
+                        ety
+                    }
+                    _ => {
+                        check_expr_with_expectation(fcx, &*e, expected);
+                        fcx.expr_ty(&*e)
+                    }
+                };
 
-            fcx.write_ty(blk.id, ety);
-            if any_err {
-                fcx.write_error(blk.id);
-            } else if any_bot {
-                fcx.write_bot(blk.id);
+                fcx.write_ty(blk.id, ety);
+                if any_err {
+                    fcx.write_error(blk.id);
+                } else if any_bot {
+                    fcx.write_bot(blk.id);
+                }
             }
-          }
         };
     });
 
index 5b14ee62b0aec3bb817491b0a9695921a33d1495..530f8dd4b9ef66435e105e5251126eb70abd055e 100644 (file)
@@ -810,7 +810,6 @@ fn mutability_allowed(a_mutbl: ast::Mutability,
                     }
                 }
                 AutoDerefRef(ref adj) => {
-                    assert!(!ty::adjust_is_object(adjustment));
                     for autoderef in range(0, adj.autoderefs) {
                         let method_call = MethodCall::autoderef(ex.id, autoderef);
                         match fcx.inh.method_map.borrow().find(&method_call) {
@@ -831,9 +830,7 @@ fn mutability_allowed(a_mutbl: ast::Mutability,
                         }
                     }
                 }
-                _ => {
-                    assert!(!ty::adjust_is_object(adjustment));
-                }
+                _ => {}
             }
         }
         None => {}
@@ -867,27 +864,21 @@ fn trait_cast_types_unsize(fcx: &FnCtxt,
                 }
                 &ty::UnsizeStruct(box ref k, tp_index) => match ty::get(src_ty).sty {
                     ty::ty_struct(_, ref substs) => {
-                        let ty_substs = substs.types.get_vec(subst::TypeSpace);
-                        let field_ty = *ty_substs.get(tp_index);
-                        let field_ty = structurally_resolved_type(fcx, sp, field_ty);
+                        let ty_substs = substs.types.get_slice(subst::TypeSpace);
+                        let field_ty = structurally_resolved_type(fcx, sp, ty_substs[tp_index]);
                         trait_cast_types_unsize(fcx, k, field_ty, sp)
                     }
                     _ => fail!("Failed to find a ty_struct to correspond with \
                                 UnsizeStruct whilst walking adjustment. Found {}",
-                                ppaux::ty_to_str(fcx.tcx(), src_ty))
+                                ppaux::ty_to_string(fcx.tcx(), src_ty))
                 },
                 _ => None
             }
         }
 
         match autoref {
-            &ty::AutoUnsize(ref k) => trait_cast_types_unsize(fcx, k, src_ty, sp),
-            &ty::AutoUnsizeUniq(ref k) => match k {
-                &ty::UnsizeVtable(bounds, def_id, ref substs) => {
-                    Some((src_ty, ty::mk_trait(fcx.tcx(), def_id, substs.clone(), bounds)))
-                }
-                _ => None
-            },
+            &ty::AutoUnsize(ref k) |
+            &ty::AutoUnsizeUniq(ref k) => trait_cast_types_unsize(fcx, k, src_ty, sp),
             &ty::AutoPtr(_, _, Some(box ref autoref)) => {
                 trait_cast_types_autoref(fcx, autoref, src_ty, sp)
             }
index 6d0b34e89d679da56a2837b904221daadcedaf39..abf366381139cdead006d0d081137a2c9e6bcd10 100644 (file)
@@ -199,8 +199,8 @@ pub fn subtype(&self, a: ty::t, b: ty::t) -> CoerceResult {
         }
     }
 
-    pub fn unpack_actual_value(&self, a: ty::t, f: |&ty::sty| -> CoerceResult)
-                               -> CoerceResult {
+    pub fn unpack_actual_value<T>(&self, a: ty::t, f: |&ty::sty| -> T)
+                                  -> T {
         match resolve_type(self.get_ref().infcx, None,
                            a, try_resolve_tvar_shallow) {
             Ok(t) => {
@@ -306,7 +306,7 @@ fn coerce_unsized(&self,
 
         let sty_b = &ty::get(b).sty;
         match (sty_a, sty_b) {
-            (&ty::ty_uniq(t_a), &ty::ty_rptr(_, mt_b)) => Err(ty::terr_mismatch),
+            (&ty::ty_uniq(_), &ty::ty_rptr(..)) => Err(ty::terr_mismatch),
             (&ty::ty_rptr(_, ty::mt{ty: t_a, ..}), &ty::ty_rptr(_, mt_b)) => {
                 self.unpack_actual_value(t_a, |sty_a| {
                     match self.unsize_ty(sty_a, mt_b.ty) {
@@ -381,8 +381,8 @@ fn unsize_ty(&self,
                   if did_a == did_b => {
                     debug!("unsizing a struct");
                     // Try unsizing each type param in turn to see if we end up with ty_b.
-                    let ty_substs_a = substs_a.types.get_vec(subst::TypeSpace);
-                    let ty_substs_b = substs_b.types.get_vec(subst::TypeSpace);
+                    let ty_substs_a = substs_a.types.get_slice(subst::TypeSpace);
+                    let ty_substs_b = substs_b.types.get_slice(subst::TypeSpace);
                     assert!(ty_substs_a.len() == ty_substs_b.len());
 
                     let sub = Sub(self.get_ref().clone());
@@ -397,7 +397,7 @@ fn unsize_ty(&self,
                             Some((new_tp, k)) => {
                                 // Check that the whole types match.
                                 let mut new_substs = substs_a.clone();
-                                *new_substs.types.get_mut_vec(subst::TypeSpace).get_mut(i) = new_tp;
+                                new_substs.types.get_mut_slice(subst::TypeSpace)[i] = new_tp;
                                 let ty = ty::mk_struct(tcx, did_a, new_substs);
                                 if self.get_ref().infcx.try(|| sub.tys(ty, ty_b)).is_err() {
                                     debug!("Unsized type parameter '{}', but still \
@@ -439,8 +439,7 @@ fn coerce_borrowed_object(&self,
         let r_a = self.get_ref().infcx.next_region_var(coercion);
 
         let a_borrowed = match *sty_a {
-            ty::ty_uniq(ty) => return Err(ty::terr_mismatch),
-            ty::ty_rptr(_, ty::mt{ty, ..}) => match ty::get(ty).sty {
+            ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => match ty::get(ty).sty {
                 ty::ty_trait(box ty::TyTrait {
                         def_id,
                         ref substs,
index 4f68d42de966c48ce15c30eeedf7e359480fff3c..5dff183108ce8f78290c96d27bb35413a4860400 100644 (file)
@@ -370,7 +370,7 @@ fn push_sig_to_string(cx: &ctxt,
           buf.push_str(mt_to_string(cx, tm).as_slice());
           buf
       }
-      ty_open(typ) => format!("opened<{}>", ty_to_str(cx, typ)),
+      ty_open(typ) => format!("opened<{}>", ty_to_string(cx, typ)),
       ty_tup(ref elems) => {
         let strs: Vec<String> = elems.iter().map(|elem| ty_to_string(cx, *elem)).collect();
         format!("({})", strs.connect(","))
index a9cbacb07bee5d12fc3b6664a5e7b32cc2d97588..bbaac7a96e9ee5df9dd3e33f3594e5aaffd89dd8 100644 (file)
@@ -18,7 +18,6 @@
 use std::rc::Rc;
 use std::gc::{Gc, GC};
 use std::cell::{Cell, RefCell};
-use std::strbuf::StrBuf;
 
 pub trait Encoder<E> {
     // Primitive types:
index 00513f7f67c3165be57a280c3018fa4723db9b5a..01de001c043c748b8f65add177da2001a2b5628a 100644 (file)
@@ -61,7 +61,7 @@
 use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
 use ast::{Visibility, WhereClause, WherePredicate};
 use ast;
-use ast_util::{as_prec, ident_to_path, lit_is_str, operator_prec};
+use ast_util::{as_prec, ident_to_path, operator_prec};
 use ast_util;
 use attr;
 use codemap::{Span, BytePos, Spanned, spanned, mk_sp};
@@ -2577,21 +2577,24 @@ pub fn parse_prefix_expr(&mut self) -> Gc<Expr> {
             ex = self.mk_unary(UnUniq, e);
           }
           token::IDENT(_, _) => {
-              if self.is_keyword(keywords::Box) {
-                self.bump();
+            if !self.is_keyword(keywords::Box) {
+                return self.parse_dot_or_call_expr();
+            }
 
-                // Check for a place: `box(PLACE) EXPR`.
-                if self.eat(&token::LPAREN) {
-                    // Support `box() EXPR` as the default.
-                    if !self.eat(&token::RPAREN) {
-                        let place = self.parse_expr();
-                        self.expect(&token::RPAREN);
-                        let subexpression = self.parse_prefix_expr();
-                        hi = subexpression.span.hi;
-                        ex = ExprBox(place, subexpression);
-                        return self.mk_expr(lo, hi, ex);
-                    }
+            self.bump();
+
+            // Check for a place: `box(PLACE) EXPR`.
+            if self.eat(&token::LPAREN) {
+                // Support `box() EXPR` as the default.
+                if !self.eat(&token::RPAREN) {
+                    let place = self.parse_expr();
+                    self.expect(&token::RPAREN);
+                    let subexpression = self.parse_prefix_expr();
+                    hi = subexpression.span.hi;
+                    ex = ExprBox(place, subexpression);
+                    return self.mk_expr(lo, hi, ex);
                 }
+            }
 
             // Otherwise, we use the unique pointer default.
             let subexpression = self.parse_prefix_expr();
index 9a56dd5c0e47b46fe04164028db7af850b57fca7..429a16ec5c89aee418cb8271ec270551f54ae065 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -268,19 +268,7 @@ pub struct Tm {
     pub tm_nsec: i32,
 }
 
-impl Tm {
-    pub fn tm_zone<'a>(&'a self) -> &'a str {
-        self.tm_zone.as_slice()
-    }
-}
-
 pub fn empty_tm() -> Tm {
-    // 64 is the max size of the timezone buffer allocated on windows
-    // in rust_localtime. In glibc the max timezone size is supposedly 3.
-    let mut zone = StrBuf::new();
-    for _ in range(0, 64) {
-        zone.push_char(' ')
-    }
     Tm {
         tm_sec: 0_i32,
         tm_min: 0_i32,
@@ -292,7 +280,6 @@ pub fn empty_tm() -> Tm {
         tm_yday: 0_i32,
         tm_isdst: 0_i32,
         tm_gmtoff: 0_i32,
-        tm_zone: zone,
         tm_nsec: 0_i32,
     }
 }
@@ -773,7 +760,6 @@ fn parse_type(s: &str, pos: uint, ch: char, tm: &mut Tm)
           'Z' => {
             if match_str(s, pos, "UTC") || match_str(s, pos, "GMT") {
                 tm.tm_gmtoff = 0_i32;
-                tm.tm_zone = "UTC".into_strbuf();
                 Ok(pos + 3u)
             } else {
                 // It's odd, but to maintain compatibility with c's
@@ -798,7 +784,6 @@ fn parse_type(s: &str, pos: uint, ch: char, tm: &mut Tm)
                     let (v, pos) = item;
                     if v == 0_i32 {
                         tm.tm_gmtoff = 0_i32;
-                        tm.tm_zone = "UTC".into_strbuf();
                     }
 
                     Ok(pos)
@@ -828,7 +813,6 @@ fn parse_type(s: &str, pos: uint, ch: char, tm: &mut Tm)
         tm_yday: 0_i32,
         tm_isdst: 0_i32,
         tm_gmtoff: 0_i32,
-        tm_zone: StrBuf::new(),
         tm_nsec: 0_i32,
     };
     let mut pos = 0u;
@@ -875,7 +859,6 @@ fn parse_type(s: &str, pos: uint, ch: char, tm: &mut Tm)
             tm_yday: tm.tm_yday,
             tm_isdst: tm.tm_isdst,
             tm_gmtoff: tm.tm_gmtoff,
-            tm_zone: tm.tm_zone.clone(),
             tm_nsec: tm.tm_nsec,
         })
     } else { result }
@@ -1077,7 +1060,6 @@ fn parse_type(ch: char, tm: &Tm) -> String {
           'w' => (tm.tm_wday as int).to_string(),
           'Y' => (tm.tm_year as int + 1900).to_string(),
           'y' => format!("{:02d}", (tm.tm_year as int + 1900) % 100),
-          'Z' => tm.tm_zone.as_slice().to_owned(),
           'z' => {
             let sign = if tm.tm_gmtoff > 0_i32 { '+' } else { '-' };
             let mut m = num::abs(tm.tm_gmtoff) / 60_i32;
@@ -1203,7 +1185,6 @@ fn test_at_utc() {
         assert_eq!(utc.tm_yday, 43_i32);
         assert_eq!(utc.tm_isdst, 0_i32);
         assert_eq!(utc.tm_gmtoff, 0_i32);
-        assert_eq!(utc.tm_zone(), "UTC");
         assert_eq!(utc.tm_nsec, 54321_i32);
     }
 
@@ -1225,12 +1206,6 @@ fn test_at() {
         assert_eq!(local.tm_yday, 43_i32);
         assert_eq!(local.tm_isdst, 0_i32);
         assert_eq!(local.tm_gmtoff, -28800_i32);
-
-        // FIXME (#2350): We should probably standardize on the timezone
-        // abbreviation.
-        let zone = local.tm_zone();
-        assert!(zone == "PST" || zone == "Pacific Standard Time");
-
         assert_eq!(local.tm_nsec, 54321_i32);
     }
 
@@ -1273,7 +1248,6 @@ fn test_strptime() {
             assert!(tm.tm_wday == 0_i32);
             assert!(tm.tm_isdst == 0_i32);
             assert!(tm.tm_gmtoff == 0_i32);
-            assert!(tm.tm_zone() == "");
             assert!(tm.tm_nsec == 0_i32);
           }
           Err(_) => ()
@@ -1297,7 +1271,6 @@ fn test_strptime() {
             assert!(tm.tm_yday == 0_i32);
             assert!(tm.tm_isdst == 0_i32);
             assert!(tm.tm_gmtoff == 0_i32);
-            assert!(tm.tm_zone() == "");
             assert!(tm.tm_nsec == 12340000_i32);
           }
         }
@@ -1409,10 +1382,10 @@ fn test(s: &str, format: &str) -> bool {
         assert!(test("6", "%w"));
         assert!(test("2009", "%Y"));
         assert!(test("09", "%y"));
-        assert!(strptime("UTC", "%Z").unwrap().tm_zone() == "UTC");
-        assert!(strptime("PST", "%Z").unwrap().tm_zone() == "");
-        assert!(strptime("-0000", "%z").unwrap().tm_gmtoff == 0);
-        assert!(strptime("-0800", "%z").unwrap().tm_gmtoff == 0);
+        assert!(strptime("-0000", "%z").unwrap().tm_gmtoff ==
+            0);
+        assert!(strptime("-0800", "%z").unwrap().tm_gmtoff ==
+            0);
         assert!(test("%", "%%"));
 
         // Test for #7256
index 262721bd63676d1df3e32eeeaf3583d718228e2e..c71cf5557e35f89f293056daa90de5762d71af75 100644 (file)
@@ -46,9 +46,11 @@ pub trait UnicodeStrSlice<'a> {
     ///
     /// ```rust
     /// let gr1 = "a\u0310e\u0301o\u0308\u0332".graphemes(true).collect::<Vec<&str>>();
-    /// assert_eq!(gr1.as_slice(), &["a\u0310", "e\u0301", "o\u0308\u0332"]);
+    /// let b: &[_] = &["a\u0310", "e\u0301", "o\u0308\u0332"];
+    /// assert_eq!(gr1.as_slice(), b);
     /// let gr2 = "a\r\nb🇷🇺🇸🇹".graphemes(true).collect::<Vec<&str>>();
-    /// assert_eq!(gr2.as_slice(), &["a", "\r\n", "b", "🇷🇺🇸🇹"]);
+    /// let b: &[_] = &["a", "\r\n", "b", "🇷🇺🇸🇹"];
+    /// assert_eq!(gr2.as_slice(), b);
     /// ```
     fn graphemes(&self, is_extended: bool) -> Graphemes<'a>;
 
@@ -59,7 +61,8 @@ pub trait UnicodeStrSlice<'a> {
     ///
     /// ```rust
     /// let gr_inds = "a̐éö̲\r\n".grapheme_indices(true).collect::<Vec<(uint, &str)>>();
-    /// assert_eq!(gr_inds.as_slice(), &[(0u, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")]);
+    /// let b: &[_] = &[(0u, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")];
+    /// assert_eq!(gr_inds.as_slice(), b);
     /// ```
     fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices<'a>;
 
index 9ced6cb62af00f0c310167f6720f498782f9db30..b5ffdef22e968dac5531f33fd210cacbdb41bfe9 100644 (file)
@@ -1095,7 +1095,8 @@ fn t<T: BytesContainer>(input: T, expected: &str) {
         t("\0", "%00");
         t("\n", "%0A");
 
-        t(&[0u8, 10, 37], "%00%0A%25");
+        let a: &[_] = &[0u8, 10, 37];
+        t(a, "%00%0A%25");
     }
 
     #[test]
@@ -1130,7 +1131,8 @@ fn t<T: BytesContainer>(input: T, expected: &str) {
         t("\0", "%00");
         t("\n", "%0A");
 
-        t(&[0u8, 10, 37], "%00%0A%25");
+        let a: &[_] = &[0u8, 10, 37];
+        t(a, "%00%0A%25");
     }
 
     #[test]
index 1a9b1c1c818b709190ac58176af7a959084af032..ba20f2c6f27f9fca7b9404cb90564be862331cdd 100644 (file)
@@ -127,15 +127,6 @@ rust_list_dir_wfd_fp_buf(void* wfd) {
 }
 #endif
 
-typedef struct
-{
-    size_t fill;    // in bytes; if zero, heapified
-    size_t alloc;   // in bytes
-    uint8_t *data;
-} rust_vec;
-
-typedef rust_vec rust_str_buf;
-
 typedef struct {
     int32_t tm_sec;
     int32_t tm_min;
@@ -147,7 +138,6 @@ typedef struct {
     int32_t tm_yday;
     int32_t tm_isdst;
     int32_t tm_gmtoff;
-    rust_str_buf tm_zone;
     int32_t tm_nsec;
 } rust_tm;
 
@@ -164,8 +154,10 @@ void rust_tm_to_tm(rust_tm* in_tm, struct tm* out_tm) {
     out_tm->tm_isdst = in_tm->tm_isdst;
 }
 
-void tm_to_rust_tm(struct tm* in_tm, rust_tm* out_tm, int32_t gmtoff,
-                   const char *zone, int32_t nsec) {
+void tm_to_rust_tm(struct tm* in_tm,
+                   rust_tm* out_tm,
+                   int32_t gmtoff,
+                   int32_t nsec) {
     out_tm->tm_sec = in_tm->tm_sec;
     out_tm->tm_min = in_tm->tm_min;
     out_tm->tm_hour = in_tm->tm_hour;
@@ -177,13 +169,6 @@ void tm_to_rust_tm(struct tm* in_tm, rust_tm* out_tm, int32_t gmtoff,
     out_tm->tm_isdst = in_tm->tm_isdst;
     out_tm->tm_gmtoff = gmtoff;
     out_tm->tm_nsec = nsec;
-
-    if (zone != NULL) {
-        size_t size = strlen(zone);
-        assert(out_tm->tm_zone.alloc >= size);
-        memcpy(out_tm->tm_zone.data, zone, size);
-        out_tm->tm_zone.fill = size;
-    }
 }
 
 #if defined(__WIN32__)
@@ -225,7 +210,7 @@ rust_gmtime(int64_t sec, int32_t nsec, rust_tm *timeptr) {
     time_t s = sec;
     GMTIME(&s, &tm);
 
-    tm_to_rust_tm(&tm, timeptr, 0, "UTC", nsec);
+    tm_to_rust_tm(&tm, timeptr, 0, nsec);
 }
 
 void
@@ -234,28 +219,13 @@ rust_localtime(int64_t sec, int32_t nsec, rust_tm *timeptr) {
     time_t s = sec;
     LOCALTIME(&s, &tm);
 
-    const char* zone = NULL;
 #if defined(__WIN32__)
     int32_t gmtoff = -timezone;
-    wchar_t wbuffer[64] = {0};
-    char buffer[256] = {0};
-    // strftime("%Z") can contain non-UTF-8 characters on non-English locale (issue #9418),
-    // so time zone should be converted from UTF-16 string.
-    // Since wcsftime depends on setlocale() result,
-    // instead we convert it using MultiByteToWideChar.
-    if (strftime(buffer, sizeof(buffer) / sizeof(char), "%Z", &tm) > 0) {
-        // ANSI -> UTF-16
-        MultiByteToWideChar(CP_ACP, 0, buffer, -1, wbuffer, sizeof(wbuffer) / sizeof(wchar_t));
-        // UTF-16 -> UTF-8
-        WideCharToMultiByte(CP_UTF8, 0, wbuffer, -1, buffer, sizeof(buffer), NULL, NULL);
-        zone = buffer;
-    }
 #else
     int32_t gmtoff = tm.tm_gmtoff;
-    zone = tm.tm_zone;
 #endif
 
-    tm_to_rust_tm(&tm, timeptr, gmtoff, zone, nsec);
+    tm_to_rust_tm(&tm, timeptr, gmtoff, nsec);
 }
 
 int64_t
index 4f53694ebd622b6e074ced8b10c58d185db3071b..6b8e126db7790a51989b47f8ff98a65125090266 100644 (file)
@@ -9,8 +9,10 @@
 // except according to those terms.
 
 static a: &'static str = "foo";
-static b: *const u8 = a as *const u8; //~ ERROR mismatched types: expected `*u8` but found `&'static str`
-static c: *const u8 = &a as *const u8; //~ ERROR mismatched types: expected `*u8` but found `&&'static str`
+static b: *const u8 = a as *const u8;
+//~^ ERROR mismatched types: expected `*const u8`, found `&'static str`
+static c: *const u8 = &a as *const u8;
+//~^ ERROR mismatched types: expected `*const u8`, found `&&'static str`
 
 fn main() {
 }
index 282cf57df26c0d6cb5f2a06a64d9ca8efff7570f..08e51038104365e985b2d2599f8f604293600c26 100644 (file)
@@ -10,7 +10,7 @@
 
 // Forbid assignment into a dynamically sized type.
 
-struct Fat<type T> {
+struct Fat<Sized? T> {
     f1: int,
     f2: &'static str,
     ptr: T
index e069eb01ae18456445a11422d380835ffe9f007b..17149941a7e1a4c0e6787d49947cabea02e25a72 100644 (file)
@@ -10,7 +10,7 @@
 
 // Forbid assignment into a dynamically sized type.
 
-struct Fat<type T> {
+struct Fat<Sized? T> {
     f1: int,
     f2: &'static str,
     ptr: T
@@ -42,5 +42,5 @@ pub fn main() {
     // Assignment.
     let f5: &mut Fat<ToBar> = &mut Fat { f1: 5, f2: "some str", ptr: Bar1 {f :42} };
     let z: Box<ToBar> = box Bar1 {f: 36};
-    f5.ptr = Bar1 {f: 36}; //~ ERROR mismatched types: expected `ToBar` but found `Bar1`
+    f5.ptr = Bar1 {f: 36}; //~ ERROR mismatched types: expected `ToBar`, found `Bar1`
 }
index a7dc4e123aff8a27d7e100c1e8ad2a247737484d..a609740eaebf50c1e0be78b50a774037c805eacf 100644 (file)
@@ -10,7 +10,7 @@
 
 // Attempt to change the type as well as unsizing.
 
-struct Fat<type T> {
+struct Fat<Sized? T> {
     ptr: T
 }
 
@@ -22,7 +22,7 @@ pub fn main() {
     let f1 = Fat { ptr: [1, 2, 3] };
     let f2: &Fat<[int, ..3]> = &f1;
     let f3: &Fat<[uint]> = f2;
-    //~^ ERROR mismatched types: expected `&Fat<[uint]>` but found `&Fat<[int, .. 3]>`
+    //~^ ERROR mismatched types: expected `&Fat<[uint]>`, found `&Fat<[int, .. 3]>`
 
     // With a trait.
     let f1 = Fat { ptr: Foo };
index d4ce59b726162b5782473903a677301e8304ecc5..118e4ce7e08340ac015bd7e0168805d82219c530 100644 (file)
@@ -10,7 +10,7 @@
 
 // Attempt to change the mutability as well as unsizing.
 
-struct Fat<type T> {
+struct Fat<Sized? T> {
     ptr: T
 }
 
index bd7c46060a5124ce6f4cff31e037bf6b467787b1..7cf647a26d7a7ef89fb318449d7d3a7619aa0020 100644 (file)
@@ -10,7 +10,7 @@
 
 // Attempt to extend the lifetime as well as unsizing.
 
-struct Fat<type T> {
+struct Fat<Sized? T> {
     ptr: T
 }
 
index 0916fa08a3924c877abe2b01ad35cd9be033fd74..9a192334997d28e47ad939fa2bef2b3af7748652 100644 (file)
@@ -10,7 +10,7 @@
 
 // Attempt to coerce from unsized to sized.
 
-struct Fat<type T> {
+struct Fat<Sized? T> {
     ptr: T
 }
 
@@ -18,5 +18,5 @@ pub fn main() {
     // With a vec of ints.
     let f1: &Fat<[int]> = &Fat { ptr: [1, 2, 3] };
     let f2: &Fat<[int, ..3]> = f1;
-    //~^ ERROR  mismatched types: expected `&Fat<[int, .. 3]>` but found `&Fat<[int]>`
+    //~^ ERROR mismatched types: expected `&Fat<[int, .. 3]>`, found `&Fat<[int]>`
 }
index b18e7dad4ac558f719ad8f7c136e4ad960fb0b23..cf526392283304bc0274daf84700e50577a7c8be 100644 (file)
@@ -13,7 +13,7 @@
 // because it would require stack allocation of an unsized temporary (*g in the
 // test).
 
-struct Fat<type T> {
+struct Fat<Sized? T> {
     ptr: T
 }
 
index 795e48cb7b005c9eeceefde9bd656186d0b3c2e0..ab9f7a8453078b0beb77decdf7120b5609e4c27a 100644 (file)
 // aux-build:issue_3907.rs
 extern crate issue_3907;
 
-type Foo = issue_3907::Foo; //~ ERROR: reference to trait
+type Foo = issue_3907::Foo;
 
 struct S {
     name: int
 }
 
+fn bar(_x: Foo) {} //~ ERROR variable `_x` has dynamically sized type `issue_3907::Foo`
+
 fn main() {}
index f7199a92d27cc42c7772f63527a798541b231c41..199bc3f5c29d9a22a060528fbd99efa768c6b357 100644 (file)
@@ -17,7 +17,7 @@ pub enum TraitWrapper {
 
 fn get_tw_map(tw: &TraitWrapper) -> &MyTrait {
     match *tw {
-        A(box ref map) => map, //~ ERROR mismatched types: expected `Box<MyTrait>` but found a box
+        A(box ref map) => map, //~ ERROR type `Box<MyTrait>` cannot be dereferenced
     }
 }
 
index 8d9116da81db21b74bdf9a37e868ccb4019aa3a7..689b8f7c6136043d9e4dbb42342c704a716715f7 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 trait I {}
-type K = I; //~ ERROR: reference to trait
+type K = I;
+
+fn foo(_x: K) {} //~ ERROR: variable `_x` has dynamically sized type `I`
 
 fn main() {}
index 3703d4f39acef8424fddbebff4d13ccc8ee7be8d..14136d96c2dffc71dec1413da0f3217f927a5795 100644 (file)
@@ -16,7 +16,7 @@ struct Struct {
 
 fn new_struct(r: A) -> Struct {
     //~^ ERROR variable `r` has dynamically sized type `A`
-    Struct { r: r }
+    Struct { r: r } //~ ERROR trying to initialise a dynamically sized struct
 }
 
 trait Curve {}
index efd8e75d3d6d3e70b8dd6cf7d0521c477791b954..ef585998aa5a5b5ce83f95475c176d5c0d04783d 100644 (file)
@@ -32,7 +32,7 @@ struct A {
 
 fn main() {
     let a = A {v: box B{v: None} as Box<Foo+Send>};
-    //~^ ERROR cannot pack type `Box<B>` as a trait bounded by Send because the type does not fulfil
+    //~^ ERROR cannot pack type `Box<B>`, which does not fulfill `Send`, as a trait bounded by Send
     let v = Rc::new(RefCell::new(a));
     let w = v.clone();
     let b = &*v;
index 27d272c9f319b4e6f9485a2e2f8eaff7597b5e8f..1500a3cbe52db8df89ba0a5b382716b16bb28543 100644 (file)
@@ -13,6 +13,6 @@
 fn first((value, _): (int, f64)) -> int { value }
 
 fn main() {
-    let y = first ((1,2,3));
+    let y = first ((1,2.0,3));
     //~^ ERROR expected a tuple with 2 elements, found one with 3 elements
 }
index e1ad27ec5c7a2040701fe3c9e56cd379c42bc91d..7f93c8595f2a2721dd2b001848fdd9c0df606eb9 100644 (file)
@@ -48,8 +48,8 @@ pub fn bar() {
                        as core::fmt::rt::Piece<'static>)] as
                      [core::fmt::rt::Piece<'static>, .. 1]);
              let __args_vec =
-                 (&([] as &'static [core::fmt::Argument<'static>]) as
-                     &'static [core::fmt::Argument<'static>]);
+                 (&([] as [core::fmt::Argument<'static>, .. 0]) as
+                     &'static [core::fmt::Argument<'static>, .. 0]);
              let __args =
                  (unsafe {
                       ((::std::fmt::Arguments::new as
@@ -58,7 +58,7 @@ pub fn bar() {
                                                                                                                                                [core::fmt::rt::Piece<'static>, .. 1]),
                                                                                                                                            (__args_vec
                                                                                                                                                as
-                                                                                                                                               &'static [core::fmt::Argument<'static>]))
+                                                                                                                                               &'static [core::fmt::Argument<'static>, .. 0]))
                           as core::fmt::Arguments<'static>)
                   } as core::fmt::Arguments<'static>);
 
index 978cca56b56048d598fcccd404fcc6f3c27a9f37..77ee0df5512ef05484f444c167dba6716bab8e84 100644 (file)
@@ -47,7 +47,7 @@ digraph block {
     N10 -> N11;
     N11 -> N12;
     N12 -> N13;
-    N13 -> N7[label="exiting scope_0 expr break \'outer,\lexiting scope_1 stmt break \'outer ;,\lexiting scope_2 block { break \'outer ; \"unreachable\"; },\lexiting scope_3 expr if x == 1i { break \'outer ; \"unreachable\"; },\lexiting scope_4 stmt if x == 1i { break \'outer ; \"unreachable\"; },\lexiting scope_5 block {\l    if x == 1i { break \'outer ; \"unreachable\"; }\l    if y >= 2i { break ; \"unreachable\"; }\l    y -= 3;\l}\l,\lexiting scope_6 expr \'inner:\l    loop  {\l        if x == 1 { break \'outer ; \"unreachable\"; }\l        if y >= 2 { break ; \"unreachable\"; }\l        y -= 3;\l    }\l,\lexiting scope_7 stmt \'inner:\l    loop  {\l        if x == 1 { break \'outer ; \"unreachable\"; }\l        if y >= 2 { break ; \"unreachable\"; }\l        y -= 3;\l    }\l,\lexiting scope_8 block {\l    \'inner:\l        loop  {\l            if x == 1 { break \'outer ; \"unreachable\"; }\l            if y >= 2 { break ; \"unreachable\"; }\l            y -= 3;\l        }\l    y -= 4;\l    x -= 5;\l}\l"];
+    N13 -> N7[label="exiting scope_0 expr break \'outer,\lexiting scope_1 stmt break \'outer ;,\lexiting scope_2 block { break \'outer ; \"unreachable\"; },\lexiting scope_3 expr if x == 1i { break \'outer ; \"unreachable\"; },\lexiting scope_4 stmt if x == 1i { break \'outer ; \"unreachable\"; },\lexiting scope_5 block {\l    if x == 1i { break \'outer ; \"unreachable\"; }\l    if y >= 2i { break ; \"unreachable\"; }\l    y -= 3i;\l}\l,\lexiting scope_6 expr \'inner:\l    loop  {\l        if x == 1i { break \'outer ; \"unreachable\"; }\l        if y >= 2i { break ; \"unreachable\"; }\l        y -= 3i;\l    }\l,\lexiting scope_7 stmt \'inner:\l    loop  {\l        if x == 1i { break \'outer ; \"unreachable\"; }\l        if y >= 2i { break ; \"unreachable\"; }\l        y -= 3i;\l    }\l,\lexiting scope_8 block {\l    \'inner:\l        loop  {\l            if x == 1i { break \'outer ; \"unreachable\"; }\l            if y >= 2i { break ; \"unreachable\"; }\l            y -= 3i;\l        }\l    y -= 4i;\l    x -= 5i;\l}\l"];
     N14 -> N15;
     N15 -> N16;
     N12 -> N17;
index 963c4b43531959a283e0a01f12818af65d9c4d8d..b5a867e60297f8202557870ebcbedbf550a883fb 100644 (file)
@@ -29,7 +29,7 @@ digraph block {
     N27[label="expr y"];
     N28[label="expr y -= 1i"];
     N29[label="block {\l    if x == 1i { continue \'outer ; \"unreachable\"; }\l    if y >= 1i { break ; \"unreachable\"; }\l    y -= 1i;\l}\l"];
-    N30[label="expr 1"];
+    N30[label="expr 1i"];
     N31[label="expr y"];
     N32[label="expr y -= 1i"];
     N33[label="expr 1i"];
diff --git a/src/test/run-pass/dst-dtor-1.rs b/src/test/run-pass/dst-dtor-1.rs
new file mode 100644 (file)
index 0000000..6e2ae11
--- /dev/null
@@ -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 DROP_RAN: bool = false;
+
+struct Foo;
+impl Drop for Foo {
+    fn drop(&mut self) {
+        unsafe { DROP_RAN = true; }
+    }
+}
+
+trait Trait {}
+impl Trait for Foo {}
+
+struct Fat<Sized? T> {
+    f: T
+}
+
+pub fn main() {
+    {
+        let _x: Box<Fat<Trait>> = box Fat { f: Foo };
+    }
+    unsafe {
+        assert!(DROP_RAN);
+    }
+}
diff --git a/src/test/run-pass/dst-dtor-2.rs b/src/test/run-pass/dst-dtor-2.rs
new file mode 100644 (file)
index 0000000..deaf492
--- /dev/null
@@ -0,0 +1,31 @@
+// 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 DROP_RAN: int = 0;
+
+struct Foo;
+impl Drop for Foo {
+    fn drop(&mut self) {
+        unsafe { DROP_RAN += 1; }
+    }
+}
+
+struct Fat<Sized? T> {
+    f: T
+}
+
+pub fn main() {
+    {
+        let _x: Box<Fat<[Foo]>> = box Fat { f: [Foo, Foo, Foo] };
+    }
+    unsafe {
+        assert!(DROP_RAN == 3);
+    }
+}
index 297880a8b53de18ef64769a1e9aa5c6a3a345d22..2028ebf64c217afd68e71edeaa0a015d23183188 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// FIXME(15049) Re-enable this test.
+// ignore-test
 // Test that structs with unsized fields work with {:?} reflection.
 
 extern crate debug;
 
-struct Fat<type T> {
+struct Fat<Sized? T> {
     f1: int,
     f2: &'static str,
     ptr: T
index 3f01d013cee326820b14c49b5511420c71615c6a..04fe6d5cefdc39b8d55382fcaca928bc43e2f4b8 100644 (file)
@@ -10,7 +10,7 @@
 
 // As dst-struct.rs, but the unsized field is the only field in the struct.
 
-struct Fat<type T> {
+struct Fat<Sized? T> {
     ptr: T
 }
 
index ae1f854ccab34803b8a1bd969be898a42695581e..6b8e25e85590f6aaa2d57bbcf84e306885f9465e 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Fat<type T> {
+struct Fat<Sized? T> {
     f1: int,
     f2: &'static str,
     ptr: T
index 7429136716c965a141bc8b6687c7e2a074e0fd58..976273095510402e0fa93ba56c80041990b11a7f 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Fat<type T> {
+struct Fat<Sized? T> {
     f1: int,
     f2: &'static str,
     ptr: T
index d2f43aacd66ab5af3873797042372d7ffd0ab1d0..430ee16bc8a26682078697fd3d7fc92d517851a6 100644 (file)
 
 fn main() {
     // A fixed-size array allocated in a garbage-collected box
-    let x = box(GC) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+    let x = box(GC) [1i, 2, 3, 4, 5, 6, 7, 8, 9, 10];
     assert_eq!(x[0], 1);
     assert_eq!(x[6], 7);
     assert_eq!(x[9], 10);
 
     let y = x;
-    assert!(*y == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
+    assert!(*y == [1i, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
 }
index 123ad36ee4f2d7c84a1e2d31dca870871bb2fb95..0aca74c76c3e78aace1b8cb9943886d06177aaeb 100644 (file)
@@ -30,7 +30,8 @@ macro_rules! demo {
                      : "r"(&wrap(y, "in", &mut history)));
             }
             assert_eq!((x,y), (1,1));
-            assert_eq!(history.as_slice(), &["out", "in"]);
+            let b: &[_] = &["out", "in"];
+            assert_eq!(history.as_slice(), b);
         }
     }
 }
index b0741391d8039ec6fb77becfa370065de01322fb..444e8bd37707e7273ed3f8221f75f723d2b41e3b 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 fn main() {
-    let mut x = &[1i, 2, 3, 4];
+    let mut x: &[_] = &[1i, 2, 3, 4];
 
     let mut result = vec!();
     loop {
index ffbc4e85cb685762e7bddf39dfb34facb4f1722e..de1bb02bfefc675964c5a482975ddcc741538572 100644 (file)
@@ -68,15 +68,21 @@ fn main() {
     assert_eq!(match_vecs_snoc::<uint>(&[], &[]), "both empty");
     assert_eq!(match_vecs_snoc(&[1i, 2, 3], &[]), "one empty");
 
-    assert_eq!(match_nested_vecs_cons(None, Ok(&[4u, 2u])), "None, Ok(at least two elements)");
+    assert_eq!(match_nested_vecs_cons(None, Ok::<&[_], ()>(&[4u, 2u])),
+               "None, Ok(at least two elements)");
     assert_eq!(match_nested_vecs_cons::<uint>(None, Err(())), "None, Ok(less than one element)");
-    assert_eq!(match_nested_vecs_cons::<bool>(Some(&[]), Ok(&[])), "Some(empty), Ok(empty)");
-    assert_eq!(match_nested_vecs_cons(Some(&[1i]), Err(())), "Some(non-empty), any");
-    assert_eq!(match_nested_vecs_cons(Some(&[(42i, ())]), Ok(&[(1i, ())])), "Some(non-empty), any");
+    assert_eq!(match_nested_vecs_cons::<bool>(Some::<&[_]>(&[]), Ok::<&[_], ()>(&[])),
+               "Some(empty), Ok(empty)");
+    assert_eq!(match_nested_vecs_cons(Some::<&[_]>(&[1i]), Err(())), "Some(non-empty), any");
+    assert_eq!(match_nested_vecs_cons(Some::<&[_]>(&[(42i, ())]), Ok::<&[_], ()>(&[(1i, ())])),
+               "Some(non-empty), any");
 
-    assert_eq!(match_nested_vecs_snoc(None, Ok(&[4u, 2u])), "None, Ok(at least two elements)");
+    assert_eq!(match_nested_vecs_snoc(None, Ok::<&[_], ()>(&[4u, 2u])),
+               "None, Ok(at least two elements)");
     assert_eq!(match_nested_vecs_snoc::<uint>(None, Err(())), "None, Ok(less than one element)");
-    assert_eq!(match_nested_vecs_snoc::<bool>(Some(&[]), Ok(&[])), "Some(empty), Ok(empty)");
-    assert_eq!(match_nested_vecs_snoc(Some(&[1i]), Err(())), "Some(non-empty), any");
-    assert_eq!(match_nested_vecs_snoc(Some(&[(42i, ())]), Ok(&[(1i, ())])), "Some(non-empty), any");
+    assert_eq!(match_nested_vecs_snoc::<bool>(Some::<&[_]>(&[]), Ok::<&[_], ()>(&[])),
+               "Some(empty), Ok(empty)");
+    assert_eq!(match_nested_vecs_snoc(Some::<&[_]>(&[1i]), Err(())), "Some(non-empty), any");
+    assert_eq!(match_nested_vecs_snoc(Some::<&[_]>(&[(42i, ())]), Ok::<&[_], ()>(&[(1i, ())])),
+               "Some(non-empty), any");
 }
index ed5cff36c8bb24be4f2b94f1531253552fcfdfc5..9a76beac9e5f75c49c160750bae829f82cc5e70a 100644 (file)
@@ -59,6 +59,7 @@ fn main() {
         }
     }
     unsafe {
-        assert_eq!(&[1, 2, 3], ORDER.as_slice());
+        let expected: &[_] = &[1, 2, 3];
+        assert_eq!(expected, ORDER.as_slice());
     }
 }
index 76f3b7bc280772994ae3895a57ce426f6099d3ae..e95495a42d2823bac8292c3e521469c61ee52abb 100644 (file)
@@ -72,7 +72,8 @@ fn d() {
 }
 
 fn e() {
-    match &[1i, 2, 3] {
+    let x: &[int] = &[1i, 2, 3];
+    match x {
         [1, 2] => (),
         [..] => ()
     }
index b96761f8b64933ed04952ea48c6745f57edeee6a..52e0ba89479f555340f95043ad9b916573f84a67 100644 (file)
@@ -9,9 +9,9 @@
 // except according to those terms.
 
 pub fn main() {
-    assert_eq!((vec!(0, 1)).to_string(), "[0, 1]".to_string());
+    assert_eq!((vec!(0i, 1)).to_string(), "[0, 1]".to_string());
 
-    let foo = vec!(3, 4);
+    let foo = vec!(3i, 4);
     let bar: &[int] = &[4, 5];
 
     assert_eq!(foo.to_string(), "[3, 4]".to_string());