]> git.lizzy.rs Git - rust.git/commitdiff
Add 'Sized' builtin kind; doesn't do anything yet
authorBen Blum <bblum@andrew.cmu.edu>
Fri, 31 May 2013 00:03:01 +0000 (20:03 -0400)
committerBen Blum <bblum@andrew.cmu.edu>
Fri, 31 May 2013 01:41:41 +0000 (21:41 -0400)
src/librustc/metadata/tydecode.rs
src/librustc/metadata/tyencode.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/ty.rs
src/librustc/middle/typeck/astconv.rs
src/librustc/util/ppaux.rs
src/libstd/kinds.rs
src/libstd/prelude.rs

index f26a52cd8cd333503aad8f1c3ba6b569b7ec8bd4..33e033ace483560174a03a5677c3594f9338dedb 100644 (file)
@@ -569,6 +569,9 @@ fn parse_bounds(st: @mut PState, conv: conv_did) -> ty::ParamBounds {
             'O' => {
                 param_bounds.builtin_bounds.add(ty::BoundStatic);
             }
+            'Z' => {
+                param_bounds.builtin_bounds.add(ty::BoundSized);
+            }
             'I' => {
                 param_bounds.trait_bounds.push(@parse_trait_ref(st, conv));
             }
index eb76b15dd28e8c5130f8f28383979811234e3515..947c68634148e57082c2bacbf9604f1a7b432d5e 100644 (file)
@@ -403,6 +403,7 @@ fn enc_bounds(w: @io::Writer, cx: @ctxt, bs: &ty::ParamBounds) {
             ty::BoundCopy => w.write_char('C'),
             ty::BoundConst => w.write_char('K'),
             ty::BoundStatic => w.write_char('O'),
+            ty::BoundSized => w.write_char('Z'),
         }
     }
 
index 3a0f6f5c10aa4e8c599278d76d2822e483ee1da0..be1aa957666fa6d0dcfd2eac88b6ea5e82878f2e 100644 (file)
@@ -36,55 +36,56 @@ pub enum LangItem {
     ConstTraitLangItem,         // 0
     CopyTraitLangItem,          // 1
     OwnedTraitLangItem,         // 2
+    SizedTraitLangItem,         // 3
 
-    DropTraitLangItem,          // 3
+    DropTraitLangItem,          // 4
 
-    AddTraitLangItem,           // 4
-    SubTraitLangItem,           // 5
-    MulTraitLangItem,           // 6
-    DivTraitLangItem,           // 7
-    RemTraitLangItem,           // 8
-    NegTraitLangItem,           // 9
-    NotTraitLangItem,           // 10
+    AddTraitLangItem,           // 5
+    SubTraitLangItem,           // 6
+    MulTraitLangItem,           // 7
+    DivTraitLangItem,           // 8
+    RemTraitLangItem,           // 9
+    NegTraitLangItem,           // 10
+    NotTraitLangItem,           // 11
     BitXorTraitLangItem,        // 11
-    BitAndTraitLangItem,        // 12
-    BitOrTraitLangItem,         // 13
-    ShlTraitLangItem,           // 14
-    ShrTraitLangItem,           // 15
-    IndexTraitLangItem,         // 16
-
-    EqTraitLangItem,            // 17
-    OrdTraitLangItem,           // 18
-
-    StrEqFnLangItem,            // 19
-    UniqStrEqFnLangItem,        // 20
-    AnnihilateFnLangItem,       // 21
-    LogTypeFnLangItem,          // 22
-    FailFnLangItem,             // 23
-    FailBoundsCheckFnLangItem,  // 24
-    ExchangeMallocFnLangItem,   // 25
-    ExchangeFreeFnLangItem,     // 26
-    MallocFnLangItem,           // 27
-    FreeFnLangItem,             // 28
-    BorrowAsImmFnLangItem,      // 29
-    BorrowAsMutFnLangItem,      // 30
-    ReturnToMutFnLangItem,      // 31
-    CheckNotBorrowedFnLangItem, // 32
-    StrDupUniqFnLangItem,       // 33
-    RecordBorrowFnLangItem,     // 34
-    UnrecordBorrowFnLangItem,   // 35
-
-    StartFnLangItem,            // 36
+    BitAndTraitLangItem,        // 13
+    BitOrTraitLangItem,         // 14
+    ShlTraitLangItem,           // 15
+    ShrTraitLangItem,           // 16
+    IndexTraitLangItem,         // 17
+
+    EqTraitLangItem,            // 18
+    OrdTraitLangItem,           // 19
+
+    StrEqFnLangItem,            // 20
+    UniqStrEqFnLangItem,        // 21
+    AnnihilateFnLangItem,       // 22
+    LogTypeFnLangItem,          // 23
+    FailFnLangItem,             // 24
+    FailBoundsCheckFnLangItem,  // 25
+    ExchangeMallocFnLangItem,   // 26
+    ExchangeFreeFnLangItem,     // 27
+    MallocFnLangItem,           // 28
+    FreeFnLangItem,             // 29
+    BorrowAsImmFnLangItem,      // 30
+    BorrowAsMutFnLangItem,      // 31
+    ReturnToMutFnLangItem,      // 32
+    CheckNotBorrowedFnLangItem, // 33
+    StrDupUniqFnLangItem,       // 34
+    RecordBorrowFnLangItem,     // 35
+    UnrecordBorrowFnLangItem,   // 36
+
+    StartFnLangItem,            // 37
 }
 
 pub struct LanguageItems {
-    items: [Option<def_id>, ..37]
+    items: [Option<def_id>, ..38]
 }
 
 pub impl LanguageItems {
     pub fn new() -> LanguageItems {
         LanguageItems {
-            items: [ None, ..37 ]
+            items: [ None, ..38 ]
         }
     }
 
@@ -97,44 +98,45 @@ pub fn item_name(index: uint) -> &'static str {
             0  => "const",
             1  => "copy",
             2  => "owned",
-
-            3  => "drop",
-
-            4  => "add",
-            5  => "sub",
-            6  => "mul",
-            7  => "div",
-            8  => "rem",
-            9 => "neg",
-            10 => "not",
-            11 => "bitxor",
-            12 => "bitand",
-            13 => "bitor",
-            14 => "shl",
-            15 => "shr",
-            16 => "index",
-            17 => "eq",
-            18 => "ord",
-
-            19 => "str_eq",
-            20 => "uniq_str_eq",
-            21 => "annihilate",
-            22 => "log_type",
-            23 => "fail_",
-            24 => "fail_bounds_check",
-            25 => "exchange_malloc",
-            26 => "exchange_free",
-            27 => "malloc",
-            28 => "free",
-            29 => "borrow_as_imm",
-            30 => "borrow_as_mut",
-            31 => "return_to_mut",
-            32 => "check_not_borrowed",
-            33 => "strdup_uniq",
-            34 => "record_borrow",
-            35 => "unrecord_borrow",
-
-            36 => "start",
+            3  => "sized",
+
+            4  => "drop",
+
+            5  => "add",
+            6  => "sub",
+            7  => "mul",
+            8  => "div",
+            9  => "rem",
+            10 => "neg",
+            11 => "not",
+            12 => "bitxor",
+            13 => "bitand",
+            14 => "bitor",
+            15 => "shl",
+            16 => "shr",
+            17 => "index",
+            18 => "eq",
+            19 => "ord",
+
+            20 => "str_eq",
+            21 => "uniq_str_eq",
+            22 => "annihilate",
+            23 => "log_type",
+            24 => "fail_",
+            25 => "fail_bounds_check",
+            26 => "exchange_malloc",
+            27 => "exchange_free",
+            28 => "malloc",
+            29 => "free",
+            30 => "borrow_as_imm",
+            31 => "borrow_as_mut",
+            32 => "return_to_mut",
+            33 => "check_not_borrowed",
+            34 => "strdup_uniq",
+            35 => "record_borrow",
+            36 => "unrecord_borrow",
+
+            37 => "start",
 
             _ => "???"
         }
@@ -151,6 +153,9 @@ pub fn copy_trait(&const self) -> def_id {
     pub fn owned_trait(&const self) -> def_id {
         self.items[OwnedTraitLangItem as uint].get()
     }
+    pub fn sized_trait(&const self) -> def_id {
+        self.items[SizedTraitLangItem as uint].get()
+    }
 
     pub fn drop_trait(&const self) -> def_id {
         self.items[DropTraitLangItem as uint].get()
@@ -267,6 +272,7 @@ fn LanguageItemCollector(crate: @crate,
     item_refs.insert(@~"const", ConstTraitLangItem as uint);
     item_refs.insert(@~"copy", CopyTraitLangItem as uint);
     item_refs.insert(@~"owned", OwnedTraitLangItem as uint);
+    item_refs.insert(@~"sized", SizedTraitLangItem as uint);
 
     item_refs.insert(@~"drop", DropTraitLangItem as uint);
 
index 8815259b3cc7b9c5258966b1caf8195b8effb427..b0903f78db5627395344d09c49eec55139ee5d26 100644 (file)
@@ -683,6 +683,7 @@ pub enum BuiltinBound {
     BoundStatic,
     BoundOwned,
     BoundConst,
+    BoundSized,
 }
 
 pub fn EmptyBuiltinBounds() -> BuiltinBounds {
@@ -695,6 +696,7 @@ pub fn AllBuiltinBounds() -> BuiltinBounds {
     set.add(BoundStatic);
     set.add(BoundOwned);
     set.add(BoundConst);
+    set.add(BoundSized);
     set
 }
 
@@ -1826,7 +1828,8 @@ fn meets_bound(&self, cx: ctxt, bb: BuiltinBound) -> bool {
             BoundCopy => self.is_copy(cx),
             BoundStatic => self.is_static(cx),
             BoundConst => self.is_const(cx),
-            BoundOwned => self.is_owned(cx)
+            BoundOwned => self.is_owned(cx),
+            BoundSized => self.is_sized(cx),
         }
     }
 
@@ -1871,6 +1874,14 @@ fn nonconst(_cx: ctxt) -> TypeContents {
         TC_MUTABLE
     }
 
+    fn is_sized(&self, cx: ctxt) -> bool {
+        !self.intersects(TypeContents::dynamically_sized(cx))
+    }
+
+    fn dynamically_sized(_cx: ctxt) -> TypeContents {
+        TC_DYNAMIC_SIZE
+    }
+
     fn moves_by_default(&self, cx: ctxt) -> bool {
         self.intersects(TypeContents::nonimplicitly_copyable(cx))
     }
@@ -1944,8 +1955,11 @@ fn to_str(&self) -> ~str {
 /// Contains a type marked with `#[non_owned]`
 static TC_NON_OWNED: TypeContents =        TypeContents{bits: 0b0100_0000_0000};
 
+/// Is a bare vector, str, function, trait, etc (only relevant at top level).
+static TC_DYNAMIC_SIZE: TypeContents =     TypeContents{bits: 0b1000_0000_0000};
+
 /// All possible contents.
-static TC_ALL: TypeContents =              TypeContents{bits: 0b0111_1111_1111};
+static TC_ALL: TypeContents =              TypeContents{bits: 0b1111_1111_1111};
 
 pub fn type_is_copyable(cx: ctxt, t: ty::t) -> bool {
     type_contents(cx, t).is_copy(cx)
@@ -2029,7 +2043,7 @@ fn tc_ty(cx: ctxt,
             }
 
             ty_box(mt) => {
-                TC_MANAGED + nonowned(tc_mt(cx, mt, cache))
+                TC_MANAGED + statically_sized(nonowned(tc_mt(cx, mt, cache)))
             }
 
             ty_trait(_, _, UniqTraitStore, _) => {
@@ -2049,28 +2063,35 @@ fn tc_ty(cx: ctxt,
 
             ty_rptr(r, mt) => {
                 borrowed_contents(r, mt.mutbl) +
-                    nonowned(tc_mt(cx, mt, cache))
+                    statically_sized(nonowned(tc_mt(cx, mt, cache)))
             }
 
             ty_uniq(mt) => {
-                TC_OWNED_POINTER + tc_mt(cx, mt, cache)
+                TC_OWNED_POINTER + statically_sized(tc_mt(cx, mt, cache))
             }
 
             ty_evec(mt, vstore_uniq) => {
-                TC_OWNED_VEC + tc_mt(cx, mt, cache)
+                TC_OWNED_VEC + statically_sized(tc_mt(cx, mt, cache))
             }
 
             ty_evec(mt, vstore_box) => {
-                TC_MANAGED + nonowned(tc_mt(cx, mt, cache))
+                TC_MANAGED + statically_sized(nonowned(tc_mt(cx, mt, cache)))
             }
 
             ty_evec(mt, vstore_slice(r)) => {
                 borrowed_contents(r, mt.mutbl) +
-                    nonowned(tc_mt(cx, mt, cache))
+                    statically_sized(nonowned(tc_mt(cx, mt, cache)))
             }
 
             ty_evec(mt, vstore_fixed(_)) => {
-                tc_mt(cx, mt, cache)
+                let contents = tc_mt(cx, mt, cache);
+                // FIXME(#6308) Uncomment this when construction of such
+                // vectors is prevented earlier in compilation.
+                // if !contents.is_sized(cx) {
+                //     cx.sess.bug("Fixed-length vector of unsized type \
+                //                  should be impossible");
+                // }
+                contents
             }
 
             ty_estr(vstore_box) => {
@@ -2145,7 +2166,7 @@ fn tc_ty(cx: ctxt,
             }
 
             ty_opaque_box => TC_MANAGED,
-            ty_unboxed_vec(mt) => tc_mt(cx, mt, cache),
+            ty_unboxed_vec(mt) => TC_DYNAMIC_SIZE + tc_mt(cx, mt, cache),
             ty_opaque_closure_ptr(sigil) => {
                 match sigil {
                     ast::BorrowedSigil => TC_BORROWED_POINTER,
@@ -2212,6 +2233,14 @@ fn nonowned(pointee: TypeContents) -> TypeContents {
         TypeContents {bits: pointee.bits & mask}
     }
 
+    fn statically_sized(pointee: TypeContents) -> TypeContents {
+        /*!
+         * If a dynamically-sized type is found behind a pointer, we should
+         * restore the 'Sized' kind to the pointer and things that contain it.
+         */
+        TypeContents {bits: pointee.bits & !TC_DYNAMIC_SIZE.bits}
+    }
+
     fn closure_contents(cty: &ClosureTy) -> TypeContents {
         let st = match cty.sigil {
             ast::BorrowedSigil => TC_BORROWED_POINTER,
@@ -2240,6 +2269,8 @@ fn type_param_def_to_contents(cx: ctxt,
                 BoundStatic => TypeContents::nonstatic(cx),
                 BoundOwned => TypeContents::nonowned(cx),
                 BoundConst => TypeContents::nonconst(cx),
+                // The dynamic-size bit can be removed at pointer-level, etc.
+                BoundSized => TypeContents::dynamically_sized(cx),
             };
         }
 
@@ -2509,6 +2540,21 @@ pub fn type_is_enum(ty: t) -> bool {
     }
 }
 
+// Is the type's representation size known at compile time?
+pub fn type_is_sized(cx: ctxt, ty: ty::t) -> bool {
+    match get(ty).sty {
+        // FIXME(#6308) add trait, vec, str, etc here.
+        ty_param(p) => {
+            let param_def = cx.ty_param_defs.get(&p.def_id.node);
+            if param_def.bounds.builtin_bounds.contains_elem(BoundSized) {
+                return true;
+            }
+            return false;
+        },
+        _ => return true,
+    }
+}
+
 // Whether a type is enum like, that is a enum type with only nullary
 // constructors
 pub fn type_is_c_like_enum(cx: ctxt, ty: t) -> bool {
index 390ba2dc0de530ffb7f4f6d7b5ac446fd56b90aa..57e2a562b20f5da674c6cd3a063f8100e8daa6b8 100644 (file)
@@ -782,6 +782,9 @@ pub fn try_add_builtin_trait(tcx: ty::ctxt,
     } else if trait_def_id == li.const_trait() {
         builtin_bounds.add(ty::BoundConst);
         true
+    } else if trait_def_id == li.sized_trait() {
+        builtin_bounds.add(ty::BoundSized);
+        true
     } else {
         false
     }
index 69e0f85522abb5593788fa550db0014ae67e454b..5c5cc98bb9c3a28711fc4f73b2f010dfcbaf4fc5 100644 (file)
@@ -563,6 +563,7 @@ fn repr(&self, tcx: ctxt) -> ~str {
                 ty::BoundStatic => ~"'static",
                 ty::BoundOwned => ~"Owned",
                 ty::BoundConst => ~"Const",
+                ty::BoundSized => ~"Sized",
             });
         }
         for self.trait_bounds.each |t| {
@@ -767,7 +768,8 @@ fn user_string(&self, _tcx: ctxt) -> ~str {
             ty::BoundCopy => ~"Copy",
             ty::BoundStatic => ~"'static",
             ty::BoundOwned => ~"Owned",
-            ty::BoundConst => ~"Const"
+            ty::BoundConst => ~"Const",
+            ty::BoundSized => ~"Sized",
         }
     }
 }
index b6c22f29c3e5a35e0e7d6533b40fe663a1dd6bac..05c963a32cc732f0741b198bff7fb2b1b2bf5884 100644 (file)
@@ -53,3 +53,8 @@ pub trait Owned {
 pub trait Const {
     // Empty.
 }
+
+#[lang="sized"]
+pub trait Sized {
+    // Empty.
+}
index 07864ce419e628ae9be5a543279b0cb0a57fe603..4dcef60781f5df28f329e2a8cef6644a3b62dc41 100644 (file)
@@ -12,7 +12,7 @@
 
 // Reexported core operators
 pub use either::{Either, Left, Right};
-pub use kinds::{Const, Copy, Owned};
+pub use kinds::{Const, Copy, Owned, Sized};
 pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
 pub use ops::{BitAnd, BitOr, BitXor};
 pub use ops::{Drop};