Skip to content

Commit 030f471

Browse files
committed
auto merge of #6853 : bblum/rust/sized, r=pcwalton
r? @nikomatsakis @pcwalton
2 parents 1dd5cd9 + 5113f68 commit 030f471

File tree

17 files changed

+231
-89
lines changed

17 files changed

+231
-89
lines changed

src/etc/kate/rust.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
<item> Copy </item>
5050
<item> Send </item>
5151
<item> Owned </item>
52+
<item> Sized </item>
5253
<item> Eq </item>
5354
<item> Ord </item>
5455
<item> Num </item>

src/etc/vim/syntax/rust.vim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ syn keyword rustType size_t ptrdiff_t clock_t time_t
4444
syn keyword rustType c_longlong c_ulonglong intptr_t uintptr_t
4545
syn keyword rustType off_t dev_t ino_t pid_t mode_t ssize_t
4646

47-
syn keyword rustTrait Const Copy Send Owned " inherent traits
47+
syn keyword rustTrait Const Copy Send Owned Sized " inherent traits
4848
syn keyword rustTrait Eq Ord Num Ptr
4949
syn keyword rustTrait Drop Add Sub Mul Quot Rem Neg BitAnd BitOr
5050
syn keyword rustTrait BitXor Shl Shr Index

src/librustc/metadata/tydecode.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,9 @@ fn parse_bounds(st: @mut PState, conv: conv_did) -> ty::ParamBounds {
569569
'O' => {
570570
param_bounds.builtin_bounds.add(ty::BoundStatic);
571571
}
572+
'Z' => {
573+
param_bounds.builtin_bounds.add(ty::BoundSized);
574+
}
572575
'I' => {
573576
param_bounds.trait_bounds.push(@parse_trait_ref(st, conv));
574577
}

src/librustc/metadata/tyencode.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ fn enc_bounds(w: @io::Writer, cx: @ctxt, bs: &ty::ParamBounds) {
403403
ty::BoundCopy => w.write_char('C'),
404404
ty::BoundConst => w.write_char('K'),
405405
ty::BoundStatic => w.write_char('O'),
406+
ty::BoundSized => w.write_char('Z'),
406407
}
407408
}
408409

src/librustc/middle/lang_items.rs

Lines changed: 82 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -36,55 +36,56 @@ pub enum LangItem {
3636
ConstTraitLangItem, // 0
3737
CopyTraitLangItem, // 1
3838
OwnedTraitLangItem, // 2
39+
SizedTraitLangItem, // 3
3940

40-
DropTraitLangItem, // 3
41+
DropTraitLangItem, // 4
4142

42-
AddTraitLangItem, // 4
43-
SubTraitLangItem, // 5
44-
MulTraitLangItem, // 6
45-
DivTraitLangItem, // 7
46-
RemTraitLangItem, // 8
47-
NegTraitLangItem, // 9
48-
NotTraitLangItem, // 10
43+
AddTraitLangItem, // 5
44+
SubTraitLangItem, // 6
45+
MulTraitLangItem, // 7
46+
DivTraitLangItem, // 8
47+
RemTraitLangItem, // 9
48+
NegTraitLangItem, // 10
49+
NotTraitLangItem, // 11
4950
BitXorTraitLangItem, // 11
50-
BitAndTraitLangItem, // 12
51-
BitOrTraitLangItem, // 13
52-
ShlTraitLangItem, // 14
53-
ShrTraitLangItem, // 15
54-
IndexTraitLangItem, // 16
55-
56-
EqTraitLangItem, // 17
57-
OrdTraitLangItem, // 18
58-
59-
StrEqFnLangItem, // 19
60-
UniqStrEqFnLangItem, // 20
61-
AnnihilateFnLangItem, // 21
62-
LogTypeFnLangItem, // 22
63-
FailFnLangItem, // 23
64-
FailBoundsCheckFnLangItem, // 24
65-
ExchangeMallocFnLangItem, // 25
66-
ExchangeFreeFnLangItem, // 26
67-
MallocFnLangItem, // 27
68-
FreeFnLangItem, // 28
69-
BorrowAsImmFnLangItem, // 29
70-
BorrowAsMutFnLangItem, // 30
71-
ReturnToMutFnLangItem, // 31
72-
CheckNotBorrowedFnLangItem, // 32
73-
StrDupUniqFnLangItem, // 33
74-
RecordBorrowFnLangItem, // 34
75-
UnrecordBorrowFnLangItem, // 35
76-
77-
StartFnLangItem, // 36
51+
BitAndTraitLangItem, // 13
52+
BitOrTraitLangItem, // 14
53+
ShlTraitLangItem, // 15
54+
ShrTraitLangItem, // 16
55+
IndexTraitLangItem, // 17
56+
57+
EqTraitLangItem, // 18
58+
OrdTraitLangItem, // 19
59+
60+
StrEqFnLangItem, // 20
61+
UniqStrEqFnLangItem, // 21
62+
AnnihilateFnLangItem, // 22
63+
LogTypeFnLangItem, // 23
64+
FailFnLangItem, // 24
65+
FailBoundsCheckFnLangItem, // 25
66+
ExchangeMallocFnLangItem, // 26
67+
ExchangeFreeFnLangItem, // 27
68+
MallocFnLangItem, // 28
69+
FreeFnLangItem, // 29
70+
BorrowAsImmFnLangItem, // 30
71+
BorrowAsMutFnLangItem, // 31
72+
ReturnToMutFnLangItem, // 32
73+
CheckNotBorrowedFnLangItem, // 33
74+
StrDupUniqFnLangItem, // 34
75+
RecordBorrowFnLangItem, // 35
76+
UnrecordBorrowFnLangItem, // 36
77+
78+
StartFnLangItem, // 37
7879
}
7980

8081
pub struct LanguageItems {
81-
items: [Option<def_id>, ..37]
82+
items: [Option<def_id>, ..38]
8283
}
8384

8485
pub impl LanguageItems {
8586
pub fn new() -> LanguageItems {
8687
LanguageItems {
87-
items: [ None, ..37 ]
88+
items: [ None, ..38 ]
8889
}
8990
}
9091

@@ -97,44 +98,45 @@ pub impl LanguageItems {
9798
0 => "const",
9899
1 => "copy",
99100
2 => "owned",
100-
101-
3 => "drop",
102-
103-
4 => "add",
104-
5 => "sub",
105-
6 => "mul",
106-
7 => "div",
107-
8 => "rem",
108-
9 => "neg",
109-
10 => "not",
110-
11 => "bitxor",
111-
12 => "bitand",
112-
13 => "bitor",
113-
14 => "shl",
114-
15 => "shr",
115-
16 => "index",
116-
17 => "eq",
117-
18 => "ord",
118-
119-
19 => "str_eq",
120-
20 => "uniq_str_eq",
121-
21 => "annihilate",
122-
22 => "log_type",
123-
23 => "fail_",
124-
24 => "fail_bounds_check",
125-
25 => "exchange_malloc",
126-
26 => "exchange_free",
127-
27 => "malloc",
128-
28 => "free",
129-
29 => "borrow_as_imm",
130-
30 => "borrow_as_mut",
131-
31 => "return_to_mut",
132-
32 => "check_not_borrowed",
133-
33 => "strdup_uniq",
134-
34 => "record_borrow",
135-
35 => "unrecord_borrow",
136-
137-
36 => "start",
101+
3 => "sized",
102+
103+
4 => "drop",
104+
105+
5 => "add",
106+
6 => "sub",
107+
7 => "mul",
108+
8 => "div",
109+
9 => "rem",
110+
10 => "neg",
111+
11 => "not",
112+
12 => "bitxor",
113+
13 => "bitand",
114+
14 => "bitor",
115+
15 => "shl",
116+
16 => "shr",
117+
17 => "index",
118+
18 => "eq",
119+
19 => "ord",
120+
121+
20 => "str_eq",
122+
21 => "uniq_str_eq",
123+
22 => "annihilate",
124+
23 => "log_type",
125+
24 => "fail_",
126+
25 => "fail_bounds_check",
127+
26 => "exchange_malloc",
128+
27 => "exchange_free",
129+
28 => "malloc",
130+
29 => "free",
131+
30 => "borrow_as_imm",
132+
31 => "borrow_as_mut",
133+
32 => "return_to_mut",
134+
33 => "check_not_borrowed",
135+
34 => "strdup_uniq",
136+
35 => "record_borrow",
137+
36 => "unrecord_borrow",
138+
139+
37 => "start",
138140

139141
_ => "???"
140142
}
@@ -151,6 +153,9 @@ pub impl LanguageItems {
151153
pub fn owned_trait(&const self) -> def_id {
152154
self.items[OwnedTraitLangItem as uint].get()
153155
}
156+
pub fn sized_trait(&const self) -> def_id {
157+
self.items[SizedTraitLangItem as uint].get()
158+
}
154159

155160
pub fn drop_trait(&const self) -> def_id {
156161
self.items[DropTraitLangItem as uint].get()
@@ -267,6 +272,7 @@ fn LanguageItemCollector(crate: @crate,
267272
item_refs.insert(@~"const", ConstTraitLangItem as uint);
268273
item_refs.insert(@~"copy", CopyTraitLangItem as uint);
269274
item_refs.insert(@~"owned", OwnedTraitLangItem as uint);
275+
item_refs.insert(@~"sized", SizedTraitLangItem as uint);
270276

271277
item_refs.insert(@~"drop", DropTraitLangItem as uint);
272278

src/librustc/middle/ty.rs

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,7 @@ pub enum BuiltinBound {
682682
BoundStatic,
683683
BoundOwned,
684684
BoundConst,
685+
BoundSized,
685686
}
686687

687688
pub fn EmptyBuiltinBounds() -> BuiltinBounds {
@@ -694,6 +695,7 @@ pub fn AllBuiltinBounds() -> BuiltinBounds {
694695
set.add(BoundStatic);
695696
set.add(BoundOwned);
696697
set.add(BoundConst);
698+
set.add(BoundSized);
697699
set
698700
}
699701

@@ -1825,7 +1827,8 @@ pub impl TypeContents {
18251827
BoundCopy => self.is_copy(cx),
18261828
BoundStatic => self.is_static(cx),
18271829
BoundConst => self.is_const(cx),
1828-
BoundOwned => self.is_owned(cx)
1830+
BoundOwned => self.is_owned(cx),
1831+
BoundSized => self.is_sized(cx),
18291832
}
18301833
}
18311834

@@ -1870,6 +1873,14 @@ pub impl TypeContents {
18701873
TC_MUTABLE
18711874
}
18721875

1876+
fn is_sized(&self, cx: ctxt) -> bool {
1877+
!self.intersects(TypeContents::dynamically_sized(cx))
1878+
}
1879+
1880+
fn dynamically_sized(_cx: ctxt) -> TypeContents {
1881+
TC_DYNAMIC_SIZE
1882+
}
1883+
18731884
fn moves_by_default(&self, cx: ctxt) -> bool {
18741885
self.intersects(TypeContents::nonimplicitly_copyable(cx))
18751886
}
@@ -1943,8 +1954,11 @@ static TC_EMPTY_ENUM: TypeContents = TypeContents{bits: 0b0010_0000_0000};
19431954
/// Contains a type marked with `#[non_owned]`
19441955
static TC_NON_OWNED: TypeContents = TypeContents{bits: 0b0100_0000_0000};
19451956

1957+
/// Is a bare vector, str, function, trait, etc (only relevant at top level).
1958+
static TC_DYNAMIC_SIZE: TypeContents = TypeContents{bits: 0b1000_0000_0000};
1959+
19461960
/// All possible contents.
1947-
static TC_ALL: TypeContents = TypeContents{bits: 0b0111_1111_1111};
1961+
static TC_ALL: TypeContents = TypeContents{bits: 0b1111_1111_1111};
19481962

19491963
pub fn type_is_copyable(cx: ctxt, t: ty::t) -> bool {
19501964
type_contents(cx, t).is_copy(cx)
@@ -2028,7 +2042,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
20282042
}
20292043

20302044
ty_box(mt) => {
2031-
TC_MANAGED + nonowned(tc_mt(cx, mt, cache))
2045+
TC_MANAGED + statically_sized(nonowned(tc_mt(cx, mt, cache)))
20322046
}
20332047

20342048
ty_trait(_, _, UniqTraitStore, _) => {
@@ -2048,28 +2062,35 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
20482062

20492063
ty_rptr(r, mt) => {
20502064
borrowed_contents(r, mt.mutbl) +
2051-
nonowned(tc_mt(cx, mt, cache))
2065+
statically_sized(nonowned(tc_mt(cx, mt, cache)))
20522066
}
20532067

20542068
ty_uniq(mt) => {
2055-
TC_OWNED_POINTER + tc_mt(cx, mt, cache)
2069+
TC_OWNED_POINTER + statically_sized(tc_mt(cx, mt, cache))
20562070
}
20572071

20582072
ty_evec(mt, vstore_uniq) => {
2059-
TC_OWNED_VEC + tc_mt(cx, mt, cache)
2073+
TC_OWNED_VEC + statically_sized(tc_mt(cx, mt, cache))
20602074
}
20612075

20622076
ty_evec(mt, vstore_box) => {
2063-
TC_MANAGED + nonowned(tc_mt(cx, mt, cache))
2077+
TC_MANAGED + statically_sized(nonowned(tc_mt(cx, mt, cache)))
20642078
}
20652079

20662080
ty_evec(mt, vstore_slice(r)) => {
20672081
borrowed_contents(r, mt.mutbl) +
2068-
nonowned(tc_mt(cx, mt, cache))
2082+
statically_sized(nonowned(tc_mt(cx, mt, cache)))
20692083
}
20702084

20712085
ty_evec(mt, vstore_fixed(_)) => {
2072-
tc_mt(cx, mt, cache)
2086+
let contents = tc_mt(cx, mt, cache);
2087+
// FIXME(#6308) Uncomment this when construction of such
2088+
// vectors is prevented earlier in compilation.
2089+
// if !contents.is_sized(cx) {
2090+
// cx.sess.bug("Fixed-length vector of unsized type \
2091+
// should be impossible");
2092+
// }
2093+
contents
20732094
}
20742095

20752096
ty_estr(vstore_box) => {
@@ -2144,7 +2165,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
21442165
}
21452166

21462167
ty_opaque_box => TC_MANAGED,
2147-
ty_unboxed_vec(mt) => tc_mt(cx, mt, cache),
2168+
ty_unboxed_vec(mt) => TC_DYNAMIC_SIZE + tc_mt(cx, mt, cache),
21482169
ty_opaque_closure_ptr(sigil) => {
21492170
match sigil {
21502171
ast::BorrowedSigil => TC_BORROWED_POINTER,
@@ -2211,6 +2232,14 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
22112232
TypeContents {bits: pointee.bits & mask}
22122233
}
22132234

2235+
fn statically_sized(pointee: TypeContents) -> TypeContents {
2236+
/*!
2237+
* If a dynamically-sized type is found behind a pointer, we should
2238+
* restore the 'Sized' kind to the pointer and things that contain it.
2239+
*/
2240+
TypeContents {bits: pointee.bits & !TC_DYNAMIC_SIZE.bits}
2241+
}
2242+
22142243
fn closure_contents(cty: &ClosureTy) -> TypeContents {
22152244
let st = match cty.sigil {
22162245
ast::BorrowedSigil => TC_BORROWED_POINTER,
@@ -2239,6 +2268,8 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
22392268
BoundStatic => TypeContents::nonstatic(cx),
22402269
BoundOwned => TypeContents::nonowned(cx),
22412270
BoundConst => TypeContents::nonconst(cx),
2271+
// The dynamic-size bit can be removed at pointer-level, etc.
2272+
BoundSized => TypeContents::dynamically_sized(cx),
22422273
};
22432274
}
22442275

@@ -2508,6 +2539,21 @@ pub fn type_is_enum(ty: t) -> bool {
25082539
}
25092540
}
25102541

2542+
// Is the type's representation size known at compile time?
2543+
pub fn type_is_sized(cx: ctxt, ty: ty::t) -> bool {
2544+
match get(ty).sty {
2545+
// FIXME(#6308) add trait, vec, str, etc here.
2546+
ty_param(p) => {
2547+
let param_def = cx.ty_param_defs.get(&p.def_id.node);
2548+
if param_def.bounds.builtin_bounds.contains_elem(BoundSized) {
2549+
return true;
2550+
}
2551+
return false;
2552+
},
2553+
_ => return true,
2554+
}
2555+
}
2556+
25112557
// Whether a type is enum like, that is a enum type with only nullary
25122558
// constructors
25132559
pub fn type_is_c_like_enum(cx: ctxt, ty: t) -> bool {

0 commit comments

Comments
 (0)