]> git.lizzy.rs Git - rust.git/commitdiff
Forbid the Sized bound on unsized types
authorNick Cameron <ncameron@mozilla.com>
Thu, 28 Aug 2014 06:50:00 +0000 (18:50 +1200)
committerNick Cameron <ncameron@mozilla.com>
Thu, 28 Aug 2014 06:50:00 +0000 (18:50 +1200)
closes #16800

src/librustc/diagnostics.rs
src/librustc/middle/kind.rs
src/test/compile-fail/bad-sized.rs [new file with mode: 0644]

index 77e73c46c402cf2f6ac23962b2dc4d80124759be..2698ac94a99c6f0fd3ce3db217d89206b90c5ff2 100644 (file)
     E0155,
     E0156,
     E0157,
-    E0158
+    E0158,
+    E0159
 )
index b96a75cba94800cd136e98b96d5ccc97e0d5cb1e..ee2d73dda95231e570bc6c31cd6a0ea01673c081 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
 use middle::freevars::freevar_entry;
 use middle::freevars;
 use middle::subst;
@@ -593,15 +592,15 @@ fn check_ty(cx: &mut Context, aty: &Ty) {
     match aty.node {
         TyPath(_, _, id) => {
             match cx.tcx.item_substs.borrow().find(&id) {
-                None => { }
+                None => {}
                 Some(ref item_substs) => {
                     let def_map = cx.tcx.def_map.borrow();
                     let did = def_map.get_copy(&id).def_id();
-                    let generics = ty::lookup_item_type(cx.tcx, did).generics;
-                    for def in generics.types.iter() {
+                    let ty = ty::lookup_item_type(cx.tcx, did);
+                    for def in ty.generics.types.iter() {
                         let ty = *item_substs.substs.types.get(def.space,
                                                                def.index);
-                        check_typaram_bounds(cx, aty.span, ty, def)
+                        check_typaram_bounds(cx, aty.span, ty, def);
                     }
                 }
             }
@@ -645,6 +644,20 @@ pub fn check_typaram_bounds(cx: &Context,
     });
 }
 
+// Check that the programmer has not added the `Sized` bound to a trait type
+// which would fool the compiler into thinking that trait types are sized, when
+// they are really unsized.
+fn check_false_sized(cx: &Context, sp: Span, ty: ty::t) {
+    match ty::get(ty).sty {
+        ty::ty_trait(..) if ty::type_is_sized(cx.tcx, ty) => {
+            span_err!(cx.tcx.sess, sp, E0159,
+                      "explicitly adding `Sized` bound to an unsized type `{}`",
+                       ty_to_string(cx.tcx, ty));
+        }
+        _ => {}
+    }
+}
+
 fn check_bounds_on_structs_or_enums_in_type_if_possible(cx: &mut Context,
                                                         span: Span,
                                                         ty: ty::t) {
@@ -674,7 +687,8 @@ fn check_bounds_on_structs_or_enums_in_type_if_possible(cx: &mut Context,
                                                   .zip(polytype.generics
                                                                .types
                                                                .iter()) {
-                    check_typaram_bounds(cx, span, *ty, type_param_def)
+                    check_typaram_bounds(cx, span, *ty, type_param_def);
+                    check_false_sized(cx, span, *ty);
                 }
 
                 // Check trait bounds.
@@ -702,6 +716,7 @@ fn check_bounds_on_structs_or_enums_in_type_if_possible(cx: &mut Context,
                                             cx.tcx)).as_slice());
                 })
             }
+            ty::ty_uniq(ty) => check_false_sized(cx, span, ty),
             _ => {}
         }
     });
diff --git a/src/test/compile-fail/bad-sized.rs b/src/test/compile-fail/bad-sized.rs
new file mode 100644 (file)
index 0000000..e0a929d
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2012 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.
+
+use std::cell::RefCell;
+
+trait Trait {}
+
+pub fn main() {
+    let x: Vec<Trait + Sized> = Vec::new();
+    //~^ ERROR explicitly adding `Sized` bound to an unsized type `Trait+Sized`
+    //~^^ ERROR explicitly adding `Sized` bound to an unsized type `Trait+Sized`
+    let x: Vec<Box<Trait + Sized>> = Vec::new();
+    //~^ ERROR explicitly adding `Sized` bound to an unsized type `Trait+Sized`
+    //~^^ ERROR explicitly adding `Sized` bound to an unsized type `Trait+Sized`
+    let x: Vec<Box<RefCell<Trait + Sized>>> = Vec::new();
+    //~^ ERROR explicitly adding `Sized` bound to an unsized type `Trait+Sized`
+    //~^^ ERROR explicitly adding `Sized` bound to an unsized type `Trait+Sized`
+}