about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Koropoff <bkoropoff@gmail.com>2014-09-27 12:17:12 -0700
committerBrian Koropoff <bkoropoff@gmail.com>2014-09-28 17:57:34 -0700
commitca15637b7ce18975113a8a8b022e97d499ad6689 (patch)
treebdccf11ce63bc1d8eb0ac572e63cdae8816d4a1e
parent34dfa45718d9d40361dadf0abf9c3dc5cc0b0381 (diff)
Reject casts to unsized types and suggest use of reference or box
This prevents ICEs or less helpful diagnostics if typeck proceeds
further.  Closes issue #17441
-rw-r--r--src/librustc/middle/typeck/check/mod.rs31
1 files changed, 31 insertions, 0 deletions
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index c7be2430cc9..d4c38d48a8c 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -1405,6 +1405,37 @@ fn check_cast(fcx: &FnCtxt,
         return
     }
 
+    if !ty::type_is_sized(fcx.tcx(), t_1) {
+        let tstr = fcx.infcx().ty_to_string(t_1);
+        fcx.type_error_message(span, |actual| {
+            format!("cast to unsized type: `{}` as `{}`", actual, tstr)
+        }, t_e, None);
+        match ty::get(t_e).sty {
+            ty::ty_rptr(_, ty::mt { mutbl: mt, .. }) => {
+                let mtstr = match mt {
+                    ast::MutMutable => "mut ",
+                    ast::MutImmutable => ""
+                };
+                if ty::type_is_trait(t_1) {
+                    span_note!(fcx.tcx().sess, t.span, "did you mean `&{}{}`?", mtstr, tstr);
+                } else {
+                    span_note!(fcx.tcx().sess, span,
+                               "consider using an implicit coercion to `&{}{}` instead",
+                               mtstr, tstr);
+                }
+            }
+            ty::ty_uniq(..) => {
+                span_note!(fcx.tcx().sess, t.span, "did you mean `Box<{}>`?", tstr);
+            }
+            _ => {
+                span_note!(fcx.tcx().sess, e.span,
+                           "consider using a box or reference as appropriate");
+            }
+        }
+        fcx.write_error(id);
+        return
+    }
+
     if ty::type_is_trait(t_1) {
         // This will be looked up later on.
         vtable2::check_object_cast(fcx, cast_expr, e, t_1);