about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_typeck/check/cast.rs14
-rw-r--r--src/librustc_typeck/diagnostics.rs26
-rw-r--r--src/test/compile-fail/E0605.rs19
-rw-r--r--src/test/ui/mismatched_types/cast-rfc0401.stderr20
-rw-r--r--src/test/ui/mismatched_types/issue-26480.stderr4
5 files changed, 70 insertions, 13 deletions
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index cff61df52cd..69174dacaaa 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -209,13 +209,13 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
                                  "only `u8` can be cast as `char`, not `{}`", self.expr_ty).emit();
             }
             CastError::NonScalar => {
-                fcx.type_error_message(self.span,
-                                       |actual| {
-                                           format!("non-scalar cast: `{}` as `{}`",
-                                                   actual,
-                                                   fcx.ty_to_string(self.cast_ty))
-                                       },
-                                       self.expr_ty);
+                struct_span_err!(fcx.tcx.sess, self.span, E0605,
+                                 "non-scalar cast: `{}` as `{}`",
+                                 self.expr_ty,
+                                 fcx.ty_to_string(self.cast_ty))
+                                .note("an `as` expression can only be used to convert between \
+                                       primitive types. Consider using the `From` trait")
+                                .emit();
             }
             CastError::IllegalCast => {
                 fcx.type_error_message(self.span,
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index e750a897844..a787aadc678 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -4225,6 +4225,32 @@ assert!(c, 'V');
 ```
 "##,
 
+E0605: r##"
+An invalid cast was attempted.
+
+Erroneous code examples:
+
+```compile_fail,E0605
+let x = 0u8;
+x as Vec<u8>; // error: non-scalar cast: `u8` as `std::vec::Vec<u8>`
+
+// Another example
+
+let v = 0 as *const u8; // So here, `v` is a `*const u8`.
+v as &u8; // error: non-scalar cast: `*const u8` as `&u8`
+```
+
+Only primitive types cast be casted into each others. Examples:
+
+```
+let x = 0u8;
+x as u32; // ok!
+
+let v = 0 as *const u8;
+v as *const i8; // ok!
+```
+"##,
+
 E0609: r##"
 Attempted to access a non-existent field in a struct.
 
diff --git a/src/test/compile-fail/E0605.rs b/src/test/compile-fail/E0605.rs
new file mode 100644
index 00000000000..add3fd8fd8a
--- /dev/null
+++ b/src/test/compile-fail/E0605.rs
@@ -0,0 +1,19 @@
+// Copyright 2017 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 x = 0u8;
+    x as Vec<u8>; //~ ERROR E0605
+                  //~| NOTE an `as` expression can only be used to convert between primitive types
+
+    let v = 0 as *const u8;
+    v as &u8; //~ ERROR E0605
+              //~| NOTE an `as` expression can only be used to convert between primitive types
+}
diff --git a/src/test/ui/mismatched_types/cast-rfc0401.stderr b/src/test/ui/mismatched_types/cast-rfc0401.stderr
index 82672d5d873..c79d242dc5e 100644
--- a/src/test/ui/mismatched_types/cast-rfc0401.stderr
+++ b/src/test/ui/mismatched_types/cast-rfc0401.stderr
@@ -20,35 +20,45 @@ error[E0609]: no field `f` on type `fn() {main}`
 75 |     let _ = main.f as *const u32;
    |                  ^
 
-error: non-scalar cast: `*const u8` as `&u8`
+error[E0605]: non-scalar cast: `*const u8` as `&u8`
   --> $DIR/cast-rfc0401.rs:39:13
    |
 39 |     let _ = v as &u8;
    |             ^^^^^^^^
+   |
+   = note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
 
-error: non-scalar cast: `*const u8` as `E`
+error[E0605]: non-scalar cast: `*const u8` as `E`
   --> $DIR/cast-rfc0401.rs:40:13
    |
 40 |     let _ = v as E;
    |             ^^^^^^
+   |
+   = note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
 
-error: non-scalar cast: `*const u8` as `fn()`
+error[E0605]: non-scalar cast: `*const u8` as `fn()`
   --> $DIR/cast-rfc0401.rs:41:13
    |
 41 |     let _ = v as fn();
    |             ^^^^^^^^^
+   |
+   = note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
 
-error: non-scalar cast: `*const u8` as `(u32,)`
+error[E0605]: non-scalar cast: `*const u8` as `(u32,)`
   --> $DIR/cast-rfc0401.rs:42:13
    |
 42 |     let _ = v as (u32,);
    |             ^^^^^^^^^^^
+   |
+   = note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
 
-error: non-scalar cast: `std::option::Option<&*const u8>` as `*const u8`
+error[E0605]: non-scalar cast: `std::option::Option<&*const u8>` as `*const u8`
   --> $DIR/cast-rfc0401.rs:43:13
    |
 43 |     let _ = Some(&v) as *const u8;
    |             ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
 
 error: casting `*const u8` as `f32` is invalid
   --> $DIR/cast-rfc0401.rs:45:13
diff --git a/src/test/ui/mismatched_types/issue-26480.stderr b/src/test/ui/mismatched_types/issue-26480.stderr
index dc3764a376c..06b88069002 100644
--- a/src/test/ui/mismatched_types/issue-26480.stderr
+++ b/src/test/ui/mismatched_types/issue-26480.stderr
@@ -7,7 +7,7 @@ error[E0308]: mismatched types
 37 |     write!(hello);
    |     -------------- in this macro invocation
 
-error: non-scalar cast: `{integer}` as `()`
+error[E0605]: non-scalar cast: `{integer}` as `()`
   --> $DIR/issue-26480.rs:32:19
    |
 32 |     ($x:expr) => ($x as ())
@@ -15,6 +15,8 @@ error: non-scalar cast: `{integer}` as `()`
 ...
 38 |     cast!(2);
    |     --------- in this macro invocation
+   |
+   = note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
 
 error: aborting due to previous error(s)