diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 91aeade65aa4c..ea08f1f624e67 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -40,9 +40,11 @@ use super::{Diverges, FnCtxt}; -use lint; +use errors::DiagnosticBuilder; use hir::def_id::DefId; +use lint; use rustc::hir; +use rustc::session::Session; use rustc::traits; use rustc::ty::{self, Ty, TypeFoldable}; use rustc::ty::cast::{CastKind, CastTy}; @@ -112,6 +114,18 @@ enum CastError { NonScalar, } +fn make_invalid_casting_error<'a, 'gcx, 'tcx>(sess: &'a Session, + span: Span, + expr_ty: Ty<'tcx>, + cast_ty: Ty<'tcx>, + fcx: &FnCtxt<'a, 'gcx, 'tcx>) + -> DiagnosticBuilder<'a> { + type_error_struct!(sess, span, expr_ty, E0606, + "casting `{}` as `{}` is invalid", + fcx.ty_to_string(expr_ty), + fcx.ty_to_string(cast_ty)) +} + impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { pub fn new(fcx: &FnCtxt<'a, 'gcx, 'tcx>, expr: &'tcx hir::Expr, @@ -146,14 +160,9 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { match e { CastError::NeedDeref => { let error_span = self.span; + let mut err = make_invalid_casting_error(fcx.tcx.sess, self.span, self.expr_ty, + self.cast_ty, fcx); let cast_ty = fcx.ty_to_string(self.cast_ty); - let mut err = fcx.type_error_struct(error_span, - |actual| { - format!("casting `{}` as `{}` is invalid", - actual, - cast_ty) - }, - self.expr_ty); err.span_label(error_span, format!("cannot cast `{}` as `{}`", fcx.ty_to_string(self.expr_ty), @@ -166,13 +175,8 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { } CastError::NeedViaThinPtr | CastError::NeedViaPtr => { - let mut err = fcx.type_error_struct(self.span, - |actual| { - format!("casting `{}` as `{}` is invalid", - actual, - fcx.ty_to_string(self.cast_ty)) - }, - self.expr_ty); + let mut err = make_invalid_casting_error(fcx.tcx.sess, self.span, self.expr_ty, + self.cast_ty, fcx); if self.cast_ty.is_uint() { err.help(&format!("cast through {} first", match e { @@ -184,13 +188,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { err.emit(); } CastError::NeedViaInt => { - fcx.type_error_struct(self.span, - |actual| { - format!("casting `{}` as `{}` is invalid", - actual, - fcx.ty_to_string(self.cast_ty)) - }, - self.expr_ty) + make_invalid_casting_error(fcx.tcx.sess, self.span, self.expr_ty, self.cast_ty, fcx) .help(&format!("cast through {} first", match e { CastError::NeedViaInt => "an integer", @@ -198,6 +196,15 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { })) .emit(); } + CastError::IllegalCast => { + make_invalid_casting_error(fcx.tcx.sess, self.span, self.expr_ty, self.cast_ty, fcx) + .emit(); + } + CastError::DifferingKinds => { + make_invalid_casting_error(fcx.tcx.sess, self.span, self.expr_ty, self.cast_ty, fcx) + .note("vtable kinds may not match") + .emit(); + } CastError::CastToBool => { struct_span_err!(fcx.tcx.sess, self.span, E0054, "cannot cast as `bool`") .span_label(self.span, "unsupported cast") @@ -205,51 +212,23 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { .emit(); } CastError::CastToChar => { - fcx.type_error_message(self.span, - |actual| { - format!("only `u8` can be cast as `char`, not `{}`", - actual) - }, - self.expr_ty); + type_error_struct!(fcx.tcx.sess, self.span, self.expr_ty, E0604, + "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); - } - CastError::IllegalCast => { - fcx.type_error_message(self.span, - |actual| { - format!("casting `{}` as `{}` is invalid", - actual, - fcx.ty_to_string(self.cast_ty)) - }, - self.expr_ty); + type_error_struct!(fcx.tcx.sess, self.span, self.expr_ty, E0605, + "non-primitive 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::SizedUnsizedCast => { - fcx.type_error_message(self.span, - |actual| { - format!("cannot cast thin pointer `{}` to fat pointer \ - `{}`", - actual, - fcx.ty_to_string(self.cast_ty)) - }, - self.expr_ty) - } - CastError::DifferingKinds => { - fcx.type_error_struct(self.span, - |actual| { - format!("casting `{}` as `{}` is invalid", - actual, - fcx.ty_to_string(self.cast_ty)) - }, - self.expr_ty) - .note("vtable kinds may not match") - .emit(); + type_error_struct!(fcx.tcx.sess, self.span, self.expr_ty, E0607, + "cannot cast thin pointer `{}` to fat pointer `{}`", + self.expr_ty, + fcx.ty_to_string(self.cast_ty)).emit(); } } } diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index bc5ba4c323dc1..b2fa2cc7c61d2 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -4208,6 +4208,104 @@ println!("{}", v[2]); ``` "##, +E0604: r##" +A cast to `char` was attempted on a type other than `u8`. + +Erroneous code example: + +```compile_fail,E0604 +0u32 as char; // error: only `u8` can be cast as `char`, not `u32` +``` + +As the error message indicates, only `u8` can be cast into `char`. Example: + +``` +let c = 86u8 as char; // ok! +assert_eq!(c, 'V'); +``` + +For more information about casts, take a look at The Book: +https://doc.rust-lang.org/book/first-edition/casting-between-types.html +"##, + +E0605: r##" +An invalid cast was attempted. + +Erroneous code examples: + +```compile_fail,E0605 +let x = 0u8; +x as Vec; // error: non-primitive 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-primitive cast: `*const u8` as `&u8` +``` + +Only primitive types can be cast into each other. Examples: + +``` +let x = 0u8; +x as u32; // ok! + +let v = 0 as *const u8; +v as *const i8; // ok! +``` + +For more information about casts, take a look at The Book: +https://doc.rust-lang.org/book/first-edition/casting-between-types.html +"##, + +E0606: r##" +An incompatible cast was attempted. + +Erroneous code example: + +```compile_fail,E0606 +let x = &0u8; // Here, `x` is a `&u8`. +let y: u32 = x as u32; // error: casting `&u8` as `u32` is invalid +``` + +When casting, keep in mind that only primitive types can be cast into each +other. Example: + +``` +let x = &0u8; +let y: u32 = *x as u32; // We dereference it first and then cast it. +``` + +For more information about casts, take a look at The Book: +https://doc.rust-lang.org/book/first-edition/casting-between-types.html +"##, + +E0607: r##" +A cast between a thin and a fat pointer was attempted. + +Erroneous code example: + +```compile_fail,E0607 +let v = 0 as *const u8; +v as *const [u8]; +``` + +First: what are thin and fat pointers? + +Thin pointers are "simple" pointers: they are purely a reference to a memory +address. + +Fat pointers are pointers referencing Dynamically Sized Types (also called DST). +DST don't have a statically known size, therefore they can only exist behind +some kind of pointers that contain additional information. Slices and trait +objects are DSTs. In the case of slices, the additional information the fat +pointer holds is their size. + +To fix this error, don't try to cast directly between thin and fat pointers. + +For more information about casts, take a look at The Book: +https://doc.rust-lang.org/book/first-edition/casting-between-types.html +"##, + E0609: r##" Attempted to access a non-existent field in a struct. diff --git a/src/test/compile-fail/E0604.rs b/src/test/compile-fail/E0604.rs new file mode 100644 index 0000000000000..c5bf3a77b6c8f --- /dev/null +++ b/src/test/compile-fail/E0604.rs @@ -0,0 +1,13 @@ +// 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() { + 1u32 as char; //~ ERROR E0604 +} diff --git a/src/test/compile-fail/E0605.rs b/src/test/compile-fail/E0605.rs new file mode 100644 index 0000000000000..add3fd8fd8ac2 --- /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/compile-fail/E0606.rs b/src/test/compile-fail/E0606.rs new file mode 100644 index 0000000000000..55071736bfe51 --- /dev/null +++ b/src/test/compile-fail/E0606.rs @@ -0,0 +1,13 @@ +// 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() { + &0u8 as u8; //~ ERROR E0606 +} diff --git a/src/test/compile-fail/E0607.rs b/src/test/compile-fail/E0607.rs new file mode 100644 index 0000000000000..fa761f2c17896 --- /dev/null +++ b/src/test/compile-fail/E0607.rs @@ -0,0 +1,14 @@ +// 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 v = 0 as *const u8; + v as *const [u8]; //~ ERROR E0607 +} diff --git a/src/test/compile-fail/cast-from-nil.rs b/src/test/compile-fail/cast-from-nil.rs index 4c6dcaccc9aed..ab22d35248073 100644 --- a/src/test/compile-fail/cast-from-nil.rs +++ b/src/test/compile-fail/cast-from-nil.rs @@ -8,5 +8,5 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: non-scalar cast: `()` as `u32` +// error-pattern: non-primitive cast: `()` as `u32` fn main() { let u = (assert!(true) as u32); } diff --git a/src/test/compile-fail/cast-to-bare-fn.rs b/src/test/compile-fail/cast-to-bare-fn.rs index 7cc5c727bc7df..d5a998c6e4b6b 100644 --- a/src/test/compile-fail/cast-to-bare-fn.rs +++ b/src/test/compile-fail/cast-to-bare-fn.rs @@ -13,8 +13,8 @@ fn foo(_x: isize) { } fn main() { let v: u64 = 5; let x = foo as extern "C" fn() -> isize; - //~^ ERROR non-scalar cast + //~^ ERROR non-primitive cast let y = v as extern "Rust" fn(isize) -> (isize, isize); - //~^ ERROR non-scalar cast + //~^ ERROR non-primitive cast y(x()); } diff --git a/src/test/compile-fail/cast-to-nil.rs b/src/test/compile-fail/cast-to-nil.rs index e5fd5bb33eb90..27d9e8a42b188 100644 --- a/src/test/compile-fail/cast-to-nil.rs +++ b/src/test/compile-fail/cast-to-nil.rs @@ -8,5 +8,5 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: non-scalar cast: `u32` as `()` +// error-pattern: non-primitive cast: `u32` as `()` fn main() { let u = 0u32 as (); } diff --git a/src/test/compile-fail/closure-no-fn-3.rs b/src/test/compile-fail/closure-no-fn-3.rs index 85dbc899208f6..6584c16c9dec6 100644 --- a/src/test/compile-fail/closure-no-fn-3.rs +++ b/src/test/compile-fail/closure-no-fn-3.rs @@ -14,5 +14,5 @@ fn main() { let b = 0u8; let baz: fn() -> u8 = (|| { b }) as fn() -> u8; - //~^ ERROR non-scalar cast + //~^ ERROR non-primitive cast } diff --git a/src/test/compile-fail/coerce-to-bang-cast.rs b/src/test/compile-fail/coerce-to-bang-cast.rs index 57d2192e6356b..0479f5cce6537 100644 --- a/src/test/compile-fail/coerce-to-bang-cast.rs +++ b/src/test/compile-fail/coerce-to-bang-cast.rs @@ -17,7 +17,7 @@ fn cast_a() { } fn cast_b() { - let y = 22 as !; //~ ERROR non-scalar cast + let y = 22 as !; //~ ERROR non-primitive cast } fn main() { } diff --git a/src/test/compile-fail/fat-ptr-cast.rs b/src/test/compile-fail/fat-ptr-cast.rs index c62987a5b900e..bc2dc1cc5d4c8 100644 --- a/src/test/compile-fail/fat-ptr-cast.rs +++ b/src/test/compile-fail/fat-ptr-cast.rs @@ -22,7 +22,7 @@ fn main() { a as isize; //~ ERROR casting a as i16; //~ ERROR casting `&[i32]` as `i16` is invalid a as u32; //~ ERROR casting `&[i32]` as `u32` is invalid - b as usize; //~ ERROR non-scalar cast + b as usize; //~ ERROR non-primitive cast p as usize; //~^ ERROR casting //~^^ HELP cast through a thin pointer diff --git a/src/test/compile-fail/issue-10991.rs b/src/test/compile-fail/issue-10991.rs index 25060b94dcf37..2d00f339f33a0 100644 --- a/src/test/compile-fail/issue-10991.rs +++ b/src/test/compile-fail/issue-10991.rs @@ -10,5 +10,5 @@ fn main() { let nil = (); - let _t = nil as usize; //~ ERROR: non-scalar cast: `()` as `usize` + let _t = nil as usize; //~ ERROR: non-primitive cast: `()` as `usize` } diff --git a/src/test/compile-fail/issue-22289.rs b/src/test/compile-fail/issue-22289.rs index bcbc414d3534b..c23fc4f334472 100644 --- a/src/test/compile-fail/issue-22289.rs +++ b/src/test/compile-fail/issue-22289.rs @@ -9,5 +9,5 @@ // except according to those terms. fn main() { - 0 as &std::any::Any; //~ ERROR non-scalar cast + 0 as &std::any::Any; //~ ERROR non-primitive cast } diff --git a/src/test/compile-fail/issue-22312.rs b/src/test/compile-fail/issue-22312.rs index 4d6e6eded2118..2128c4206301b 100644 --- a/src/test/compile-fail/issue-22312.rs +++ b/src/test/compile-fail/issue-22312.rs @@ -19,7 +19,7 @@ pub trait Array2D: Index { } let i = y * self.columns() + x; let indexer = &(*self as &Index>::Output>); - //~^ERROR non-scalar cast + //~^ERROR non-primitive cast Some(indexer.index(i)) } } diff --git a/src/test/compile-fail/issue-2995.rs b/src/test/compile-fail/issue-2995.rs index 8fbf97411cc7d..d735e184d5cd5 100644 --- a/src/test/compile-fail/issue-2995.rs +++ b/src/test/compile-fail/issue-2995.rs @@ -9,7 +9,7 @@ // except according to those terms. fn bad (p: *const isize) { - let _q: &isize = p as &isize; //~ ERROR non-scalar cast + let _q: &isize = p as &isize; //~ ERROR non-primitive cast } fn main() { } diff --git a/src/test/compile-fail/nonscalar-cast.rs b/src/test/compile-fail/nonscalar-cast.rs index d6f274da967d1..0abbc05eef05d 100644 --- a/src/test/compile-fail/nonscalar-cast.rs +++ b/src/test/compile-fail/nonscalar-cast.rs @@ -8,13 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:non-scalar cast - #[derive(Debug)] struct foo { x: isize } fn main() { - println!("{}", foo{ x: 1 } as isize); + println!("{}", foo{ x: 1 } as isize); //~ non-primitive cast: `foo` as `isize` [E0605] } diff --git a/src/test/compile-fail/tag-variant-cast-non-nullary.rs b/src/test/compile-fail/tag-variant-cast-non-nullary.rs index b01063291266c..220537633eaf1 100644 --- a/src/test/compile-fail/tag-variant-cast-non-nullary.rs +++ b/src/test/compile-fail/tag-variant-cast-non-nullary.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//error-pattern: non-scalar cast - enum non_nullary { nullary, other(isize), @@ -17,5 +15,5 @@ enum non_nullary { fn main() { let v = non_nullary::nullary; - let val = v as isize; + let val = v as isize; //~ ERROR non-primitive cast: `non_nullary` as `isize` [E0605] } diff --git a/src/test/compile-fail/uninhabited-enum-cast.rs b/src/test/compile-fail/uninhabited-enum-cast.rs index b4df5fb1e2acc..2a5d25e6b98dd 100644 --- a/src/test/compile-fail/uninhabited-enum-cast.rs +++ b/src/test/compile-fail/uninhabited-enum-cast.rs @@ -11,7 +11,7 @@ enum E {} fn f(e: E) { - println!("{}", (e as isize).to_string()); //~ ERROR non-scalar cast + println!("{}", (e as isize).to_string()); //~ ERROR non-primitive cast } fn main() {} diff --git a/src/test/ui/mismatched_types/cast-rfc0401.stderr b/src/test/ui/mismatched_types/cast-rfc0401.stderr index 58cd130dcc253..879acbcf9d9d1 100644 --- a/src/test/ui/mismatched_types/cast-rfc0401.stderr +++ b/src/test/ui/mismatched_types/cast-rfc0401.stderr @@ -1,4 +1,4 @@ -error: casting `*const U` as `*const V` is invalid +error[E0606]: casting `*const U` as `*const V` is invalid --> $DIR/cast-rfc0401.rs:13:5 | 13 | u as *const V @@ -6,7 +6,7 @@ error: casting `*const U` as `*const V` is invalid | = note: vtable kinds may not match -error: casting `*const U` as `*const str` is invalid +error[E0606]: casting `*const U` as `*const str` is invalid --> $DIR/cast-rfc0401.rs:18:5 | 18 | u as *const str @@ -20,49 +20,59 @@ 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-primitive 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-primitive 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-primitive 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-primitive 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-primitive 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 +error[E0606]: casting `*const u8` as `f32` is invalid --> $DIR/cast-rfc0401.rs:45:13 | 45 | let _ = v as f32; | ^^^^^^^^ -error: casting `fn() {main}` as `f64` is invalid +error[E0606]: casting `fn() {main}` as `f64` is invalid --> $DIR/cast-rfc0401.rs:46:13 | 46 | let _ = main as f64; | ^^^^^^^^^^^ -error: casting `&*const u8` as `usize` is invalid +error[E0606]: casting `&*const u8` as `usize` is invalid --> $DIR/cast-rfc0401.rs:47:13 | 47 | let _ = &v as usize; @@ -70,7 +80,7 @@ error: casting `&*const u8` as `usize` is invalid | = help: cast through a raw pointer first -error: casting `f32` as `*const u8` is invalid +error[E0606]: casting `f32` as `*const u8` is invalid --> $DIR/cast-rfc0401.rs:48:13 | 48 | let _ = f as *const u8; @@ -92,13 +102,13 @@ error[E0054]: cannot cast as `bool` | = help: compare with zero instead -error: only `u8` can be cast as `char`, not `u32` +error[E0604]: only `u8` can be cast as `char`, not `u32` --> $DIR/cast-rfc0401.rs:51:13 | 51 | let _ = 0x61u32 as char; | ^^^^^^^^^^^^^^^ -error: casting `bool` as `f32` is invalid +error[E0606]: casting `bool` as `f32` is invalid --> $DIR/cast-rfc0401.rs:53:13 | 53 | let _ = false as f32; @@ -106,7 +116,7 @@ error: casting `bool` as `f32` is invalid | = help: cast through an integer first -error: casting `E` as `f32` is invalid +error[E0606]: casting `E` as `f32` is invalid --> $DIR/cast-rfc0401.rs:54:13 | 54 | let _ = E::A as f32; @@ -114,7 +124,7 @@ error: casting `E` as `f32` is invalid | = help: cast through an integer first -error: casting `char` as `f32` is invalid +error[E0606]: casting `char` as `f32` is invalid --> $DIR/cast-rfc0401.rs:55:13 | 55 | let _ = 'a' as f32; @@ -122,67 +132,67 @@ error: casting `char` as `f32` is invalid | = help: cast through an integer first -error: casting `bool` as `*const u8` is invalid +error[E0606]: casting `bool` as `*const u8` is invalid --> $DIR/cast-rfc0401.rs:57:13 | 57 | let _ = false as *const u8; | ^^^^^^^^^^^^^^^^^^ -error: casting `E` as `*const u8` is invalid +error[E0606]: casting `E` as `*const u8` is invalid --> $DIR/cast-rfc0401.rs:58:13 | 58 | let _ = E::A as *const u8; | ^^^^^^^^^^^^^^^^^ -error: casting `char` as `*const u8` is invalid +error[E0606]: casting `char` as `*const u8` is invalid --> $DIR/cast-rfc0401.rs:59:13 | 59 | let _ = 'a' as *const u8; | ^^^^^^^^^^^^^^^^ -error: casting `usize` as `*const [u8]` is invalid +error[E0606]: casting `usize` as `*const [u8]` is invalid --> $DIR/cast-rfc0401.rs:61:13 | 61 | let _ = 42usize as *const [u8]; | ^^^^^^^^^^^^^^^^^^^^^^ -error: cannot cast thin pointer `*const u8` to fat pointer `*const [u8]` +error[E0607]: cannot cast thin pointer `*const u8` to fat pointer `*const [u8]` --> $DIR/cast-rfc0401.rs:62:13 | 62 | let _ = v as *const [u8]; | ^^^^^^^^^^^^^^^^ -error: casting `&Foo` as `*const str` is invalid +error[E0606]: casting `&Foo` as `*const str` is invalid --> $DIR/cast-rfc0401.rs:64:13 | 64 | let _ = foo as *const str; | ^^^^^^^^^^^^^^^^^ -error: casting `&Foo` as `*mut str` is invalid +error[E0606]: casting `&Foo` as `*mut str` is invalid --> $DIR/cast-rfc0401.rs:65:13 | 65 | let _ = foo as *mut str; | ^^^^^^^^^^^^^^^ -error: casting `fn() {main}` as `*mut str` is invalid +error[E0606]: casting `fn() {main}` as `*mut str` is invalid --> $DIR/cast-rfc0401.rs:66:13 | 66 | let _ = main as *mut str; | ^^^^^^^^^^^^^^^^ -error: casting `&f32` as `*mut f32` is invalid +error[E0606]: casting `&f32` as `*mut f32` is invalid --> $DIR/cast-rfc0401.rs:67:13 | 67 | let _ = &f as *mut f32; | ^^^^^^^^^^^^^^ -error: casting `&f32` as `*const f64` is invalid +error[E0606]: casting `&f32` as `*const f64` is invalid --> $DIR/cast-rfc0401.rs:68:13 | 68 | let _ = &f as *const f64; | ^^^^^^^^^^^^^^^^ -error: casting `*const [i8]` as `usize` is invalid +error[E0606]: casting `*const [i8]` as `usize` is invalid --> $DIR/cast-rfc0401.rs:69:13 | 69 | let _ = fat_sv as usize; @@ -190,7 +200,7 @@ error: casting `*const [i8]` as `usize` is invalid | = help: cast through a thin pointer first -error: casting `*const Foo` as `*const [u16]` is invalid +error[E0606]: casting `*const Foo` as `*const [u16]` is invalid --> $DIR/cast-rfc0401.rs:78:13 | 78 | let _ = cf as *const [u16]; @@ -198,7 +208,7 @@ error: casting `*const Foo` as `*const [u16]` is invalid | = note: vtable kinds may not match -error: casting `*const Foo` as `*const Bar` is invalid +error[E0606]: casting `*const Foo` as `*const Bar` is invalid --> $DIR/cast-rfc0401.rs:79:13 | 79 | let _ = cf as *const Bar; @@ -224,7 +234,7 @@ error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied = help: the trait `std::marker::Sized` is not implemented for `str` = note: required for the cast to the object type `Foo` -error: casting `&{float}` as `f32` is invalid +error[E0606]: casting `&{float}` as `f32` is invalid --> $DIR/cast-rfc0401.rs:81:30 | 81 | vec![0.0].iter().map(|s| s as f32).collect::>(); diff --git a/src/test/ui/mismatched_types/issue-26480.stderr b/src/test/ui/mismatched_types/issue-26480.stderr index dc3764a376cde..9da9042e78ed1 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-primitive 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)