| //! Errors emitted by `rustc_hir_typeck`. |
| use std::borrow::Cow; |
| |
| use crate::fluent_generated as fluent; |
| use rustc_errors::{ |
| codes::*, Applicability, Diag, DiagArgValue, EmissionGuarantee, IntoDiagArg, MultiSpan, |
| SubdiagMessageOp, Subdiagnostic, |
| }; |
| use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; |
| use rustc_middle::ty::Ty; |
| use rustc_span::{ |
| edition::{Edition, LATEST_STABLE_EDITION}, |
| symbol::Ident, |
| Span, Symbol, |
| }; |
| |
| #[derive(Diagnostic)] |
| #[diag(hir_typeck_field_multiply_specified_in_initializer, code = E0062)] |
| pub struct FieldMultiplySpecifiedInInitializer { |
| #[primary_span] |
| #[label] |
| pub span: Span, |
| #[label(hir_typeck_previous_use_label)] |
| pub prev_span: Span, |
| pub ident: Ident, |
| } |
| |
| #[derive(Diagnostic)] |
| #[diag(hir_typeck_return_stmt_outside_of_fn_body, code = E0572)] |
| pub struct ReturnStmtOutsideOfFnBody { |
| #[primary_span] |
| pub span: Span, |
| #[label(hir_typeck_encl_body_label)] |
| pub encl_body_span: Option<Span>, |
| #[label(hir_typeck_encl_fn_label)] |
| pub encl_fn_span: Option<Span>, |
| pub statement_kind: ReturnLikeStatementKind, |
| } |
| |
| pub enum ReturnLikeStatementKind { |
| Return, |
| Become, |
| } |
| |
| impl IntoDiagArg for ReturnLikeStatementKind { |
| fn into_diag_arg(self) -> DiagArgValue { |
| let kind = match self { |
| Self::Return => "return", |
| Self::Become => "become", |
| } |
| .into(); |
| |
| DiagArgValue::Str(kind) |
| } |
| } |
| |
| #[derive(Diagnostic)] |
| #[diag(hir_typeck_rustcall_incorrect_args)] |
| pub struct RustCallIncorrectArgs { |
| #[primary_span] |
| pub span: Span, |
| } |
| |
| #[derive(Diagnostic)] |
| #[diag(hir_typeck_yield_expr_outside_of_coroutine, code = E0627)] |
| pub struct YieldExprOutsideOfCoroutine { |
| #[primary_span] |
| pub span: Span, |
| } |
| |
| #[derive(Diagnostic)] |
| #[diag(hir_typeck_struct_expr_non_exhaustive, code = E0639)] |
| pub struct StructExprNonExhaustive { |
| #[primary_span] |
| pub span: Span, |
| pub what: &'static str, |
| } |
| |
| #[derive(Diagnostic)] |
| #[diag(hir_typeck_functional_record_update_on_non_struct, code = E0436)] |
| pub struct FunctionalRecordUpdateOnNonStruct { |
| #[primary_span] |
| pub span: Span, |
| } |
| |
| #[derive(Diagnostic)] |
| #[diag(hir_typeck_address_of_temporary_taken, code = E0745)] |
| pub struct AddressOfTemporaryTaken { |
| #[primary_span] |
| #[label] |
| pub span: Span, |
| } |
| |
| #[derive(Subdiagnostic)] |
| pub enum AddReturnTypeSuggestion { |
| #[suggestion( |
| hir_typeck_add_return_type_add, |
| code = " -> {found}", |
| applicability = "machine-applicable" |
| )] |
| Add { |
| #[primary_span] |
| span: Span, |
| found: String, |
| }, |
| #[suggestion( |
| hir_typeck_add_return_type_missing_here, |
| code = " -> _", |
| applicability = "has-placeholders" |
| )] |
| MissingHere { |
| #[primary_span] |
| span: Span, |
| }, |
| } |
| |
| #[derive(Subdiagnostic)] |
| pub enum ExpectedReturnTypeLabel<'tcx> { |
| #[label(hir_typeck_expected_default_return_type)] |
| Unit { |
| #[primary_span] |
| span: Span, |
| }, |
| #[label(hir_typeck_expected_return_type)] |
| Other { |
| #[primary_span] |
| span: Span, |
| expected: Ty<'tcx>, |
| }, |
| } |
| |
| #[derive(Diagnostic)] |
| #[diag(hir_typeck_explicit_destructor, code = E0040)] |
| pub struct ExplicitDestructorCall { |
| #[primary_span] |
| #[label] |
| pub span: Span, |
| #[subdiagnostic] |
| pub sugg: ExplicitDestructorCallSugg, |
| } |
| |
| #[derive(Subdiagnostic)] |
| pub enum ExplicitDestructorCallSugg { |
| #[suggestion(hir_typeck_suggestion, code = "drop", applicability = "maybe-incorrect")] |
| Empty(#[primary_span] Span), |
| #[multipart_suggestion(hir_typeck_suggestion, style = "short")] |
| Snippet { |
| #[suggestion_part(code = "drop(")] |
| lo: Span, |
| #[suggestion_part(code = ")")] |
| hi: Span, |
| }, |
| } |
| |
| #[derive(Diagnostic)] |
| #[diag(hir_typeck_missing_parentheses_in_range, code = E0689)] |
| pub struct MissingParenthesesInRange { |
| #[primary_span] |
| #[label(hir_typeck_missing_parentheses_in_range)] |
| pub span: Span, |
| pub ty_str: String, |
| pub method_name: String, |
| #[subdiagnostic] |
| pub add_missing_parentheses: Option<AddMissingParenthesesInRange>, |
| } |
| |
| #[derive(LintDiagnostic)] |
| pub enum NeverTypeFallbackFlowingIntoUnsafe { |
| #[help] |
| #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_call)] |
| Call, |
| #[help] |
| #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_method)] |
| Method, |
| #[help] |
| #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_path)] |
| Path, |
| #[help] |
| #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_union_field)] |
| UnionField, |
| #[help] |
| #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_deref)] |
| Deref, |
| } |
| |
| #[derive(Subdiagnostic)] |
| #[multipart_suggestion( |
| hir_typeck_add_missing_parentheses_in_range, |
| style = "verbose", |
| applicability = "maybe-incorrect" |
| )] |
| pub struct AddMissingParenthesesInRange { |
| pub func_name: String, |
| #[suggestion_part(code = "(")] |
| pub left: Span, |
| #[suggestion_part(code = ")")] |
| pub right: Span, |
| } |
| |
| pub struct TypeMismatchFruTypo { |
| /// Span of the LHS of the range |
| pub expr_span: Span, |
| /// Span of the `..RHS` part of the range |
| pub fru_span: Span, |
| /// Rendered expression of the RHS of the range |
| pub expr: Option<String>, |
| } |
| |
| impl Subdiagnostic for TypeMismatchFruTypo { |
| fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>( |
| self, |
| diag: &mut Diag<'_, G>, |
| _f: &F, |
| ) { |
| diag.arg("expr", self.expr.as_deref().unwrap_or("NONE")); |
| |
| // Only explain that `a ..b` is a range if it's split up |
| if self.expr_span.between(self.fru_span).is_empty() { |
| diag.span_note(self.expr_span.to(self.fru_span), fluent::hir_typeck_fru_note); |
| } else { |
| let mut multispan: MultiSpan = vec![self.expr_span, self.fru_span].into(); |
| multispan.push_span_label(self.expr_span, fluent::hir_typeck_fru_expr); |
| multispan.push_span_label(self.fru_span, fluent::hir_typeck_fru_expr2); |
| diag.span_note(multispan, fluent::hir_typeck_fru_note); |
| } |
| |
| diag.span_suggestion( |
| self.expr_span.shrink_to_hi(), |
| fluent::hir_typeck_fru_suggestion, |
| ", ", |
| Applicability::MaybeIncorrect, |
| ); |
| } |
| } |
| |
| #[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)] |
| #[note(hir_typeck_note_edition_guide)] |
| Cargo { edition: Edition }, |
| #[help(hir_typeck_help_set_edition_standalone)] |
| #[note(hir_typeck_note_edition_guide)] |
| Standalone { edition: Edition }, |
| } |
| |
| impl HelpUseLatestEdition { |
| pub fn new() -> Self { |
| let edition = LATEST_STABLE_EDITION; |
| if rustc_session::utils::was_invoked_from_cargo() { |
| Self::Cargo { edition } |
| } else { |
| Self::Standalone { edition } |
| } |
| } |
| } |
| |
| #[derive(Diagnostic)] |
| #[diag(hir_typeck_invalid_callee, code = E0618)] |
| pub struct InvalidCallee { |
| #[primary_span] |
| pub span: Span, |
| 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( |
| hir_typeck_option_result_copied, |
| code = ".copied()", |
| style = "verbose", |
| applicability = "machine-applicable" |
| )] |
| Copied { |
| #[primary_span] |
| span: Span, |
| def_path: String, |
| }, |
| #[suggestion( |
| hir_typeck_option_result_cloned, |
| code = ".cloned()", |
| style = "verbose", |
| applicability = "machine-applicable" |
| )] |
| Cloned { |
| #[primary_span] |
| span: Span, |
| def_path: String, |
| }, |
| // FIXME: #114050 |
| // #[suggestion( |
| // hir_typeck_option_result_asref, |
| // code = ".as_ref()", |
| // style = "verbose", |
| // applicability = "machine-applicable" |
| // )] |
| // AsRef { |
| // #[primary_span] |
| // span: Span, |
| // def_path: String, |
| // expected_ty: Ty<'tcx>, |
| // expr_ty: Ty<'tcx>, |
| // }, |
| } |
| |
| pub struct RemoveSemiForCoerce { |
| pub expr: Span, |
| pub ret: Span, |
| pub semi: Span, |
| } |
| |
| impl Subdiagnostic for RemoveSemiForCoerce { |
| fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>( |
| self, |
| diag: &mut Diag<'_, G>, |
| _f: &F, |
| ) { |
| let mut multispan: MultiSpan = self.semi.into(); |
| multispan.push_span_label(self.expr, fluent::hir_typeck_remove_semi_for_coerce_expr); |
| multispan.push_span_label(self.ret, fluent::hir_typeck_remove_semi_for_coerce_ret); |
| multispan.push_span_label(self.semi, fluent::hir_typeck_remove_semi_for_coerce_semi); |
| diag.span_note(multispan, fluent::hir_typeck_remove_semi_for_coerce); |
| |
| diag.tool_only_span_suggestion( |
| self.semi, |
| fluent::hir_typeck_remove_semi_for_coerce_suggestion, |
| "", |
| Applicability::MaybeIncorrect, |
| ); |
| } |
| } |
| |
| #[derive(Diagnostic)] |
| #[diag(hir_typeck_const_select_must_be_const)] |
| #[help] |
| pub struct ConstSelectMustBeConst { |
| #[primary_span] |
| pub span: Span, |
| } |
| |
| #[derive(Diagnostic)] |
| #[diag(hir_typeck_const_select_must_be_fn)] |
| #[note] |
| #[help] |
| pub struct ConstSelectMustBeFn<'a> { |
| #[primary_span] |
| pub span: Span, |
| pub ty: Ty<'a>, |
| } |
| |
| #[derive(Diagnostic)] |
| #[diag(hir_typeck_union_pat_multiple_fields)] |
| pub struct UnionPatMultipleFields { |
| #[primary_span] |
| pub span: Span, |
| } |
| |
| #[derive(Diagnostic)] |
| #[diag(hir_typeck_union_pat_dotdot)] |
| pub struct UnionPatDotDot { |
| #[primary_span] |
| 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 { |
| #[primary_span] |
| pub span: Span, |
| } |
| |
| #[derive(Subdiagnostic)] |
| pub enum SuggestBoxing { |
| #[note(hir_typeck_suggest_boxing_note)] |
| #[multipart_suggestion( |
| hir_typeck_suggest_boxing_when_appropriate, |
| applicability = "machine-applicable" |
| )] |
| Unit { |
| #[suggestion_part(code = "Box::new(())")] |
| start: Span, |
| #[suggestion_part(code = "")] |
| end: Span, |
| }, |
| #[note(hir_typeck_suggest_boxing_note)] |
| AsyncBody, |
| #[note(hir_typeck_suggest_boxing_note)] |
| #[multipart_suggestion( |
| hir_typeck_suggest_boxing_when_appropriate, |
| applicability = "machine-applicable" |
| )] |
| Other { |
| #[suggestion_part(code = "Box::new(")] |
| start: Span, |
| #[suggestion_part(code = ")")] |
| end: Span, |
| }, |
| } |
| |
| #[derive(Subdiagnostic)] |
| #[suggestion( |
| hir_typeck_suggest_ptr_null_mut, |
| applicability = "maybe-incorrect", |
| code = "core::ptr::null_mut()" |
| )] |
| pub struct SuggestPtrNullMut { |
| #[primary_span] |
| 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 { |
| #[primary_span] |
| pub span: Span, |
| pub item_kind: &'static str, |
| pub item_name: Ident, |
| pub ty_prefix: Cow<'static, str>, |
| pub ty_str: String, |
| pub trait_missing_method: bool, |
| } |
| |
| #[derive(Subdiagnostic)] |
| #[note(hir_typeck_candidate_trait_note)] |
| pub struct CandidateTraitNote { |
| #[primary_span] |
| pub span: Span, |
| pub trait_name: String, |
| pub item_name: Ident, |
| 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::Subdiagnostic for CastUnknownPointerSub { |
| fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>( |
| self, |
| diag: &mut Diag<'_, G>, |
| f: &F, |
| ) { |
| match self { |
| CastUnknownPointerSub::To(span) => { |
| let msg = f(diag, crate::fluent_generated::hir_typeck_label_to); |
| diag.span_label(span, msg); |
| let msg = f(diag, crate::fluent_generated::hir_typeck_note); |
| diag.note(msg); |
| } |
| CastUnknownPointerSub::From(span) => { |
| let msg = f(diag, crate::fluent_generated::hir_typeck_label_from); |
| 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 { |
| #[primary_span] |
| pub span: Span, |
| 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, |
| applicability = "machine-applicable", |
| style = "verbose" |
| )] |
| pub struct SuggestConvertViaMethod<'tcx> { |
| #[suggestion_part(code = "{sugg}")] |
| pub span: Span, |
| #[suggestion_part(code = "")] |
| pub borrow_removal_span: Option<Span>, |
| pub sugg: String, |
| pub expected: Ty<'tcx>, |
| pub found: Ty<'tcx>, |
| } |
| |
| #[derive(Subdiagnostic)] |
| #[note(hir_typeck_note_caller_chooses_ty_for_ty_param)] |
| pub struct NoteCallerChoosesTyForTyParam<'tcx> { |
| pub ty_param_name: Symbol, |
| pub found_ty: Ty<'tcx>, |
| } |
| |
| #[derive(Subdiagnostic)] |
| pub enum SuggestBoxingForReturnImplTrait { |
| #[multipart_suggestion(hir_typeck_rpit_change_return_type, applicability = "maybe-incorrect")] |
| ChangeReturnType { |
| #[suggestion_part(code = "Box<dyn")] |
| start_sp: Span, |
| #[suggestion_part(code = ">")] |
| end_sp: Span, |
| }, |
| #[multipart_suggestion(hir_typeck_rpit_box_return_expr, applicability = "maybe-incorrect")] |
| BoxReturnExpr { |
| #[suggestion_part(code = "Box::new(")] |
| starts: Vec<Span>, |
| #[suggestion_part(code = ")")] |
| ends: Vec<Span>, |
| }, |
| } |
| #[derive(LintDiagnostic)] |
| #[diag(hir_typeck_dereferencing_mut_binding)] |
| pub struct DereferencingMutBinding { |
| #[label] |
| #[help] |
| pub span: Span, |
| } |