about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-09-29 08:14:27 -0700
committerAlex Crichton <alex@alexcrichton.com>2014-09-29 08:14:27 -0700
commit0358f3112707739fcb6576ef84cc4cc05413e24e (patch)
tree0350e725d029177b1ceaf5787038f45254ab53e7
parent7784a8d39773517da476a19562cea0ef0cd36eab (diff)
parent69d570fbec565a565e0e79b5ce3bfc638d4b83c1 (diff)
downloadrust-0358f3112707739fcb6576ef84cc4cc05413e24e.tar.gz
rust-0358f3112707739fcb6576ef84cc4cc05413e24e.zip
rollup merge of #17598 : bkoropoff/issue-17441
-rw-r--r--src/librustc/middle/typeck/check/mod.rs31
-rw-r--r--src/test/compile-fail/issue-17441.rs24
2 files changed, 55 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);
diff --git a/src/test/compile-fail/issue-17441.rs b/src/test/compile-fail/issue-17441.rs
new file mode 100644
index 00000000000..da548ca5ffe
--- /dev/null
+++ b/src/test/compile-fail/issue-17441.rs
@@ -0,0 +1,24 @@
+// Copyright 2014 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.
+
+fn main() {
+    let _foo = &[1u, 2] as [uint];
+    //~^ ERROR cast to unsized type: `&[uint, .. 2]` as `[uint]`
+    //~^^ NOTE consider using an implicit coercion to `&[uint]` instead
+    let _bar = box 1u as std::fmt::Show;
+    //~^ ERROR cast to unsized type: `Box<uint>` as `core::fmt::Show`
+    //~^^ NOTE did you mean `Box<core::fmt::Show>`?
+    let _baz = 1u as std::fmt::Show;
+    //~^ ERROR cast to unsized type: `uint` as `core::fmt::Show`
+    //~^^ NOTE consider using a box or reference as appropriate
+    let _quux = [1u, 2] as [uint];
+    //~^ ERROR cast to unsized type: `[uint, .. 2]` as `[uint]`
+    //~^^ NOTE consider using a box or reference as appropriate
+}