use std::{ io::Error, path::{Path, PathBuf}, }; use crate::fluent_generated as fluent; use rustc_ast::Label; use rustc_errors::{ error_code, AddToDiagnostic, Applicability, Diagnostic, DiagnosticSymbolList, ErrorGuaranteed, IntoDiagnostic, MultiSpan, }; use rustc_hir::{self as hir, ExprKind, Target}; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::{MainDefinition, Ty}; use rustc_span::{Span, Symbol, DUMMY_SP}; use crate::check_attr::ProcMacroKind; use crate::lang_items::Duplicate; #[derive(Diagnostic)] #[diag(passes_incorrect_do_not_recommend_location)] pub struct IncorrectDoNotRecommendLocation { #[primary_span] pub span: Span, } #[derive(LintDiagnostic)] #[diag(passes_outer_crate_level_attr)] pub struct OuterCrateLevelAttr; #[derive(LintDiagnostic)] #[diag(passes_inner_crate_level_attr)] pub struct InnerCrateLevelAttr; #[derive(LintDiagnostic)] #[diag(passes_ignored_attr_with_macro)] pub struct IgnoredAttrWithMacro<'a> { pub sym: &'a str, } #[derive(LintDiagnostic)] #[diag(passes_ignored_attr)] pub struct IgnoredAttr<'a> { pub sym: &'a str, } #[derive(LintDiagnostic)] #[diag(passes_inline_ignored_function_prototype)] pub struct IgnoredInlineAttrFnProto; #[derive(LintDiagnostic)] #[diag(passes_inline_ignored_constants)] #[warning] #[note] pub struct IgnoredInlineAttrConstants; #[derive(Diagnostic)] #[diag(passes_inline_not_fn_or_closure, code = "E0518")] pub struct InlineNotFnOrClosure { #[primary_span] pub attr_span: Span, #[label] pub defn_span: Span, } #[derive(LintDiagnostic)] #[diag(passes_coverage_ignored_function_prototype)] pub struct IgnoredCoverageFnProto; #[derive(LintDiagnostic)] #[diag(passes_coverage_propagate)] pub struct IgnoredCoveragePropagate; #[derive(LintDiagnostic)] #[diag(passes_coverage_fn_defn)] pub struct IgnoredCoverageFnDefn; #[derive(Diagnostic)] #[diag(passes_coverage_not_coverable, code = "E0788")] pub struct IgnoredCoverageNotCoverable { #[primary_span] pub attr_span: Span, #[label] pub defn_span: Span, } #[derive(Diagnostic)] #[diag(passes_should_be_applied_to_fn)] pub struct AttrShouldBeAppliedToFn { #[primary_span] pub attr_span: Span, #[label] pub defn_span: Span, pub on_crate: bool, } #[derive(Diagnostic)] #[diag(passes_naked_tracked_caller, code = "E0736")] pub struct NakedTrackedCaller { #[primary_span] pub attr_span: Span, } #[derive(Diagnostic)] #[diag(passes_should_be_applied_to_fn, code = "E0739")] pub struct TrackedCallerWrongLocation { #[primary_span] pub attr_span: Span, #[label] pub defn_span: Span, pub on_crate: bool, } #[derive(Diagnostic)] #[diag(passes_should_be_applied_to_struct_enum, code = "E0701")] pub struct NonExhaustiveWrongLocation { #[primary_span] pub attr_span: Span, #[label] pub defn_span: Span, } #[derive(Diagnostic)] #[diag(passes_should_be_applied_to_trait)] pub struct AttrShouldBeAppliedToTrait { #[primary_span] pub attr_span: Span, #[label] pub defn_span: Span, } #[derive(LintDiagnostic)] #[diag(passes_target_feature_on_statement)] pub struct TargetFeatureOnStatement; #[derive(Diagnostic)] #[diag(passes_should_be_applied_to_static)] pub struct AttrShouldBeAppliedToStatic { #[primary_span] pub attr_span: Span, #[label] pub defn_span: Span, } #[derive(Diagnostic)] #[diag(passes_doc_expect_str)] pub struct DocExpectStr<'a> { #[primary_span] pub attr_span: Span, pub attr_name: &'a str, } #[derive(Diagnostic)] #[diag(passes_doc_alias_empty)] pub struct DocAliasEmpty<'a> { #[primary_span] pub span: Span, pub attr_str: &'a str, } #[derive(Diagnostic)] #[diag(passes_doc_alias_bad_char)] pub struct DocAliasBadChar<'a> { #[primary_span] pub span: Span, pub attr_str: &'a str, pub char_: char, } #[derive(Diagnostic)] #[diag(passes_doc_alias_start_end)] pub struct DocAliasStartEnd<'a> { #[primary_span] pub span: Span, pub attr_str: &'a str, } #[derive(Diagnostic)] #[diag(passes_doc_alias_bad_location)] pub struct DocAliasBadLocation<'a> { #[primary_span] pub span: Span, pub attr_str: &'a str, pub location: &'a str, } #[derive(Diagnostic)] #[diag(passes_doc_alias_not_an_alias)] pub struct DocAliasNotAnAlias<'a> { #[primary_span] pub span: Span, pub attr_str: &'a str, } #[derive(LintDiagnostic)] #[diag(passes_doc_alias_duplicated)] pub struct DocAliasDuplicated { #[label] pub first_defn: Span, } #[derive(Diagnostic)] #[diag(passes_doc_alias_not_string_literal)] pub struct DocAliasNotStringLiteral { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_doc_alias_malformed)] pub struct DocAliasMalformed { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_doc_keyword_empty_mod)] pub struct DocKeywordEmptyMod { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_doc_keyword_not_mod)] pub struct DocKeywordNotMod { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_doc_keyword_invalid_ident)] pub struct DocKeywordInvalidIdent { #[primary_span] pub span: Span, pub doc_keyword: Symbol, } #[derive(Diagnostic)] #[diag(passes_doc_fake_variadic_not_valid)] pub struct DocFakeVariadicNotValid { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_doc_keyword_only_impl)] pub struct DocKeywordOnlyImpl { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_doc_inline_conflict)] #[help] pub struct DocKeywordConflict { #[primary_span] pub spans: MultiSpan, } #[derive(LintDiagnostic)] #[diag(passes_doc_inline_only_use)] #[note] pub struct DocInlineOnlyUse { #[label] pub attr_span: Span, #[label(passes_not_a_use_item_label)] pub item_span: Option, } #[derive(LintDiagnostic)] #[diag(passes_doc_masked_only_extern_crate)] #[note] pub struct DocMaskedOnlyExternCrate { #[label] pub attr_span: Span, #[label(passes_not_an_extern_crate_label)] pub item_span: Option, } #[derive(LintDiagnostic)] #[diag(passes_doc_masked_not_extern_crate_self)] pub struct DocMaskedNotExternCrateSelf { #[label] pub attr_span: Span, #[label(passes_extern_crate_self_label)] pub item_span: Option, } #[derive(Diagnostic)] #[diag(passes_doc_attr_not_crate_level)] pub struct DocAttrNotCrateLevel<'a> { #[primary_span] pub span: Span, pub attr_name: &'a str, } #[derive(LintDiagnostic)] #[diag(passes_doc_test_unknown)] pub struct DocTestUnknown { pub path: String, } #[derive(LintDiagnostic)] #[diag(passes_doc_test_literal)] pub struct DocTestLiteral; #[derive(LintDiagnostic)] #[diag(passes_doc_test_takes_list)] pub struct DocTestTakesList; #[derive(LintDiagnostic)] #[diag(passes_doc_cfg_hide_takes_list)] pub struct DocCfgHideTakesList; #[derive(LintDiagnostic)] #[diag(passes_doc_test_unknown_any)] pub struct DocTestUnknownAny { pub path: String, } #[derive(LintDiagnostic)] #[diag(passes_doc_test_unknown_spotlight)] #[note] #[note(passes_no_op_note)] pub struct DocTestUnknownSpotlight { pub path: String, #[suggestion(style = "short", applicability = "machine-applicable", code = "notable_trait")] pub span: Span, } #[derive(LintDiagnostic)] #[diag(passes_doc_test_unknown_include)] pub struct DocTestUnknownInclude { pub path: String, pub value: String, pub inner: &'static str, #[suggestion(code = "#{inner}[doc = include_str!(\"{value}\")]")] pub sugg: (Span, Applicability), } #[derive(LintDiagnostic)] #[diag(passes_doc_invalid)] pub struct DocInvalid; #[derive(Diagnostic)] #[diag(passes_pass_by_value)] pub struct PassByValue { #[primary_span] pub attr_span: Span, #[label] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_allow_incoherent_impl)] pub struct AllowIncoherentImpl { #[primary_span] pub attr_span: Span, #[label] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_has_incoherent_inherent_impl)] pub struct HasIncoherentInherentImpl { #[primary_span] pub attr_span: Span, #[label] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_both_ffi_const_and_pure, code = "E0757")] pub struct BothFfiConstAndPure { #[primary_span] pub attr_span: Span, } #[derive(Diagnostic)] #[diag(passes_ffi_pure_invalid_target, code = "E0755")] pub struct FfiPureInvalidTarget { #[primary_span] pub attr_span: Span, } #[derive(Diagnostic)] #[diag(passes_ffi_const_invalid_target, code = "E0756")] pub struct FfiConstInvalidTarget { #[primary_span] pub attr_span: Span, } #[derive(Diagnostic)] #[diag(passes_ffi_returns_twice_invalid_target, code = "E0724")] pub struct FfiReturnsTwiceInvalidTarget { #[primary_span] pub attr_span: Span, } #[derive(LintDiagnostic)] #[diag(passes_must_use_async)] pub struct MustUseAsync { #[label] pub span: Span, } #[derive(LintDiagnostic)] #[diag(passes_must_use_no_effect)] pub struct MustUseNoEffect { pub article: &'static str, pub target: rustc_hir::Target, } #[derive(Diagnostic)] #[diag(passes_must_not_suspend)] pub struct MustNotSuspend { #[primary_span] pub attr_span: Span, #[label] pub span: Span, } #[derive(LintDiagnostic)] #[diag(passes_cold)] #[warning] pub struct Cold { #[label] pub span: Span, pub on_crate: bool, } #[derive(LintDiagnostic)] #[diag(passes_link)] #[warning] pub struct Link { #[label] pub span: Option, } #[derive(LintDiagnostic)] #[diag(passes_link_name)] #[warning] pub struct LinkName<'a> { #[help] pub attr_span: Option, #[label] pub span: Span, pub value: &'a str, } #[derive(Diagnostic)] #[diag(passes_no_link)] pub struct NoLink { #[primary_span] pub attr_span: Span, #[label] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_export_name)] pub struct ExportName { #[primary_span] pub attr_span: Span, #[label] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_rustc_layout_scalar_valid_range_not_struct)] pub struct RustcLayoutScalarValidRangeNotStruct { #[primary_span] pub attr_span: Span, #[label] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_rustc_layout_scalar_valid_range_arg)] pub struct RustcLayoutScalarValidRangeArg { #[primary_span] pub attr_span: Span, } #[derive(Diagnostic)] #[diag(passes_rustc_legacy_const_generics_only)] pub struct RustcLegacyConstGenericsOnly { #[primary_span] pub attr_span: Span, #[label] pub param_span: Span, } #[derive(Diagnostic)] #[diag(passes_rustc_legacy_const_generics_index)] pub struct RustcLegacyConstGenericsIndex { #[primary_span] pub attr_span: Span, #[label] pub generics_span: Span, } #[derive(Diagnostic)] #[diag(passes_rustc_legacy_const_generics_index_exceed)] pub struct RustcLegacyConstGenericsIndexExceed { #[primary_span] #[label] pub span: Span, pub arg_count: usize, } #[derive(Diagnostic)] #[diag(passes_rustc_legacy_const_generics_index_negative)] pub struct RustcLegacyConstGenericsIndexNegative { #[primary_span] pub invalid_args: Vec, } #[derive(Diagnostic)] #[diag(passes_rustc_dirty_clean)] pub struct RustcDirtyClean { #[primary_span] pub span: Span, } #[derive(LintDiagnostic)] #[diag(passes_link_section)] #[warning] pub struct LinkSection { #[label] pub span: Span, } #[derive(LintDiagnostic)] #[diag(passes_no_mangle_foreign)] #[warning] #[note] pub struct NoMangleForeign { #[label] pub span: Span, #[suggestion(code = "", applicability = "machine-applicable")] pub attr_span: Span, pub foreign_item_kind: &'static str, } #[derive(LintDiagnostic)] #[diag(passes_no_mangle)] #[warning] pub struct NoMangle { #[label] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_repr_ident, code = "E0565")] pub struct ReprIdent { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_repr_conflicting, code = "E0566")] pub struct ReprConflicting { #[primary_span] pub hint_spans: Vec, } #[derive(LintDiagnostic)] #[diag(passes_repr_conflicting, code = "E0566")] pub struct ReprConflictingLint; #[derive(Diagnostic)] #[diag(passes_used_static)] pub struct UsedStatic { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_used_compiler_linker)] pub struct UsedCompilerLinker { #[primary_span] pub spans: Vec, } #[derive(Diagnostic)] #[diag(passes_allow_internal_unstable)] pub struct AllowInternalUnstable { #[primary_span] pub attr_span: Span, #[label] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_debug_visualizer_placement)] pub struct DebugVisualizerPlacement { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_debug_visualizer_invalid)] #[note(passes_note_1)] #[note(passes_note_2)] #[note(passes_note_3)] pub struct DebugVisualizerInvalid { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_debug_visualizer_unreadable)] pub struct DebugVisualizerUnreadable<'a> { #[primary_span] pub span: Span, pub file: &'a Path, pub error: Error, } #[derive(Diagnostic)] #[diag(passes_rustc_allow_const_fn_unstable)] pub struct RustcAllowConstFnUnstable { #[primary_span] pub attr_span: Span, #[label] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_rustc_safe_intrinsic)] pub struct RustcSafeIntrinsic { #[primary_span] pub attr_span: Span, #[label] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_rustc_std_internal_symbol)] pub struct RustcStdInternalSymbol { #[primary_span] pub attr_span: Span, #[label] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_link_ordinal)] pub struct LinkOrdinal { #[primary_span] pub attr_span: Span, } #[derive(Diagnostic)] #[diag(passes_confusables)] pub struct Confusables { #[primary_span] pub attr_span: Span, } #[derive(Diagnostic)] #[diag(passes_empty_confusables)] pub(crate) struct EmptyConfusables { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_incorrect_meta_item, code = "E0539")] pub(crate) struct IncorrectMetaItem { #[primary_span] pub span: Span, #[subdiagnostic] pub suggestion: IncorrectMetaItemSuggestion, } #[derive(Subdiagnostic)] #[multipart_suggestion(passes_incorrect_meta_item_suggestion, applicability = "maybe-incorrect")] pub(crate) struct IncorrectMetaItemSuggestion { #[suggestion_part(code = "\"")] pub lo: Span, #[suggestion_part(code = "\"")] pub hi: Span, } #[derive(Diagnostic)] #[diag(passes_stability_promotable)] pub struct StabilityPromotable { #[primary_span] pub attr_span: Span, } #[derive(LintDiagnostic)] #[diag(passes_deprecated)] pub struct Deprecated; #[derive(LintDiagnostic)] #[diag(passes_macro_use)] pub struct MacroUse { pub name: Symbol, } #[derive(LintDiagnostic)] pub enum MacroExport { #[diag(passes_macro_export)] Normal, #[diag(passes_macro_export_on_decl_macro)] #[note] OnDeclMacro, #[diag(passes_invalid_macro_export_arguments)] UnknownItem { name: Symbol }, #[diag(passes_invalid_macro_export_arguments_too_many_items)] TooManyItems, } #[derive(Subdiagnostic)] pub enum UnusedNote { #[note(passes_unused_empty_lints_note)] EmptyList { name: Symbol }, #[note(passes_unused_no_lints_note)] NoLints { name: Symbol }, #[note(passes_unused_default_method_body_const_note)] DefaultMethodBodyConst, } #[derive(LintDiagnostic)] #[diag(passes_unused)] pub struct Unused { #[suggestion(code = "", applicability = "machine-applicable")] pub attr_span: Span, #[subdiagnostic] pub note: UnusedNote, } #[derive(Diagnostic)] #[diag(passes_non_exported_macro_invalid_attrs, code = "E0518")] pub struct NonExportedMacroInvalidAttrs { #[primary_span] #[label] pub attr_span: Span, } #[derive(LintDiagnostic)] #[diag(passes_unused_duplicate)] pub struct UnusedDuplicate { #[suggestion(code = "", applicability = "machine-applicable")] pub this: Span, #[note] pub other: Span, #[warning] pub warning: Option<()>, } #[derive(Diagnostic)] #[diag(passes_unused_multiple)] pub struct UnusedMultiple { #[primary_span] #[suggestion(code = "", applicability = "machine-applicable")] pub this: Span, #[note] pub other: Span, pub name: Symbol, } #[derive(Diagnostic)] #[diag(passes_rustc_lint_opt_ty)] pub struct RustcLintOptTy { #[primary_span] pub attr_span: Span, #[label] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_rustc_lint_opt_deny_field_access)] pub struct RustcLintOptDenyFieldAccess { #[primary_span] pub attr_span: Span, #[label] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_collapse_debuginfo)] pub struct CollapseDebuginfo { #[primary_span] pub attr_span: Span, #[label] pub defn_span: Span, } #[derive(LintDiagnostic)] #[diag(passes_deprecated_annotation_has_no_effect)] pub struct DeprecatedAnnotationHasNoEffect { #[suggestion(applicability = "machine-applicable", code = "")] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_unknown_external_lang_item, code = "E0264")] pub struct UnknownExternLangItem { #[primary_span] pub span: Span, pub lang_item: Symbol, } #[derive(Diagnostic)] #[diag(passes_missing_panic_handler)] pub struct MissingPanicHandler; #[derive(Diagnostic)] #[diag(passes_missing_lang_item)] #[note] #[help] pub struct MissingLangItem { pub name: Symbol, } #[derive(Diagnostic)] #[diag(passes_lang_item_fn_with_target_feature)] pub struct LangItemWithTargetFeature { #[primary_span] pub attr_span: Span, pub name: Symbol, #[label] pub sig_span: Span, } #[derive(Diagnostic)] #[diag(passes_lang_item_on_incorrect_target, code = "E0718")] pub struct LangItemOnIncorrectTarget { #[primary_span] #[label] pub span: Span, pub name: Symbol, pub expected_target: Target, pub actual_target: Target, } #[derive(Diagnostic)] #[diag(passes_unknown_lang_item, code = "E0522")] pub struct UnknownLangItem { #[primary_span] #[label] pub span: Span, pub name: Symbol, } pub struct InvalidAttrAtCrateLevel { pub span: Span, pub sugg_span: Option, pub name: Symbol, pub item: Option, } #[derive(Clone, Copy)] pub struct ItemFollowingInnerAttr { pub span: Span, pub kind: &'static str, } impl IntoDiagnostic<'_> for InvalidAttrAtCrateLevel { #[track_caller] fn into_diagnostic( self, dcx: &'_ rustc_errors::DiagCtxt, ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { let mut diag = dcx.struct_err(fluent::passes_invalid_attr_at_crate_level); diag.set_span(self.span); diag.set_arg("name", self.name); // Only emit an error with a suggestion if we can create a string out // of the attribute span if let Some(span) = self.sugg_span { diag.span_suggestion_verbose( span, fluent::passes_suggestion, String::new(), rustc_errors::Applicability::MachineApplicable, ); } if let Some(item) = self.item { diag.set_arg("kind", item.kind); diag.span_label(item.span, fluent::passes_invalid_attr_at_crate_level_item); } diag } } #[derive(Diagnostic)] #[diag(passes_duplicate_diagnostic_item_in_crate)] pub struct DuplicateDiagnosticItemInCrate { #[primary_span] pub duplicate_span: Option, #[note(passes_diagnostic_item_first_defined)] pub orig_span: Option, #[note] pub different_crates: Option<()>, pub crate_name: Symbol, pub orig_crate_name: Symbol, pub name: Symbol, } #[derive(Diagnostic)] #[diag(passes_layout_abi)] pub struct LayoutAbi { #[primary_span] pub span: Span, pub abi: String, } #[derive(Diagnostic)] #[diag(passes_layout_align)] pub struct LayoutAlign { #[primary_span] pub span: Span, pub align: String, } #[derive(Diagnostic)] #[diag(passes_layout_size)] pub struct LayoutSize { #[primary_span] pub span: Span, pub size: String, } #[derive(Diagnostic)] #[diag(passes_layout_homogeneous_aggregate)] pub struct LayoutHomogeneousAggregate { #[primary_span] pub span: Span, pub homogeneous_aggregate: String, } #[derive(Diagnostic)] #[diag(passes_layout_of)] pub struct LayoutOf { #[primary_span] pub span: Span, pub normalized_ty: String, pub ty_layout: String, } #[derive(Diagnostic)] #[diag(passes_layout_invalid_attribute)] pub struct LayoutInvalidAttribute { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_abi_of)] pub struct AbiOf { #[primary_span] pub span: Span, pub fn_name: Symbol, pub fn_abi: String, } #[derive(Diagnostic)] #[diag(passes_abi_ne)] pub struct AbiNe { #[primary_span] pub span: Span, pub left: String, pub right: String, } #[derive(Diagnostic)] #[diag(passes_abi_invalid_attribute)] pub struct AbiInvalidAttribute { #[primary_span] pub span: Span, } #[derive(Diagnostic)] #[diag(passes_unrecognized_field)] pub struct UnrecognizedField { #[primary_span] pub span: Span, pub name: Symbol, } #[derive(Diagnostic)] #[diag(passes_feature_stable_twice, code = "E0711")] pub struct FeatureStableTwice { #[primary_span] pub span: Span, pub feature: Symbol, pub since: Symbol, pub prev_since: Symbol, } #[derive(Diagnostic)] #[diag(passes_feature_previously_declared, code = "E0711")] pub struct FeaturePreviouslyDeclared<'a, 'b> { #[primary_span] pub span: Span, pub feature: Symbol, pub declared: &'a str, pub prev_declared: &'b str, } pub struct BreakNonLoop<'a> { pub span: Span, pub head: Option, pub kind: &'a str, pub suggestion: String, pub loop_label: Option