Skip to content

Commit 5729d9b

Browse files
committed
Review changes
1 parent 0540a59 commit 5729d9b

File tree

6 files changed

+44
-51
lines changed

6 files changed

+44
-51
lines changed

src/librustc/middle/ty.rs

+1-24
Original file line numberDiff line numberDiff line change
@@ -2590,30 +2590,7 @@ pub fn type_is_machine(ty: t) -> bool {
25902590
// Is the type's representation size known at compile time?
25912591
#[allow(dead_code)] // leaving in for DST
25922592
pub fn type_is_sized(cx: &ctxt, ty: ty::t) -> bool {
2593-
match get(ty).sty {
2594-
ty_param(tp) => {
2595-
assert_eq!(tp.def_id.krate, ast::LOCAL_CRATE);
2596-
2597-
let ty_param_defs = cx.ty_param_defs.borrow();
2598-
let param_def = ty_param_defs.get(&tp.def_id.node);
2599-
param_def.bounds.builtin_bounds.contains_elem(BoundSized)
2600-
},
2601-
ty_self(def_id) => {
2602-
let trait_def = lookup_trait_def(cx, def_id);
2603-
trait_def.bounds.contains_elem(BoundSized)
2604-
},
2605-
ty_struct(def_id, ref substs) => {
2606-
let flds = lookup_struct_fields(cx, def_id);
2607-
let mut tps = flds.iter().map(|f| lookup_field_type(cx, def_id, f.id, substs));
2608-
!tps.any(|ty| !type_is_sized(cx, ty))
2609-
}
2610-
ty_tup(ref ts) => !ts.iter().any(|t| !type_is_sized(cx, *t)),
2611-
ty_enum(did, ref substs) => {
2612-
let variants = substd_enum_variants(cx, did, substs);
2613-
!variants.iter().any(|v| v.args.iter().any(|t| !type_is_sized(cx, *t)))
2614-
}
2615-
_ => true
2616-
}
2593+
type_contents(cx, ty).is_sized(cx)
26172594
}
26182595

26192596
// Whether a type is enum like, that is an enum type with only nullary

src/librustc/middle/typeck/check/mod.rs

+27-12
Original file line numberDiff line numberDiff line change
@@ -576,15 +576,20 @@ fn check_for_field_shadowing(tcx: &ty::ctxt,
576576
}
577577

578578
fn check_fields_sized(tcx: &ty::ctxt,
579-
struct_def: @ast::StructDef) {
579+
struct_def: &ast::StructDef) {
580580
let len = struct_def.fields.len();
581-
for i in range(0, len) {
582-
let f = struct_def.fields.get(i);
581+
if len == 0 {
582+
return;
583+
}
584+
for f in struct_def.fields.slice_to(len - 1).iter() {
583585
let t = ty::node_id_to_type(tcx, f.node.id);
584-
if !ty::type_is_sized(tcx, t) && i < (len - 1) {
586+
if !ty::type_is_sized(tcx, t) {
585587
match f.node.kind {
586588
ast::NamedField(ident, _) => {
587-
tcx.sess.span_err(f.span, format!("type of field {} is dynamically sized",
589+
tcx.sess.span_err(f.span, format!("type `{}` is dynamically sized. \
590+
dynamically sized types may only \
591+
appear as the type of the final \
592+
field in a struct",
588593
token::get_ident(ident)));
589594
}
590595
ast::UnnamedField(_) => {
@@ -3519,16 +3524,18 @@ pub fn check_representable(tcx: &ty::ctxt,
35193524
/// is representable, but not instantiable.
35203525
pub fn check_instantiable(tcx: &ty::ctxt,
35213526
sp: Span,
3522-
item_id: ast::NodeId) -> bool {
3527+
item_id: ast::NodeId)
3528+
-> bool {
35233529
let item_ty = ty::node_id_to_type(tcx, item_id);
35243530
if !ty::is_instantiable(tcx, item_ty) {
35253531
tcx.sess.span_err(sp, format!("this type cannot be instantiated \
35263532
without an instance of itself; \
35273533
consider using `Option<{}>`",
35283534
ppaux::ty_to_str(tcx, item_ty)));
3529-
return false
3535+
false
3536+
} else {
3537+
true
35303538
}
3531-
true
35323539
}
35333540

35343541
pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
@@ -3567,12 +3574,20 @@ pub fn check_enum_variants_sized(ccx: &CrateCtxt,
35673574
ast::TupleVariantKind(ref args) if args.len() > 0 => {
35683575
let ctor_ty = ty::node_id_to_type(ccx.tcx, v.node.id);
35693576
let arg_tys: Vec<ty::t> = ty::ty_fn_args(ctor_ty).iter().map(|a| *a).collect();
3570-
for i in range(0, args.len()) {
3571-
let t = arg_tys.get(i);
3577+
let len = arg_tys.len();
3578+
if len == 0 {
3579+
return;
3580+
}
3581+
for (i, t) in arg_tys.slice_to(len - 1).iter().enumerate() {
35723582
// Allow the last field in an enum to be unsized.
3573-
if !ty::type_is_sized(ccx.tcx, *t) && i < args.len() -1 {
3583+
// We want to do this so that we can support smart pointers.
3584+
// A struct value with an unsized final field is itself
3585+
// unsized and we must track this in the type system.
3586+
if !ty::type_is_sized(ccx.tcx, *t) {
35743587
ccx.tcx.sess.span_err(args.get(i).ty.span,
3575-
format!("type {} is dynamically sized",
3588+
format!("type `{}` is dynamically sized. \
3589+
dynamically sized types may only \
3590+
appear as the final type in a variant",
35763591
ppaux::ty_to_str(ccx.tcx, *t)));
35773592
}
35783593
}

src/librustc/middle/typeck/collect.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -1141,14 +1141,12 @@ fn ty_generics(ccx: &CrateCtxt,
11411141
param_bounds.trait_bounds.as_slice(),
11421142
|trait_ref| {
11431143
let trait_def = ty::lookup_trait_def(tcx, trait_ref.def_id);
1144-
for bound in trait_def.bounds.iter() {
1145-
if bound == ty::BoundSized {
1146-
tcx.sess.span_err(span,
1147-
format!("incompatible bounds on type parameter {}, \
1148-
bound {} does not allow unsized type",
1149-
token::get_ident(ident),
1150-
ppaux::trait_ref_to_str(tcx, trait_ref)));
1151-
}
1144+
if trait_def.bounds.contains_elem(ty::BoundSized) {
1145+
tcx.sess.span_err(span,
1146+
format!("incompatible bounds on type parameter {}, \
1147+
bound {} does not allow unsized type",
1148+
token::get_ident(ident),
1149+
ppaux::trait_ref_to_str(tcx, &*trait_ref)));
11521150
}
11531151
true
11541152
});

src/libsyntax/print/pprust.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,8 @@ impl<'a> State<'a> {
678678
try!(self.print_ident(item.ident));
679679
try!(self.print_generics(generics));
680680
if *sized == ast::DynSize {
681-
try!(self.word_space("for type"));
681+
try!(space(&mut self.s));
682+
try!(word(&mut self.s, "for type"));
682683
}
683684
if traits.len() != 0u {
684685
try!(word(&mut self.s, ":"));

src/test/compile-fail/unsized5.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,18 @@ fn f6<type X: T>(x: &X) {
2323
}*/
2424

2525
struct S1<type X> {
26-
f1: X, //~ ERROR type of field f1 is dynamically sized
26+
f1: X, //~ ERROR type `f1` is dynamically sized. dynamically sized types may only appear as the
2727
f2: int,
2828
}
2929
struct S2<type X> {
3030
f: int,
31-
g: X, //~ ERROR type of field g is dynamically sized
31+
g: X, //~ ERROR type `g` is dynamically sized. dynamically sized types may only appear as the ty
3232
h: int,
3333
}
3434

3535
enum E<type X> {
36-
V1(X, int), //~ERROR type X is dynamically sized
37-
V2{f1: X, f: int}, //~ERROR type of field f1 is dynamically sized
36+
V1(X, int), //~ERROR type `X` is dynamically sized. dynamically sized types may only appear as t
37+
V2{f1: X, f: int}, //~ERROR type `f1` is dynamically sized. dynamically sized types may only app
3838
}
3939

4040
pub fn main() {

src/test/run-pass/unsized2.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ trait T4<X> {
6666
fn m2(x: &T5<X>);
6767
}
6868
trait T5<type X> {
69-
fn m1(x: &T4<X>); // not an error (for now)
69+
// not an error (for now)
70+
fn m1(x: &T4<X>);
7071
fn m2(x: &T5<X>);
7172
}
7273

@@ -75,7 +76,8 @@ trait T6<X: T> {
7576
fn m2(x: &T5<X>);
7677
}
7778
trait T7<type X: T> {
78-
fn m1(x: &T4<X>); // not an error (for now)
79+
// not an error (for now)
80+
fn m1(x: &T4<X>);
7981
fn m2(x: &T5<X>);
8082
}
8183

0 commit comments

Comments
 (0)