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};
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> {
+ struct_span_err!(sess, span, 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,
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),
}
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 {
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",
}))
.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")
primitive types. Consider using the `From` trait")
.emit();
}
- 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);
- }
CastError::SizedUnsizedCast => {
fcx.type_error_message(self.span,
|actual| {
},
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();
- }
}
}
```
"##,
+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 cast be casted into each
+others. Example:
+
+```
+let x = &0u8;
+let y: u32 = *x as u32; // We dereference it first and then cast it.
+```
+"##,
+
E0609: r##"
Attempted to access a non-existent field in a struct.
--- /dev/null
+// 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() {
+ &0u8 as u8; //~ ERROR E0606
+}
-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
|
= 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
|
= 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;
|
= 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;
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;
|
= 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;
|
= 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;
|
= 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];
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;
|
= 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];
|
= 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;
= 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::<Vec<f32>>();