From 0e4b8ffccdfaa48e7ec61d8f8dc06f15f31c800f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 7 Jun 2017 22:24:15 +0200 Subject: [PATCH] Add E0605 --- src/librustc_typeck/check/cast.rs | 14 +++++----- src/librustc_typeck/diagnostics.rs | 26 +++++++++++++++++++ src/test/compile-fail/E0605.rs | 19 ++++++++++++++ .../ui/mismatched_types/cast-rfc0401.stderr | 20 ++++++++++---- .../ui/mismatched_types/issue-26480.stderr | 4 ++- 5 files changed, 70 insertions(+), 13 deletions(-) create mode 100644 src/test/compile-fail/E0605.rs 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; // error: non-scalar cast: `u8` as `std::vec::Vec` + +// 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 or the MIT license +// , 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; //~ 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)