Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add builtin Sized kind and a few basic tests #6853

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/etc/kate/rust.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
<item> Copy </item>
<item> Send </item>
<item> Owned </item>
<item> Sized </item>
<item> Eq </item>
<item> Ord </item>
<item> Num </item>
Expand Down
2 changes: 1 addition & 1 deletion src/etc/vim/syntax/rust.vim
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ syn keyword rustType size_t ptrdiff_t clock_t time_t
syn keyword rustType c_longlong c_ulonglong intptr_t uintptr_t
syn keyword rustType off_t dev_t ino_t pid_t mode_t ssize_t

syn keyword rustTrait Const Copy Send Owned " inherent traits
syn keyword rustTrait Const Copy Send Owned Sized " inherent traits
syn keyword rustTrait Eq Ord Num Ptr
syn keyword rustTrait Drop Add Sub Mul Quot Rem Neg BitAnd BitOr
syn keyword rustTrait BitXor Shl Shr Index
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/metadata/tydecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc/metadata/tyencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
}
}

Expand Down
158 changes: 82 additions & 76 deletions src/librustc/middle/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 ]
}
}

Expand All @@ -97,44 +98,45 @@ pub impl LanguageItems {
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",

_ => "???"
}
Expand All @@ -151,6 +153,9 @@ pub impl LanguageItems {
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()
Expand Down Expand Up @@ -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);

Expand Down
66 changes: 56 additions & 10 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,7 @@ pub enum BuiltinBound {
BoundStatic,
BoundOwned,
BoundConst,
BoundSized,
}

pub fn EmptyBuiltinBounds() -> BuiltinBounds {
Expand All @@ -695,6 +696,7 @@ pub fn AllBuiltinBounds() -> BuiltinBounds {
set.add(BoundStatic);
set.add(BoundOwned);
set.add(BoundConst);
set.add(BoundSized);
set
}

Expand Down Expand Up @@ -1826,7 +1828,8 @@ pub impl TypeContents {
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),
}
}

Expand Down Expand Up @@ -1871,6 +1874,14 @@ pub impl 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))
}
Expand Down Expand Up @@ -1944,8 +1955,11 @@ static TC_EMPTY_ENUM: TypeContents = TypeContents{bits: 0b0010_0000_0000};
/// 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)
Expand Down Expand Up @@ -2029,7 +2043,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
}

ty_box(mt) => {
TC_MANAGED + nonowned(tc_mt(cx, mt, cache))
TC_MANAGED + statically_sized(nonowned(tc_mt(cx, mt, cache)))
}

ty_trait(_, _, UniqTraitStore, _) => {
Expand All @@ -2049,28 +2063,35 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {

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) => {
Expand Down Expand Up @@ -2145,7 +2166,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
}

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,
Expand Down Expand Up @@ -2212,6 +2233,14 @@ pub fn type_contents(cx: ctxt, ty: t) -> 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,
Expand Down Expand Up @@ -2240,6 +2269,8 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
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),
};
}

Expand Down Expand Up @@ -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 {
Expand Down
Loading