Rollup merge of #73361 - estebank:non-primitive-cast, r=davidtwco
Tweak "non-primitive cast" error - Suggest borrowing expression if it would allow cast to work. - Suggest using `<Type>::from(<expr>)` when appropriate. - Minor tweak to `;` typo suggestion. Partily address #47136.
This commit is contained in:
commit
9ca811772c
35 changed files with 204 additions and 121 deletions
|
@ -374,6 +374,7 @@ pub trait Into<T>: Sized {
|
||||||
/// [`Into`]: trait.Into.html
|
/// [`Into`]: trait.Into.html
|
||||||
/// [`from`]: trait.From.html#tymethod.from
|
/// [`from`]: trait.From.html#tymethod.from
|
||||||
/// [book]: ../../book/ch09-00-error-handling.html
|
/// [book]: ../../book/ch09-00-error-handling.html
|
||||||
|
#[rustc_diagnostic_item = "from_trait"]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_on_unimplemented(on(
|
#[rustc_on_unimplemented(on(
|
||||||
all(_Self = "&str", T = "std::string::String"),
|
all(_Self = "&str", T = "std::string::String"),
|
||||||
|
|
|
@ -961,7 +961,7 @@ impl<'a> Parser<'a> {
|
||||||
self.bump();
|
self.bump();
|
||||||
let sp = self.prev_token.span;
|
let sp = self.prev_token.span;
|
||||||
self.struct_span_err(sp, &msg)
|
self.struct_span_err(sp, &msg)
|
||||||
.span_suggestion(sp, "change this to `;`", ";".to_string(), appl)
|
.span_suggestion_short(sp, "change this to `;`", ";".to_string(), appl)
|
||||||
.emit();
|
.emit();
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else if self.look_ahead(0, |t| {
|
} else if self.look_ahead(0, |t| {
|
||||||
|
|
|
@ -345,6 +345,7 @@ symbols! {
|
||||||
from_method,
|
from_method,
|
||||||
from_ok,
|
from_ok,
|
||||||
from_usize,
|
from_usize,
|
||||||
|
from_trait,
|
||||||
fundamental,
|
fundamental,
|
||||||
future,
|
future,
|
||||||
Future,
|
Future,
|
||||||
|
|
|
@ -43,6 +43,7 @@ use rustc_middle::ty::subst::SubstsRef;
|
||||||
use rustc_middle::ty::{self, Ty, TypeAndMut, TypeFoldable};
|
use rustc_middle::ty::{self, Ty, TypeAndMut, TypeFoldable};
|
||||||
use rustc_session::lint;
|
use rustc_session::lint;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::traits;
|
use rustc_trait_selection::traits;
|
||||||
use rustc_trait_selection::traits::error_reporting::report_object_safety_error;
|
use rustc_trait_selection::traits::error_reporting::report_object_safety_error;
|
||||||
|
@ -333,10 +334,11 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
||||||
"only `u8` can be cast as `char`, not `{}`",
|
"only `u8` can be cast as `char`, not `{}`",
|
||||||
self.expr_ty
|
self.expr_ty
|
||||||
)
|
)
|
||||||
|
.span_label(self.span, "invalid cast")
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
CastError::NonScalar => {
|
CastError::NonScalar => {
|
||||||
type_error_struct!(
|
let mut err = type_error_struct!(
|
||||||
fcx.tcx.sess,
|
fcx.tcx.sess,
|
||||||
self.span,
|
self.span,
|
||||||
self.expr_ty,
|
self.expr_ty,
|
||||||
|
@ -344,12 +346,75 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
||||||
"non-primitive cast: `{}` as `{}`",
|
"non-primitive cast: `{}` as `{}`",
|
||||||
self.expr_ty,
|
self.expr_ty,
|
||||||
fcx.ty_to_string(self.cast_ty)
|
fcx.ty_to_string(self.cast_ty)
|
||||||
)
|
);
|
||||||
.note(
|
let mut sugg = None;
|
||||||
"an `as` expression can only be used to convert between \
|
if let ty::Ref(reg, _, mutbl) = self.cast_ty.kind {
|
||||||
primitive types. Consider using the `From` trait",
|
if fcx
|
||||||
)
|
.try_coerce(
|
||||||
.emit();
|
self.expr,
|
||||||
|
fcx.tcx.mk_ref(reg, TypeAndMut { ty: self.expr_ty, mutbl }),
|
||||||
|
self.cast_ty,
|
||||||
|
AllowTwoPhase::No,
|
||||||
|
)
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
sugg = Some(format!("&{}", mutbl.prefix_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(sugg) = sugg {
|
||||||
|
err.span_label(self.span, "invalid cast");
|
||||||
|
err.span_suggestion_verbose(
|
||||||
|
self.expr.span.shrink_to_lo(),
|
||||||
|
"borrow the value for the cast to be valid",
|
||||||
|
sugg,
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
} else if !matches!(
|
||||||
|
self.cast_ty.kind,
|
||||||
|
ty::FnDef(..) | ty::FnPtr(..) | ty::Closure(..)
|
||||||
|
) {
|
||||||
|
let mut label = true;
|
||||||
|
// Check `impl From<self.expr_ty> for self.cast_ty {}` for accurate suggestion:
|
||||||
|
if let Ok(snippet) = fcx.tcx.sess.source_map().span_to_snippet(self.expr.span) {
|
||||||
|
if let Some(from_trait) = fcx.tcx.get_diagnostic_item(sym::from_trait) {
|
||||||
|
let ty = fcx.resolve_vars_if_possible(&self.cast_ty);
|
||||||
|
// Erase regions to avoid panic in `prove_value` when calling
|
||||||
|
// `type_implements_trait`.
|
||||||
|
let ty = fcx.tcx.erase_regions(&ty);
|
||||||
|
let expr_ty = fcx.resolve_vars_if_possible(&self.expr_ty);
|
||||||
|
let expr_ty = fcx.tcx.erase_regions(&expr_ty);
|
||||||
|
let ty_params = fcx.tcx.mk_substs_trait(expr_ty, &[]);
|
||||||
|
// Check for infer types because cases like `Option<{integer}>` would
|
||||||
|
// panic otherwise.
|
||||||
|
if !expr_ty.has_infer_types()
|
||||||
|
&& fcx.tcx.type_implements_trait((
|
||||||
|
from_trait,
|
||||||
|
ty,
|
||||||
|
ty_params,
|
||||||
|
fcx.param_env,
|
||||||
|
))
|
||||||
|
{
|
||||||
|
label = false;
|
||||||
|
err.span_suggestion(
|
||||||
|
self.span,
|
||||||
|
"consider using the `From` trait instead",
|
||||||
|
format!("{}::from({})", self.cast_ty, snippet),
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let msg = "an `as` expression can only be used to convert between primitive \
|
||||||
|
types or to coerce to a specific trait object";
|
||||||
|
if label {
|
||||||
|
err.span_label(self.span, msg);
|
||||||
|
} else {
|
||||||
|
err.note(msg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err.span_label(self.span, "invalid cast");
|
||||||
|
}
|
||||||
|
err.emit();
|
||||||
}
|
}
|
||||||
CastError::SizedUnsizedCast => {
|
CastError::SizedUnsizedCast => {
|
||||||
use crate::structured_errors::{SizedUnsizedCastError, StructuredDiagnostic};
|
use crate::structured_errors::{SizedUnsizedCastError, StructuredDiagnostic};
|
||||||
|
@ -370,21 +435,22 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
||||||
};
|
};
|
||||||
let mut err = struct_span_err!(
|
let mut err = struct_span_err!(
|
||||||
fcx.tcx.sess,
|
fcx.tcx.sess,
|
||||||
self.span,
|
if unknown_cast_to { self.cast_span } else { self.span },
|
||||||
E0641,
|
E0641,
|
||||||
"cannot cast {} a pointer of an unknown kind",
|
"cannot cast {} a pointer of an unknown kind",
|
||||||
if unknown_cast_to { "to" } else { "from" }
|
if unknown_cast_to { "to" } else { "from" }
|
||||||
);
|
);
|
||||||
err.note(
|
|
||||||
"the type information given here is insufficient to check whether \
|
|
||||||
the pointer cast is valid",
|
|
||||||
);
|
|
||||||
if unknown_cast_to {
|
if unknown_cast_to {
|
||||||
err.span_suggestion_short(
|
err.span_label(self.cast_span, "needs more type information");
|
||||||
self.cast_span,
|
err.note(
|
||||||
"consider giving more type information",
|
"the type information given here is insufficient to check whether \
|
||||||
String::new(),
|
the pointer cast is valid",
|
||||||
Applicability::Unspecified,
|
);
|
||||||
|
} else {
|
||||||
|
err.span_label(
|
||||||
|
self.span,
|
||||||
|
"the type information given here is insufficient to check whether \
|
||||||
|
the pointer cast is valid",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
err.emit();
|
err.emit();
|
||||||
|
@ -438,13 +504,16 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
self.cast_span,
|
self.cast_span,
|
||||||
"try casting to a `Box` instead",
|
"you can cast to a `Box` instead",
|
||||||
format!("Box<{}>", s),
|
format!("Box<{}>", s),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
err.span_help(self.cast_span, &format!("did you mean `Box<{}>`?", tstr));
|
err.span_help(
|
||||||
|
self.cast_span,
|
||||||
|
&format!("you might have meant `Box<{}>`", tstr),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,7 @@ error[E0605]: non-primitive cast: `()` as `u32`
|
||||||
--> $DIR/cast-from-nil.rs:2:21
|
--> $DIR/cast-from-nil.rs:2:21
|
||||||
|
|
|
|
||||||
LL | fn main() { let u = (assert!(true) as u32); }
|
LL | fn main() { let u = (assert!(true) as u32); }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -2,17 +2,13 @@ error[E0605]: non-primitive cast: `fn(isize) {foo}` as `extern "C" fn() -> isize
|
||||||
--> $DIR/cast-to-bare-fn.rs:5:13
|
--> $DIR/cast-to-bare-fn.rs:5:13
|
||||||
|
|
|
|
||||||
LL | let x = foo as extern "C" fn() -> isize;
|
LL | let x = foo as extern "C" fn() -> isize;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast
|
||||||
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
|
|
||||||
error[E0605]: non-primitive cast: `u64` as `fn(isize) -> (isize, isize)`
|
error[E0605]: non-primitive cast: `u64` as `fn(isize) -> (isize, isize)`
|
||||||
--> $DIR/cast-to-bare-fn.rs:7:13
|
--> $DIR/cast-to-bare-fn.rs:7:13
|
||||||
|
|
|
|
||||||
LL | let y = v as extern "Rust" fn(isize) -> (isize, isize);
|
LL | let y = v as extern "Rust" fn(isize) -> (isize, isize);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast
|
||||||
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,7 @@ error[E0605]: non-primitive cast: `u32` as `()`
|
||||||
--> $DIR/cast-to-nil.rs:2:21
|
--> $DIR/cast-to-nil.rs:2:21
|
||||||
|
|
|
|
||||||
LL | fn main() { let u = 0u32 as (); }
|
LL | fn main() { let u = 0u32 as (); }
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ error[E0620]: cast to unsized type: `std::boxed::Box<{integer}>` as `dyn std::ma
|
||||||
LL | Box::new(1) as dyn Send;
|
LL | Box::new(1) as dyn Send;
|
||||||
| ^^^^^^^^^^^^^^^--------
|
| ^^^^^^^^^^^^^^^--------
|
||||||
| |
|
| |
|
||||||
| help: try casting to a `Box` instead: `Box<dyn Send>`
|
| help: you can cast to a `Box` instead: `Box<dyn Send>`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,7 @@ error[E0605]: non-primitive cast: `[closure@$DIR/closure-no-fn-3.rs:6:27: 6:37 b
|
||||||
--> $DIR/closure-no-fn-3.rs:6:27
|
--> $DIR/closure-no-fn-3.rs:6:27
|
||||||
|
|
|
|
||||||
LL | let baz: fn() -> u8 = (|| { b }) as fn() -> u8;
|
LL | let baz: fn() -> u8 = (|| { b }) as fn() -> u8;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast
|
||||||
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -2,17 +2,13 @@ error[E0605]: non-primitive cast: `i32` as `!`
|
||||||
--> $DIR/coerce-to-bang-cast.rs:6:13
|
--> $DIR/coerce-to-bang-cast.rs:6:13
|
||||||
|
|
|
|
||||||
LL | let y = {return; 22} as !;
|
LL | let y = {return; 22} as !;
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
|
|
||||||
error[E0605]: non-primitive cast: `i32` as `!`
|
error[E0605]: non-primitive cast: `i32` as `!`
|
||||||
--> $DIR/coerce-to-bang-cast.rs:11:13
|
--> $DIR/coerce-to-bang-cast.rs:11:13
|
||||||
|
|
|
|
||||||
LL | let y = 22 as !;
|
LL | let y = 22 as !;
|
||||||
| ^^^^^^^
|
| ^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ error[E0604]: only `u8` can be cast as `char`, not `i8`
|
||||||
--> $DIR/const-eval-overflow-4b.rs:25:13
|
--> $DIR/const-eval-overflow-4b.rs:25:13
|
||||||
|
|
|
|
||||||
LL | : [u32; 5i8 as char as usize]
|
LL | : [u32; 5i8 as char as usize]
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^ invalid cast
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ error[E0604]: only `u8` can be cast as `char`, not `u32`
|
||||||
--> $DIR/E0604.rs:2:5
|
--> $DIR/E0604.rs:2:5
|
||||||
|
|
|
|
||||||
LL | 1u32 as char;
|
LL | 1u32 as char;
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^ invalid cast
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -2,17 +2,13 @@ error[E0605]: non-primitive cast: `u8` as `std::vec::Vec<u8>`
|
||||||
--> $DIR/E0605.rs:3:5
|
--> $DIR/E0605.rs:3:5
|
||||||
|
|
|
|
||||||
LL | x as Vec<u8>;
|
LL | x as Vec<u8>;
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
|
|
||||||
error[E0605]: non-primitive cast: `*const u8` as `&u8`
|
error[E0605]: non-primitive cast: `*const u8` as `&u8`
|
||||||
--> $DIR/E0605.rs:6:5
|
--> $DIR/E0605.rs:6:5
|
||||||
|
|
|
|
||||||
LL | v as &u8;
|
LL | v as &u8;
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -42,15 +42,13 @@ error[E0604]: only `u8` can be cast as `char`, not `u32`
|
||||||
--> $DIR/error-festival.rs:25:5
|
--> $DIR/error-festival.rs:25:5
|
||||||
|
|
|
|
||||||
LL | 0u32 as char;
|
LL | 0u32 as char;
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^ invalid cast
|
||||||
|
|
||||||
error[E0605]: non-primitive cast: `u8` as `std::vec::Vec<u8>`
|
error[E0605]: non-primitive cast: `u8` as `std::vec::Vec<u8>`
|
||||||
--> $DIR/error-festival.rs:29:5
|
--> $DIR/error-festival.rs:29:5
|
||||||
|
|
|
|
||||||
LL | x as Vec<u8>;
|
LL | x as Vec<u8>;
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
|
|
||||||
error[E0054]: cannot cast as `bool`
|
error[E0054]: cannot cast as `bool`
|
||||||
--> $DIR/error-festival.rs:33:24
|
--> $DIR/error-festival.rs:33:24
|
||||||
|
|
|
@ -34,9 +34,7 @@ error[E0605]: non-primitive cast: `std::boxed::Box<[i32]>` as `usize`
|
||||||
--> $DIR/fat-ptr-cast.rs:14:5
|
--> $DIR/fat-ptr-cast.rs:14:5
|
||||||
|
|
|
|
||||||
LL | b as usize;
|
LL | b as usize;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
|
|
||||||
error[E0606]: casting `*const [i32]` as `usize` is invalid
|
error[E0606]: casting `*const [i32]` as `usize` is invalid
|
||||||
--> $DIR/fat-ptr-cast.rs:15:5
|
--> $DIR/fat-ptr-cast.rs:15:5
|
||||||
|
|
|
@ -2,9 +2,7 @@ error[E0605]: non-primitive cast: `()` as `usize`
|
||||||
--> $DIR/issue-10991.rs:3:14
|
--> $DIR/issue-10991.rs:3:14
|
||||||
|
|
|
|
||||||
LL | let _t = nil as usize;
|
LL | let _t = nil as usize;
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,12 @@ impl<'a> Test<'a> for Foo<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> NoLifetime for Foo<'a> {
|
impl<'a> NoLifetime for Foo<'a> {
|
||||||
fn get<'p, T : Test<'a>>(&self) -> T {
|
fn get<'p, T: Test<'a> + From<Foo<'a>>>(&self) -> T {
|
||||||
//~^ ERROR E0195
|
//~^ ERROR E0195
|
||||||
//~| NOTE lifetimes do not match method in trait
|
//~| NOTE lifetimes do not match method in trait
|
||||||
return *self as T;
|
return *self as T;
|
||||||
//~^ ERROR non-primitive cast: `Foo<'a>` as `T`
|
//~^ ERROR non-primitive cast: `Foo<'a>` as `T`
|
||||||
//~| NOTE an `as` expression can only be used to convert between primitive types.
|
//~| NOTE an `as` expression can only be used to convert between primitive types
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,16 +4,16 @@ error[E0195]: lifetime parameters or bounds on method `get` do not match the tra
|
||||||
LL | fn get<'p, T : Test<'p>>(&self) -> T;
|
LL | fn get<'p, T : Test<'p>>(&self) -> T;
|
||||||
| ------------------ lifetimes in impl do not match this method in trait
|
| ------------------ lifetimes in impl do not match this method in trait
|
||||||
...
|
...
|
||||||
LL | fn get<'p, T : Test<'a>>(&self) -> T {
|
LL | fn get<'p, T: Test<'a> + From<Foo<'a>>>(&self) -> T {
|
||||||
| ^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait
|
||||||
|
|
||||||
error[E0605]: non-primitive cast: `Foo<'a>` as `T`
|
error[E0605]: non-primitive cast: `Foo<'a>` as `T`
|
||||||
--> $DIR/issue-16048.rs:24:16
|
--> $DIR/issue-16048.rs:24:16
|
||||||
|
|
|
|
||||||
LL | return *self as T;
|
LL | return *self as T;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^ help: consider using the `From` trait instead: `T::from(*self)`
|
||||||
|
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
= note: an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ error[E0620]: cast to unsized type: `std::boxed::Box<usize>` as `dyn std::fmt::D
|
||||||
LL | let _bar = Box::new(1_usize) as dyn std::fmt::Debug;
|
LL | let _bar = Box::new(1_usize) as dyn std::fmt::Debug;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^-------------------
|
| ^^^^^^^^^^^^^^^^^^^^^-------------------
|
||||||
| |
|
| |
|
||||||
| help: try casting to a `Box` instead: `Box<dyn std::fmt::Debug>`
|
| help: you can cast to a `Box` instead: `Box<dyn std::fmt::Debug>`
|
||||||
|
|
||||||
error[E0620]: cast to unsized type: `usize` as `dyn std::fmt::Debug`
|
error[E0620]: cast to unsized type: `usize` as `dyn std::fmt::Debug`
|
||||||
--> $DIR/issue-17441.rs:8:16
|
--> $DIR/issue-17441.rs:8:16
|
||||||
|
|
|
@ -2,9 +2,12 @@ error[E0605]: non-primitive cast: `i32` as `&(dyn std::any::Any + 'static)`
|
||||||
--> $DIR/issue-22289.rs:2:5
|
--> $DIR/issue-22289.rs:2:5
|
||||||
|
|
|
|
||||||
LL | 0 as &dyn std::any::Any;
|
LL | 0 as &dyn std::any::Any;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^ invalid cast
|
||||||
|
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
help: borrow the value for the cast to be valid
|
||||||
|
|
|
||||||
|
LL | &0 as &dyn std::any::Any;
|
||||||
|
| ^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::ops::Index;
|
use std::ops::Index;
|
||||||
|
|
||||||
pub trait Array2D: Index<usize> {
|
pub trait Array2D: Index<usize> + Sized {
|
||||||
fn rows(&self) -> usize;
|
fn rows(&self) -> usize;
|
||||||
fn columns(&self) -> usize;
|
fn columns(&self) -> usize;
|
||||||
fn get<'a>(&'a self, y: usize, x: usize) -> Option<&'a <Self as Index<usize>>::Output> {
|
fn get<'a>(&'a self, y: usize, x: usize) -> Option<&'a <Self as Index<usize>>::Output> {
|
||||||
|
|
|
@ -2,9 +2,12 @@ error[E0605]: non-primitive cast: `Self` as `&dyn std::ops::Index<usize, Output
|
||||||
--> $DIR/issue-22312.rs:11:24
|
--> $DIR/issue-22312.rs:11:24
|
||||||
|
|
|
|
||||||
LL | let indexer = &(*self as &dyn Index<usize, Output = <Self as Index<usize>>::Output>);
|
LL | let indexer = &(*self as &dyn Index<usize, Output = <Self as Index<usize>>::Output>);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast
|
||||||
|
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
help: borrow the value for the cast to be valid
|
||||||
|
|
|
||||||
|
LL | let indexer = &(&*self as &dyn Index<usize, Output = <Self as Index<usize>>::Output>);
|
||||||
|
| ^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,7 @@ error[E0605]: non-primitive cast: `*const isize` as `&isize`
|
||||||
--> $DIR/issue-2995.rs:2:22
|
--> $DIR/issue-2995.rs:2:22
|
||||||
|
|
|
|
||||||
LL | let _q: &isize = p as &isize;
|
LL | let _q: &isize = p as &isize;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -1,30 +1,24 @@
|
||||||
error[E0641]: cannot cast to a pointer of an unknown kind
|
error[E0641]: cannot cast to a pointer of an unknown kind
|
||||||
--> $DIR/issue-45730.rs:3:23
|
--> $DIR/issue-45730.rs:3:28
|
||||||
|
|
|
|
||||||
LL | let x: *const _ = 0 as _;
|
LL | let x: *const _ = 0 as _;
|
||||||
| ^^^^^-
|
| ^ needs more type information
|
||||||
| |
|
|
||||||
| help: consider giving more type information
|
|
||||||
|
|
|
|
||||||
= note: the type information given here is insufficient to check whether the pointer cast is valid
|
= note: the type information given here is insufficient to check whether the pointer cast is valid
|
||||||
|
|
||||||
error[E0641]: cannot cast to a pointer of an unknown kind
|
error[E0641]: cannot cast to a pointer of an unknown kind
|
||||||
--> $DIR/issue-45730.rs:5:23
|
--> $DIR/issue-45730.rs:5:28
|
||||||
|
|
|
|
||||||
LL | let x: *const _ = 0 as *const _;
|
LL | let x: *const _ = 0 as *const _;
|
||||||
| ^^^^^--------
|
| ^^^^^^^^ needs more type information
|
||||||
| |
|
|
||||||
| help: consider giving more type information
|
|
||||||
|
|
|
|
||||||
= note: the type information given here is insufficient to check whether the pointer cast is valid
|
= note: the type information given here is insufficient to check whether the pointer cast is valid
|
||||||
|
|
||||||
error[E0641]: cannot cast to a pointer of an unknown kind
|
error[E0641]: cannot cast to a pointer of an unknown kind
|
||||||
--> $DIR/issue-45730.rs:8:13
|
--> $DIR/issue-45730.rs:8:44
|
||||||
|
|
|
|
||||||
LL | let x = 0 as *const i32 as *const _ as *mut _;
|
LL | let x = 0 as *const i32 as *const _ as *mut _;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------
|
| ^^^^^^ needs more type information
|
||||||
| |
|
|
||||||
| help: consider giving more type information
|
|
||||||
|
|
|
|
||||||
= note: the type information given here is insufficient to check whether the pointer cast is valid
|
= note: the type information given here is insufficient to check whether the pointer cast is valid
|
||||||
|
|
||||||
|
|
|
@ -24,41 +24,31 @@ error[E0605]: non-primitive cast: `*const u8` as `&u8`
|
||||||
--> $DIR/cast-rfc0401.rs:29:13
|
--> $DIR/cast-rfc0401.rs:29:13
|
||||||
|
|
|
|
||||||
LL | let _ = v as &u8;
|
LL | let _ = v as &u8;
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
|
|
||||||
error[E0605]: non-primitive cast: `*const u8` as `E`
|
error[E0605]: non-primitive cast: `*const u8` as `E`
|
||||||
--> $DIR/cast-rfc0401.rs:30:13
|
--> $DIR/cast-rfc0401.rs:30:13
|
||||||
|
|
|
|
||||||
LL | let _ = v as E;
|
LL | let _ = v as E;
|
||||||
| ^^^^^^
|
| ^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
|
|
||||||
error[E0605]: non-primitive cast: `*const u8` as `fn()`
|
error[E0605]: non-primitive cast: `*const u8` as `fn()`
|
||||||
--> $DIR/cast-rfc0401.rs:31:13
|
--> $DIR/cast-rfc0401.rs:31:13
|
||||||
|
|
|
|
||||||
LL | let _ = v as fn();
|
LL | let _ = v as fn();
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^ invalid cast
|
||||||
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
|
|
||||||
error[E0605]: non-primitive cast: `*const u8` as `(u32,)`
|
error[E0605]: non-primitive cast: `*const u8` as `(u32,)`
|
||||||
--> $DIR/cast-rfc0401.rs:32:13
|
--> $DIR/cast-rfc0401.rs:32:13
|
||||||
|
|
|
|
||||||
LL | let _ = v as (u32,);
|
LL | let _ = v as (u32,);
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
|
|
||||||
error[E0605]: non-primitive 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:33:13
|
--> $DIR/cast-rfc0401.rs:33:13
|
||||||
|
|
|
|
||||||
LL | let _ = Some(&v) as *const u8;
|
LL | let _ = Some(&v) as *const u8;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
|
|
||||||
error[E0606]: casting `*const u8` as `f32` is invalid
|
error[E0606]: casting `*const u8` as `f32` is invalid
|
||||||
--> $DIR/cast-rfc0401.rs:35:13
|
--> $DIR/cast-rfc0401.rs:35:13
|
||||||
|
@ -102,7 +92,7 @@ error[E0604]: only `u8` can be cast as `char`, not `u32`
|
||||||
--> $DIR/cast-rfc0401.rs:41:13
|
--> $DIR/cast-rfc0401.rs:41:13
|
||||||
|
|
|
|
||||||
LL | let _ = 0x61u32 as char;
|
LL | let _ = 0x61u32 as char;
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^ invalid cast
|
||||||
|
|
||||||
error[E0606]: casting `bool` as `f32` is invalid
|
error[E0606]: casting `bool` as `f32` is invalid
|
||||||
--> $DIR/cast-rfc0401.rs:43:13
|
--> $DIR/cast-rfc0401.rs:43:13
|
||||||
|
|
|
@ -17,12 +17,11 @@ error[E0605]: non-primitive cast: `{integer}` as `()`
|
||||||
--> $DIR/issue-26480.rs:22:19
|
--> $DIR/issue-26480.rs:22:19
|
||||||
|
|
|
|
||||||
LL | ($x:expr) => ($x as ())
|
LL | ($x:expr) => ($x as ())
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
...
|
...
|
||||||
LL | cast!(2);
|
LL | cast!(2);
|
||||||
| --------- in this macro invocation
|
| --------- in this macro invocation
|
||||||
|
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
16
src/test/ui/nonscalar-cast.fixed
Normal file
16
src/test/ui/nonscalar-cast.fixed
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Foo {
|
||||||
|
x: isize
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Foo> for isize {
|
||||||
|
fn from(val: Foo) -> isize {
|
||||||
|
val.x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("{}", isize::from(Foo { x: 1 })); //~ non-primitive cast: `Foo` as `isize` [E0605]
|
||||||
|
}
|
|
@ -1,8 +1,16 @@
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Foo {
|
struct Foo {
|
||||||
x: isize
|
x: isize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Foo> for isize {
|
||||||
|
fn from(val: Foo) -> isize {
|
||||||
|
val.x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("{}", Foo { x: 1 } as isize); //~ non-primitive cast: `Foo` as `isize` [E0605]
|
println!("{}", Foo { x: 1 } as isize); //~ non-primitive cast: `Foo` as `isize` [E0605]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
error[E0605]: non-primitive cast: `Foo` as `isize`
|
error[E0605]: non-primitive cast: `Foo` as `isize`
|
||||||
--> $DIR/nonscalar-cast.rs:7:20
|
--> $DIR/nonscalar-cast.rs:15:20
|
||||||
|
|
|
|
||||||
LL | println!("{}", Foo { x: 1 } as isize);
|
LL | println!("{}", Foo { x: 1 } as isize);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using the `From` trait instead: `isize::from(Foo { x: 1 })`
|
||||||
|
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
= note: an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
error[E0641]: cannot cast to a pointer of an unknown kind
|
error[E0641]: cannot cast to a pointer of an unknown kind
|
||||||
--> $DIR/order-dependent-cast-inference.rs:5:17
|
--> $DIR/order-dependent-cast-inference.rs:5:22
|
||||||
|
|
|
|
||||||
LL | let mut y = 0 as *const _;
|
LL | let mut y = 0 as *const _;
|
||||||
| ^^^^^--------
|
| ^^^^^^^^ needs more type information
|
||||||
| |
|
|
||||||
| help: consider giving more type information
|
|
||||||
|
|
|
|
||||||
= note: the type information given here is insufficient to check whether the pointer cast is valid
|
= note: the type information given here is insufficient to check whether the pointer cast is valid
|
||||||
|
|
||||||
|
|
20
src/test/ui/tag-variant-cast-non-nullary.fixed
Normal file
20
src/test/ui/tag-variant-cast-non-nullary.fixed
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// run-rustfix
|
||||||
|
#![allow(dead_code, unused_variables)]
|
||||||
|
enum NonNullary {
|
||||||
|
Nullary,
|
||||||
|
Other(isize),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<NonNullary> for isize {
|
||||||
|
fn from(val: NonNullary) -> isize {
|
||||||
|
match val {
|
||||||
|
NonNullary::Nullary => 0,
|
||||||
|
NonNullary::Other(i) => i,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let v = NonNullary::Nullary;
|
||||||
|
let val = isize::from(v); //~ ERROR non-primitive cast: `NonNullary` as `isize` [E0605]
|
||||||
|
}
|
|
@ -1,8 +1,19 @@
|
||||||
|
// run-rustfix
|
||||||
|
#![allow(dead_code, unused_variables)]
|
||||||
enum NonNullary {
|
enum NonNullary {
|
||||||
Nullary,
|
Nullary,
|
||||||
Other(isize),
|
Other(isize),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<NonNullary> for isize {
|
||||||
|
fn from(val: NonNullary) -> isize {
|
||||||
|
match val {
|
||||||
|
NonNullary::Nullary => 0,
|
||||||
|
NonNullary::Other(i) => i,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let v = NonNullary::Nullary;
|
let v = NonNullary::Nullary;
|
||||||
let val = v as isize; //~ ERROR non-primitive cast: `NonNullary` as `isize` [E0605]
|
let val = v as isize; //~ ERROR non-primitive cast: `NonNullary` as `isize` [E0605]
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
error[E0605]: non-primitive cast: `NonNullary` as `isize`
|
error[E0605]: non-primitive cast: `NonNullary` as `isize`
|
||||||
--> $DIR/tag-variant-cast-non-nullary.rs:8:15
|
--> $DIR/tag-variant-cast-non-nullary.rs:19:15
|
||||||
|
|
|
|
||||||
LL | let val = v as isize;
|
LL | let val = v as isize;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^ help: consider using the `From` trait instead: `isize::from(v)`
|
||||||
|
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
= note: an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,7 @@ error[E0605]: non-primitive cast: `impl std::fmt::Debug` as `&'static str`
|
||||||
--> $DIR/never_reveal_concrete_type.rs:14:13
|
--> $DIR/never_reveal_concrete_type.rs:14:13
|
||||||
|
|
|
|
||||||
LL | let _ = x as &'static str;
|
LL | let _ = x as &'static str;
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,7 @@ error[E0605]: non-primitive cast: `E` as `isize`
|
||||||
--> $DIR/uninhabited-enum-cast.rs:4:20
|
--> $DIR/uninhabited-enum-cast.rs:4:20
|
||||||
|
|
|
|
||||||
LL | println!("{}", (e as isize).to_string());
|
LL | println!("{}", (e as isize).to_string());
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||||
|
|
|
||||||
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue