Rollup merge of #115879 - clubby789:migrate-hir-typeck-cast, r=compiler-errors

Migrate diagnostics in `hir_typeck/src/cast.rs`
This commit is contained in:
Matthias Krüger 2023-09-19 01:29:42 +02:00 committed by GitHub
commit 970ee09c22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 363 additions and 192 deletions

View File

@ -16,6 +16,21 @@ hir_typeck_candidate_trait_note = `{$trait_name}` defines an item `{$item_name}`
*[other] , perhaps you need to restrict type parameter `{$action_or_ty}` with it
}
hir_typeck_cannot_cast_to_bool = cannot cast `{$expr_ty}` as `bool`
.suggestion = compare with zero instead
.help = compare with zero instead
.label = unsupported cast
hir_typeck_cast_enum_drop = cannot cast enum `{$expr_ty}` into integer `{$cast_ty}` because it implements `Drop`
hir_typeck_cast_unknown_pointer = cannot cast {$to ->
[true] to
*[false] from
} a pointer of an unknown kind
.label_to = needs more type information
.note = the type information given here is insufficient to check whether the pointer cast is valid
.label_from = the type information given here is insufficient to check whether the pointer cast is valid
hir_typeck_const_select_must_be_const = this argument must be a `const fn`
.help = consult the documentation on `const_eval_select` for more information
@ -29,6 +44,8 @@ hir_typeck_convert_using_method = try using `{$sugg}` to convert `{$found}` to `
hir_typeck_ctor_is_private = tuple struct constructor `{$def}` is private
hir_typeck_deref_is_empty = this expression `Deref`s to `{$deref_ty}` which implements `is_empty`
hir_typeck_expected_default_return_type = expected `()` because of default return type
hir_typeck_expected_return_type = expected `{$expected}` because of return type
@ -57,6 +74,13 @@ hir_typeck_functional_record_update_on_non_struct =
hir_typeck_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml`
hir_typeck_help_set_edition_standalone = pass `--edition {$edition}` to `rustc`
hir_typeck_int_to_fat = cannot cast `{$expr_ty}` to a pointer that {$known_wide ->
[true] is
*[false] may be
} wide
hir_typeck_int_to_fat_label = creating a `{$cast_ty}` requires both an address and {$metadata}
hir_typeck_int_to_fat_label_nightly = consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts`
hir_typeck_invalid_callee = expected function, found {$ty}
hir_typeck_lang_start_expected_sig_note = the `start` lang item should have the signature `fn(fn() -> T, isize, *const *const u8, u8) -> isize`
@ -69,6 +93,16 @@ hir_typeck_lang_start_incorrect_param = parameter {$param_num} of the `start` la
hir_typeck_lang_start_incorrect_ret_ty = the return type of the `start` lang item is incorrect
.suggestion = change the type from `{$found_ty}` to `{$expected_ty}`
hir_typeck_lossy_provenance_int2ptr =
strict provenance disallows casting integer `{$expr_ty}` to pointer `{$cast_ty}`
.suggestion = use `.with_addr()` to adjust a valid pointer in the same allocation, to this address
.help = if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::from_exposed_addr()` instead
hir_typeck_lossy_provenance_ptr2int =
under strict provenance it is considered bad style to cast pointer `{$expr_ty}` to integer `{$cast_ty}`
.suggestion = use `.addr()` to obtain the address of a pointer
.help = if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
hir_typeck_method_call_on_unknown_raw_pointee =
cannot call a method on a raw pointer with an unknown pointee type
@ -113,8 +147,18 @@ hir_typeck_suggest_boxing_when_appropriate = store this in the heap by calling `
hir_typeck_suggest_ptr_null_mut = consider using `core::ptr::null_mut` instead
hir_typeck_trivial_cast = trivial {$numeric ->
[true] numeric cast
*[false] cast
}: `{$expr_ty}` as `{$cast_ty}`
.help = cast can be replaced by coercion; this might require a temporary variable
hir_typeck_union_pat_dotdot = `..` cannot be used in union patterns
hir_typeck_union_pat_multiple_fields = union patterns should have exactly one field
hir_typeck_use_is_empty =
consider using the `is_empty` method on `{$expr_ty}` to determine if it contains anything
hir_typeck_yield_expr_outside_of_generator =
yield expression outside of generator literal

View File

@ -30,11 +30,10 @@
use super::FnCtxt;
use crate::errors;
use crate::type_error_struct;
use hir::ExprKind;
use rustc_errors::{
struct_span_err, Applicability, DelayDm, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
};
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
use rustc_hir as hir;
use rustc_macros::{TypeFoldable, TypeVisitable};
use rustc_middle::mir::Mutability;
@ -321,33 +320,15 @@ impl<'a, 'tcx> CastCheck<'tcx> {
.emit();
}
CastError::CastToBool => {
let mut err = struct_span_err!(
fcx.tcx.sess,
self.span,
E0054,
"cannot cast `{}` as `bool`",
self.expr_ty
);
if self.expr_ty.is_numeric() {
match fcx.tcx.sess.source_map().span_to_snippet(self.expr_span) {
Ok(snippet) => {
err.span_suggestion(
self.span,
"compare with zero instead",
format!("{snippet} != 0"),
Applicability::MachineApplicable,
);
}
Err(_) => {
err.span_help(self.span, "compare with zero instead");
}
}
let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
let help = if self.expr_ty.is_numeric() {
errors::CannotCastToBoolHelp::Numeric(
self.expr_span.shrink_to_hi().with_hi(self.span.hi()),
)
} else {
err.span_label(self.span, "unsupported cast");
}
err.emit();
errors::CannotCastToBoolHelp::Unsupported(self.span)
};
fcx.tcx.sess.emit_err(errors::CannotCastToBool { span: self.span, expr_ty, help });
}
CastError::CastToChar => {
let mut err = type_error_struct!(
@ -536,33 +517,20 @@ impl<'a, 'tcx> CastCheck<'tcx> {
.emit();
}
CastError::IntToFatCast(known_metadata) => {
let mut err = struct_span_err!(
fcx.tcx.sess,
self.cast_span,
E0606,
"cannot cast `{}` to a pointer that {} wide",
fcx.ty_to_string(self.expr_ty),
if known_metadata.is_some() { "is" } else { "may be" }
);
err.span_label(
self.cast_span,
format!(
"creating a `{}` requires both an address and {}",
self.cast_ty,
known_metadata.unwrap_or("type-specific metadata"),
),
);
if fcx.tcx.sess.is_nightly_build() {
err.span_label(
self.expr_span,
"consider casting this expression to `*const ()`, \
then using `core::ptr::from_raw_parts`",
);
}
err.emit();
let expr_if_nightly = fcx.tcx.sess.is_nightly_build().then_some(self.expr_span);
let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty);
let expr_ty = fcx.ty_to_string(self.expr_ty);
let metadata = known_metadata.unwrap_or("type-specific metadata");
let known_wide = known_metadata.is_some();
let span = self.cast_span;
fcx.tcx.sess.emit_err(errors::IntToWide {
span,
metadata,
expr_ty,
cast_ty,
expr_if_nightly,
known_wide,
});
}
CastError::UnknownCastPtrKind | CastError::UnknownExprPtrKind => {
let unknown_cast_to = match e {
@ -570,27 +538,16 @@ impl<'a, 'tcx> CastCheck<'tcx> {
CastError::UnknownExprPtrKind => false,
_ => bug!(),
};
let mut err = struct_span_err!(
fcx.tcx.sess,
if unknown_cast_to { self.cast_span } else { self.span },
E0641,
"cannot cast {} a pointer of an unknown kind",
if unknown_cast_to { "to" } else { "from" }
);
if unknown_cast_to {
err.span_label(self.cast_span, "needs more type information");
err.note(
"the type information given here is insufficient to check whether \
the pointer cast is valid",
);
let (span, sub) = if unknown_cast_to {
(self.cast_span, errors::CastUnknownPointerSub::To(self.cast_span))
} else {
err.span_label(
self.span,
"the type information given here is insufficient to check whether \
the pointer cast is valid",
);
}
err.emit();
(self.cast_span, errors::CastUnknownPointerSub::From(self.span))
};
fcx.tcx.sess.emit_err(errors::CastUnknownPointer {
span,
to: unknown_cast_to,
sub,
});
}
CastError::ForeignNonExhaustiveAdt => {
make_invalid_casting_error(
@ -674,31 +631,18 @@ impl<'a, 'tcx> CastCheck<'tcx> {
}
fn trivial_cast_lint(&self, fcx: &FnCtxt<'a, 'tcx>) {
let t_cast = self.cast_ty;
let t_expr = self.expr_ty;
let (adjective, lint) = if t_cast.is_numeric() && t_expr.is_numeric() {
("numeric ", lint::builtin::TRIVIAL_NUMERIC_CASTS)
let (numeric, lint) = if self.cast_ty.is_numeric() && self.expr_ty.is_numeric() {
(true, lint::builtin::TRIVIAL_NUMERIC_CASTS)
} else {
("", lint::builtin::TRIVIAL_CASTS)
(false, lint::builtin::TRIVIAL_CASTS)
};
fcx.tcx.struct_span_lint_hir(
let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty);
fcx.tcx.emit_spanned_lint(
lint,
self.expr.hir_id,
self.span,
DelayDm(|| {
format!(
"trivial {}cast: `{}` as `{}`",
adjective,
fcx.ty_to_string(t_expr),
fcx.ty_to_string(t_cast)
)
}),
|lint| {
lint.help(
"cast can be replaced by coercion; this might \
require a temporary variable",
)
},
errors::TrivialCast { numeric, expr_ty, cast_ty },
);
}
@ -991,93 +935,67 @@ impl<'a, 'tcx> CastCheck<'tcx> {
if let ty::Adt(d, _) = self.expr_ty.kind()
&& d.has_dtor(fcx.tcx)
{
fcx.tcx.struct_span_lint_hir(
let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty);
fcx.tcx.emit_spanned_lint(
lint::builtin::CENUM_IMPL_DROP_CAST,
self.expr.hir_id,
self.span,
DelayDm(|| format!(
"cannot cast enum `{}` into integer `{}` because it implements `Drop`",
self.expr_ty, self.cast_ty
)),
|lint| {
lint
},
errors::CastEnumDrop {
expr_ty,
cast_ty,
}
);
}
}
fn lossy_provenance_ptr2int_lint(&self, fcx: &FnCtxt<'a, 'tcx>, t_c: ty::cast::IntTy) {
fcx.tcx.struct_span_lint_hir(
let expr_prec = self.expr.precedence().order();
let needs_parens = expr_prec < rustc_ast::util::parser::PREC_POSTFIX;
let needs_cast = !matches!(t_c, ty::cast::IntTy::U(ty::UintTy::Usize));
let cast_span = self.expr_span.shrink_to_hi().to(self.cast_span);
let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty);
let expr_span = self.expr_span.shrink_to_lo();
let sugg = match (needs_parens, needs_cast) {
(true, true) => errors::LossyProvenancePtr2IntSuggestion::NeedsParensCast {
expr_span,
cast_span,
cast_ty,
},
(true, false) => {
errors::LossyProvenancePtr2IntSuggestion::NeedsParens { expr_span, cast_span }
}
(false, true) => {
errors::LossyProvenancePtr2IntSuggestion::NeedsCast { cast_span, cast_ty }
}
(false, false) => errors::LossyProvenancePtr2IntSuggestion::Other { cast_span },
};
let lint = errors::LossyProvenancePtr2Int { expr_ty, cast_ty, sugg };
fcx.tcx.emit_spanned_lint(
lint::builtin::LOSSY_PROVENANCE_CASTS,
self.expr.hir_id,
self.span,
DelayDm(|| format!(
"under strict provenance it is considered bad style to cast pointer `{}` to integer `{}`",
self.expr_ty, self.cast_ty
)),
|lint| {
let msg = "use `.addr()` to obtain the address of a pointer";
let expr_prec = self.expr.precedence().order();
let needs_parens = expr_prec < rustc_ast::util::parser::PREC_POSTFIX;
let scalar_cast = match t_c {
ty::cast::IntTy::U(ty::UintTy::Usize) => String::new(),
_ => format!(" as {}", self.cast_ty),
};
let cast_span = self.expr_span.shrink_to_hi().to(self.cast_span);
if needs_parens {
let suggestions = vec![
(self.expr_span.shrink_to_lo(), String::from("(")),
(cast_span, format!(").addr(){scalar_cast}")),
];
lint.multipart_suggestion(msg, suggestions, Applicability::MaybeIncorrect);
} else {
lint.span_suggestion(
cast_span,
msg,
format!(".addr(){scalar_cast}"),
Applicability::MaybeIncorrect,
);
}
lint.help(
"if you can't comply with strict provenance and need to expose the pointer \
provenance you can use `.expose_addr()` instead"
);
lint
},
lint,
);
}
fn fuzzy_provenance_int2ptr_lint(&self, fcx: &FnCtxt<'a, 'tcx>) {
fcx.tcx.struct_span_lint_hir(
let sugg = errors::LossyProvenanceInt2PtrSuggestion {
lo: self.expr_span.shrink_to_lo(),
hi: self.expr_span.shrink_to_hi().to(self.cast_span),
};
let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty);
let lint = errors::LossyProvenanceInt2Ptr { expr_ty, cast_ty, sugg };
fcx.tcx.emit_spanned_lint(
lint::builtin::FUZZY_PROVENANCE_CASTS,
self.expr.hir_id,
self.span,
DelayDm(|| format!(
"strict provenance disallows casting integer `{}` to pointer `{}`",
self.expr_ty, self.cast_ty
)),
|lint| {
let msg = "use `.with_addr()` to adjust a valid pointer in the same allocation, to this address";
let suggestions = vec![
(self.expr_span.shrink_to_lo(), String::from("(...).with_addr(")),
(self.expr_span.shrink_to_hi().to(self.cast_span), String::from(")")),
];
lint.multipart_suggestion(msg, suggestions, Applicability::MaybeIncorrect);
lint.help(
"if you can't comply with strict provenance and don't have a pointer with \
the correct provenance you can use `std::ptr::from_exposed_addr()` instead"
);
lint
},
lint,
);
}
@ -1093,26 +1011,19 @@ impl<'a, 'tcx> CastCheck<'tcx> {
if let Some((deref_ty, _)) = derefed {
// Give a note about what the expr derefs to.
if deref_ty != self.expr_ty.peel_refs() {
err.span_note(
self.expr_span,
format!(
"this expression `Deref`s to `{}` which implements `is_empty`",
fcx.ty_to_string(deref_ty)
),
);
err.subdiagnostic(errors::DerefImplsIsEmpty {
span: self.expr_span,
deref_ty: fcx.ty_to_string(deref_ty),
});
}
// Create a multipart suggestion: add `!` and `.is_empty()` in
// place of the cast.
let suggestion = vec![
(self.expr_span.shrink_to_lo(), "!".to_string()),
(self.span.with_lo(self.expr_span.hi()), ".is_empty()".to_string()),
];
err.multipart_suggestion_verbose(format!(
"consider using the `is_empty` method on `{}` to determine if it contains anything",
fcx.ty_to_string(self.expr_ty),
), suggestion, Applicability::MaybeIncorrect);
err.subdiagnostic(errors::UseIsEmpty {
lo: self.expr_span.shrink_to_lo(),
hi: self.span.with_lo(self.expr_span.hi()),
expr_ty: fcx.ty_to_string(self.expr_ty),
});
}
}
}

View File

@ -6,7 +6,7 @@ use rustc_errors::{
AddToDiagnostic, Applicability, Diagnostic, DiagnosticArgValue, IntoDiagnosticArg, MultiSpan,
SubdiagnosticMessage,
};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
use rustc_middle::ty::Ty;
use rustc_span::{
edition::{Edition, LATEST_STABLE_EDITION},
@ -269,6 +269,69 @@ pub struct LangStartIncorrectRetTy<'tcx> {
pub found_ty: Ty<'tcx>,
}
#[derive(LintDiagnostic)]
#[diag(hir_typeck_lossy_provenance_int2ptr)]
#[help]
pub struct LossyProvenanceInt2Ptr<'tcx> {
pub expr_ty: Ty<'tcx>,
pub cast_ty: Ty<'tcx>,
#[subdiagnostic]
pub sugg: LossyProvenanceInt2PtrSuggestion,
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(hir_typeck_suggestion, applicability = "has-placeholders")]
pub struct LossyProvenanceInt2PtrSuggestion {
#[suggestion_part(code = "(...).with_addr(")]
pub lo: Span,
#[suggestion_part(code = ")")]
pub hi: Span,
}
#[derive(LintDiagnostic)]
#[diag(hir_typeck_lossy_provenance_ptr2int)]
#[help]
pub struct LossyProvenancePtr2Int<'tcx> {
pub expr_ty: Ty<'tcx>,
pub cast_ty: Ty<'tcx>,
#[subdiagnostic]
pub sugg: LossyProvenancePtr2IntSuggestion<'tcx>,
}
#[derive(Subdiagnostic)]
pub enum LossyProvenancePtr2IntSuggestion<'tcx> {
#[multipart_suggestion(hir_typeck_suggestion, applicability = "maybe-incorrect")]
NeedsParensCast {
#[suggestion_part(code = "(")]
expr_span: Span,
#[suggestion_part(code = ").addr() as {cast_ty}")]
cast_span: Span,
cast_ty: Ty<'tcx>,
},
#[multipart_suggestion(hir_typeck_suggestion, applicability = "maybe-incorrect")]
NeedsParens {
#[suggestion_part(code = "(")]
expr_span: Span,
#[suggestion_part(code = ").addr()")]
cast_span: Span,
},
#[suggestion(
hir_typeck_suggestion,
code = ".addr() as {cast_ty}",
applicability = "maybe-incorrect"
)]
NeedsCast {
#[primary_span]
cast_span: Span,
cast_ty: Ty<'tcx>,
},
#[suggestion(hir_typeck_suggestion, code = ".addr()", applicability = "maybe-incorrect")]
Other {
#[primary_span]
cast_span: Span,
},
}
#[derive(Subdiagnostic)]
pub enum HelpUseLatestEdition {
#[help(hir_typeck_help_set_edition_cargo)]
@ -298,6 +361,20 @@ pub struct InvalidCallee {
pub ty: String,
}
#[derive(Diagnostic)]
#[diag(hir_typeck_int_to_fat, code = "E0606")]
pub struct IntToWide<'tcx> {
#[primary_span]
#[label(hir_typeck_int_to_fat_label)]
pub span: Span,
pub metadata: &'tcx str,
pub expr_ty: String,
pub cast_ty: Ty<'tcx>,
#[label(hir_typeck_int_to_fat_label_nightly)]
pub expr_if_nightly: Option<Span>,
pub known_wide: bool,
}
#[derive(Subdiagnostic)]
pub enum OptionResultRefMismatch {
#[suggestion(
@ -396,6 +473,20 @@ pub struct UnionPatDotDot {
pub span: Span,
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(
hir_typeck_use_is_empty,
applicability = "maybe-incorrect",
style = "verbose"
)]
pub struct UseIsEmpty {
#[suggestion_part(code = "!")]
pub lo: Span,
#[suggestion_part(code = ".is_empty()")]
pub hi: Span,
pub expr_ty: String,
}
#[derive(Diagnostic)]
#[diag(hir_typeck_arg_mismatch_indeterminate)]
pub struct ArgMismatchIndeterminate {
@ -442,6 +533,15 @@ pub struct SuggestPtrNullMut {
pub span: Span,
}
#[derive(LintDiagnostic)]
#[diag(hir_typeck_trivial_cast)]
#[help]
pub struct TrivialCast<'tcx> {
pub numeric: bool,
pub expr_ty: Ty<'tcx>,
pub cast_ty: Ty<'tcx>,
}
#[derive(Diagnostic)]
#[diag(hir_typeck_no_associated_item, code = "E0599")]
pub struct NoAssociatedItem {
@ -464,6 +564,74 @@ pub struct CandidateTraitNote {
pub action_or_ty: String,
}
#[derive(Diagnostic)]
#[diag(hir_typeck_cannot_cast_to_bool, code = "E0054")]
pub struct CannotCastToBool<'tcx> {
#[primary_span]
pub span: Span,
pub expr_ty: Ty<'tcx>,
#[subdiagnostic]
pub help: CannotCastToBoolHelp,
}
#[derive(LintDiagnostic)]
#[diag(hir_typeck_cast_enum_drop)]
pub struct CastEnumDrop<'tcx> {
pub expr_ty: Ty<'tcx>,
pub cast_ty: Ty<'tcx>,
}
#[derive(Diagnostic)]
#[diag(hir_typeck_cast_unknown_pointer, code = "E0641")]
pub struct CastUnknownPointer {
#[primary_span]
pub span: Span,
pub to: bool,
#[subdiagnostic]
pub sub: CastUnknownPointerSub,
}
pub enum CastUnknownPointerSub {
To(Span),
From(Span),
}
impl rustc_errors::AddToDiagnostic for CastUnknownPointerSub {
fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, f: F)
where
F: Fn(
&mut Diagnostic,
rustc_errors::SubdiagnosticMessage,
) -> rustc_errors::SubdiagnosticMessage,
{
match self {
CastUnknownPointerSub::To(span) => {
let msg = f(diag, crate::fluent_generated::hir_typeck_label_to.into());
diag.span_label(span, msg);
let msg = f(diag, crate::fluent_generated::hir_typeck_note.into());
diag.note(msg);
}
CastUnknownPointerSub::From(span) => {
let msg = f(diag, crate::fluent_generated::hir_typeck_label_from.into());
diag.span_label(span, msg);
}
}
}
}
#[derive(Subdiagnostic)]
pub enum CannotCastToBoolHelp {
#[suggestion(
hir_typeck_suggestion,
applicability = "machine-applicable",
code = " != 0",
style = "verbose"
)]
Numeric(#[primary_span] Span),
#[label(hir_typeck_label)]
Unsupported(#[primary_span] Span),
}
#[derive(Diagnostic)]
#[diag(hir_typeck_ctor_is_private, code = "E0603")]
pub struct CtorIsPrivate {
@ -472,6 +640,14 @@ pub struct CtorIsPrivate {
pub def: String,
}
#[derive(Subdiagnostic)]
#[note(hir_typeck_deref_is_empty)]
pub struct DerefImplsIsEmpty {
#[primary_span]
pub span: Span,
pub deref_ty: String,
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(
hir_typeck_convert_using_method,

View File

@ -1,11 +1,11 @@
fn main() {
let u = 5 as bool; //~ ERROR cannot cast `i32` as `bool`
//~| HELP compare with zero instead
//~| SUGGESTION 5 != 0
//~| SUGGESTION != 0
let t = (1 + 2) as bool; //~ ERROR cannot cast `i32` as `bool`
//~| HELP compare with zero instead
//~| SUGGESTION (1 + 2) != 0
//~| SUGGESTION != 0
let _ = 5_u32 as bool; //~ ERROR cannot cast `u32` as `bool`
//~| HELP compare with zero instead

View File

@ -2,25 +2,45 @@ error[E0054]: cannot cast `i32` as `bool`
--> $DIR/cast-as-bool.rs:2:13
|
LL | let u = 5 as bool;
| ^^^^^^^^^ help: compare with zero instead: `5 != 0`
| ^^^^^^^^^
|
help: compare with zero instead
|
LL | let u = 5 != 0;
| ~~~~
error[E0054]: cannot cast `i32` as `bool`
--> $DIR/cast-as-bool.rs:6:13
|
LL | let t = (1 + 2) as bool;
| ^^^^^^^^^^^^^^^ help: compare with zero instead: `(1 + 2) != 0`
| ^^^^^^^^^^^^^^^
|
help: compare with zero instead
|
LL | let t = (1 + 2) != 0;
| ~~~~
error[E0054]: cannot cast `u32` as `bool`
--> $DIR/cast-as-bool.rs:10:13
|
LL | let _ = 5_u32 as bool;
| ^^^^^^^^^^^^^ help: compare with zero instead: `5_u32 != 0`
| ^^^^^^^^^^^^^
|
help: compare with zero instead
|
LL | let _ = 5_u32 != 0;
| ~~~~
error[E0054]: cannot cast `f64` as `bool`
--> $DIR/cast-as-bool.rs:13:13
|
LL | let _ = 64.0_f64 as bool;
| ^^^^^^^^^^^^^^^^ help: compare with zero instead: `64.0_f64 != 0`
| ^^^^^^^^^^^^^^^^
|
help: compare with zero instead
|
LL | let _ = 64.0_f64 != 0;
| ~~~~
error[E0054]: cannot cast `IntEnum` as `bool`
--> $DIR/cast-as-bool.rs:24:13

View File

@ -2,7 +2,12 @@ error[E0054]: cannot cast `i32` as `bool`
--> $DIR/cast-rfc0401-2.rs:6:13
|
LL | let _ = 3 as bool;
| ^^^^^^^^^ help: compare with zero instead: `3 != 0`
| ^^^^^^^^^
|
help: compare with zero instead
|
LL | let _ = 3 != 0;
| ~~~~
error: aborting due to previous error

View File

@ -2,7 +2,12 @@ error[E0054]: cannot cast `i32` as `bool`
--> $DIR/E0054.rs:3:24
|
LL | let x_is_nonzero = x as bool;
| ^^^^^^^^^ help: compare with zero instead: `x != 0`
| ^^^^^^^^^
|
help: compare with zero instead
|
LL | let x_is_nonzero = x != 0;
| ~~~~
error: aborting due to previous error

View File

@ -63,7 +63,12 @@ error[E0054]: cannot cast `{integer}` as `bool`
--> $DIR/error-festival.rs:33:24
|
LL | let x_is_nonzero = x as bool;
| ^^^^^^^^^ help: compare with zero instead: `x != 0`
| ^^^^^^^^^
|
help: compare with zero instead
|
LL | let x_is_nonzero = x != 0;
| ~~~~
error[E0606]: casting `&u8` as `u32` is invalid
--> $DIR/error-festival.rs:37:18

View File

@ -86,7 +86,12 @@ error[E0054]: cannot cast `i32` as `bool`
--> $DIR/cast-rfc0401.rs:39:13
|
LL | let _ = 3_i32 as bool;
| ^^^^^^^^^^^^^ help: compare with zero instead: `3_i32 != 0`
| ^^^^^^^^^^^^^
|
help: compare with zero instead
|
LL | let _ = 3_i32 != 0;
| ~~~~
error[E0054]: cannot cast `E` as `bool`
--> $DIR/cast-rfc0401.rs:40:13