1 #![allow(rustc::untranslatable_diagnostic)] 2 #![allow(rustc::diagnostic_outside_of_impl)] 3 use std::num::NonZeroU32; 4 5 use crate::fluent_generated as fluent; 6 use rustc_errors::{ 7 AddToDiagnostic, Applicability, DecorateLint, DiagnosticMessage, DiagnosticStyledString, 8 SuggestionStyle, 9 }; 10 use rustc_hir::def_id::DefId; 11 use rustc_macros::{LintDiagnostic, Subdiagnostic}; 12 use rustc_middle::ty::{ 13 inhabitedness::InhabitedPredicate, Clause, PolyExistentialTraitRef, Ty, TyCtxt, 14 }; 15 use rustc_session::parse::ParseSess; 16 use rustc_span::{edition::Edition, sym, symbol::Ident, Span, Symbol}; 17 18 use crate::{ 19 builtin::InitError, builtin::TypeAliasBounds, errors::OverruledAttributeSub, LateContext, 20 }; 21 22 // array_into_iter.rs 23 #[derive(LintDiagnostic)] 24 #[diag(lint_array_into_iter)] 25 pub struct ArrayIntoIterDiag<'a> { 26 pub target: &'a str, 27 #[suggestion(lint_use_iter_suggestion, code = "iter", applicability = "machine-applicable")] 28 pub suggestion: Span, 29 #[subdiagnostic] 30 pub sub: Option<ArrayIntoIterDiagSub>, 31 } 32 33 #[derive(Subdiagnostic)] 34 pub enum ArrayIntoIterDiagSub { 35 #[suggestion(lint_remove_into_iter_suggestion, code = "", applicability = "maybe-incorrect")] 36 RemoveIntoIter { 37 #[primary_span] 38 span: Span, 39 }, 40 #[multipart_suggestion( 41 lint_use_explicit_into_iter_suggestion, 42 applicability = "maybe-incorrect" 43 )] 44 UseExplicitIntoIter { 45 #[suggestion_part(code = "IntoIterator::into_iter(")] 46 start_span: Span, 47 #[suggestion_part(code = ")")] 48 end_span: Span, 49 }, 50 } 51 52 // builtin.rs 53 #[derive(LintDiagnostic)] 54 #[diag(lint_builtin_while_true)] 55 pub struct BuiltinWhileTrue { 56 #[suggestion(style = "short", code = "{replace}", applicability = "machine-applicable")] 57 pub suggestion: Span, 58 pub replace: String, 59 } 60 61 #[derive(LintDiagnostic)] 62 #[diag(lint_builtin_box_pointers)] 63 pub struct BuiltinBoxPointers<'a> { 64 pub ty: Ty<'a>, 65 } 66 67 #[derive(LintDiagnostic)] 68 #[diag(lint_builtin_non_shorthand_field_patterns)] 69 pub struct BuiltinNonShorthandFieldPatterns { 70 pub ident: Ident, 71 #[suggestion(code = "{prefix}{ident}", applicability = "machine-applicable")] 72 pub suggestion: Span, 73 pub prefix: &'static str, 74 } 75 76 #[derive(LintDiagnostic)] 77 pub enum BuiltinUnsafe { 78 #[diag(lint_builtin_allow_internal_unsafe)] 79 AllowInternalUnsafe, 80 #[diag(lint_builtin_unsafe_block)] 81 UnsafeBlock, 82 #[diag(lint_builtin_unsafe_trait)] 83 UnsafeTrait, 84 #[diag(lint_builtin_unsafe_impl)] 85 UnsafeImpl, 86 #[diag(lint_builtin_no_mangle_fn)] 87 #[note(lint_builtin_overridden_symbol_name)] 88 NoMangleFn, 89 #[diag(lint_builtin_export_name_fn)] 90 #[note(lint_builtin_overridden_symbol_name)] 91 ExportNameFn, 92 #[diag(lint_builtin_link_section_fn)] 93 #[note(lint_builtin_overridden_symbol_section)] 94 LinkSectionFn, 95 #[diag(lint_builtin_no_mangle_static)] 96 #[note(lint_builtin_overridden_symbol_name)] 97 NoMangleStatic, 98 #[diag(lint_builtin_export_name_static)] 99 #[note(lint_builtin_overridden_symbol_name)] 100 ExportNameStatic, 101 #[diag(lint_builtin_link_section_static)] 102 #[note(lint_builtin_overridden_symbol_section)] 103 LinkSectionStatic, 104 #[diag(lint_builtin_no_mangle_method)] 105 #[note(lint_builtin_overridden_symbol_name)] 106 NoMangleMethod, 107 #[diag(lint_builtin_export_name_method)] 108 #[note(lint_builtin_overridden_symbol_name)] 109 ExportNameMethod, 110 #[diag(lint_builtin_decl_unsafe_fn)] 111 DeclUnsafeFn, 112 #[diag(lint_builtin_decl_unsafe_method)] 113 DeclUnsafeMethod, 114 #[diag(lint_builtin_impl_unsafe_method)] 115 ImplUnsafeMethod, 116 } 117 118 #[derive(LintDiagnostic)] 119 #[diag(lint_builtin_missing_doc)] 120 pub struct BuiltinMissingDoc<'a> { 121 pub article: &'a str, 122 pub desc: &'a str, 123 } 124 125 #[derive(LintDiagnostic)] 126 #[diag(lint_builtin_missing_copy_impl)] 127 pub struct BuiltinMissingCopyImpl; 128 129 pub struct BuiltinMissingDebugImpl<'a> { 130 pub tcx: TyCtxt<'a>, 131 pub def_id: DefId, 132 } 133 134 // Needed for def_path_str 135 impl<'a> DecorateLint<'a, ()> for BuiltinMissingDebugImpl<'_> { decorate_lint<'b>( self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()>136 fn decorate_lint<'b>( 137 self, 138 diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, 139 ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { 140 diag.set_arg("debug", self.tcx.def_path_str(self.def_id)); 141 diag 142 } 143 msg(&self) -> DiagnosticMessage144 fn msg(&self) -> DiagnosticMessage { 145 fluent::lint_builtin_missing_debug_impl 146 } 147 } 148 149 #[derive(LintDiagnostic)] 150 #[diag(lint_builtin_anonymous_params)] 151 pub struct BuiltinAnonymousParams<'a> { 152 #[suggestion(code = "_: {ty_snip}")] 153 pub suggestion: (Span, Applicability), 154 pub ty_snip: &'a str, 155 } 156 157 // FIXME(davidtwco) translatable deprecated attr 158 #[derive(LintDiagnostic)] 159 #[diag(lint_builtin_deprecated_attr_link)] 160 pub struct BuiltinDeprecatedAttrLink<'a> { 161 pub name: Symbol, 162 pub reason: &'a str, 163 pub link: &'a str, 164 #[subdiagnostic] 165 pub suggestion: BuiltinDeprecatedAttrLinkSuggestion<'a>, 166 } 167 168 #[derive(Subdiagnostic)] 169 pub enum BuiltinDeprecatedAttrLinkSuggestion<'a> { 170 #[suggestion(lint_msg_suggestion, code = "", applicability = "machine-applicable")] 171 Msg { 172 #[primary_span] 173 suggestion: Span, 174 msg: &'a str, 175 }, 176 #[suggestion(lint_default_suggestion, code = "", applicability = "machine-applicable")] 177 Default { 178 #[primary_span] 179 suggestion: Span, 180 }, 181 } 182 183 #[derive(LintDiagnostic)] 184 #[diag(lint_builtin_deprecated_attr_used)] 185 pub struct BuiltinDeprecatedAttrUsed { 186 pub name: String, 187 #[suggestion( 188 lint_builtin_deprecated_attr_default_suggestion, 189 style = "short", 190 code = "", 191 applicability = "machine-applicable" 192 )] 193 pub suggestion: Span, 194 } 195 196 #[derive(LintDiagnostic)] 197 #[diag(lint_builtin_unused_doc_comment)] 198 pub struct BuiltinUnusedDocComment<'a> { 199 pub kind: &'a str, 200 #[label] 201 pub label: Span, 202 #[subdiagnostic] 203 pub sub: BuiltinUnusedDocCommentSub, 204 } 205 206 #[derive(Subdiagnostic)] 207 pub enum BuiltinUnusedDocCommentSub { 208 #[help(lint_plain_help)] 209 PlainHelp, 210 #[help(lint_block_help)] 211 BlockHelp, 212 } 213 214 #[derive(LintDiagnostic)] 215 #[diag(lint_builtin_no_mangle_generic)] 216 pub struct BuiltinNoMangleGeneric { 217 // Use of `#[no_mangle]` suggests FFI intent; correct 218 // fix may be to monomorphize source by hand 219 #[suggestion(style = "short", code = "", applicability = "maybe-incorrect")] 220 pub suggestion: Span, 221 } 222 223 #[derive(LintDiagnostic)] 224 #[diag(lint_builtin_const_no_mangle)] 225 pub struct BuiltinConstNoMangle { 226 #[suggestion(code = "pub static", applicability = "machine-applicable")] 227 pub suggestion: Span, 228 } 229 230 #[derive(LintDiagnostic)] 231 #[diag(lint_builtin_mutable_transmutes)] 232 pub struct BuiltinMutablesTransmutes; 233 234 #[derive(LintDiagnostic)] 235 #[diag(lint_builtin_unstable_features)] 236 pub struct BuiltinUnstableFeatures; 237 238 // lint_ungated_async_fn_track_caller 239 pub struct BuiltinUngatedAsyncFnTrackCaller<'a> { 240 pub label: Span, 241 pub parse_sess: &'a ParseSess, 242 } 243 244 impl<'a> DecorateLint<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> { decorate_lint<'b>( self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()>245 fn decorate_lint<'b>( 246 self, 247 diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, 248 ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { 249 diag.span_label(self.label, fluent::lint_label); 250 rustc_session::parse::add_feature_diagnostics( 251 diag, 252 &self.parse_sess, 253 sym::closure_track_caller, 254 ); 255 diag 256 } 257 msg(&self) -> DiagnosticMessage258 fn msg(&self) -> DiagnosticMessage { 259 fluent::lint_ungated_async_fn_track_caller 260 } 261 } 262 263 #[derive(LintDiagnostic)] 264 #[diag(lint_builtin_unreachable_pub)] 265 pub struct BuiltinUnreachablePub<'a> { 266 pub what: &'a str, 267 #[suggestion(code = "pub(crate)")] 268 pub suggestion: (Span, Applicability), 269 #[help] 270 pub help: Option<()>, 271 } 272 273 pub struct SuggestChangingAssocTypes<'a, 'b> { 274 pub ty: &'a rustc_hir::Ty<'b>, 275 } 276 277 impl AddToDiagnostic for SuggestChangingAssocTypes<'_, '_> { add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) where F: Fn( &mut rustc_errors::Diagnostic, rustc_errors::SubdiagnosticMessage, ) -> rustc_errors::SubdiagnosticMessage,278 fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) 279 where 280 F: Fn( 281 &mut rustc_errors::Diagnostic, 282 rustc_errors::SubdiagnosticMessage, 283 ) -> rustc_errors::SubdiagnosticMessage, 284 { 285 // Access to associates types should use `<T as Bound>::Assoc`, which does not need a 286 // bound. Let's see if this type does that. 287 288 // We use a HIR visitor to walk the type. 289 use rustc_hir::intravisit::{self, Visitor}; 290 struct WalkAssocTypes<'a> { 291 err: &'a mut rustc_errors::Diagnostic, 292 } 293 impl Visitor<'_> for WalkAssocTypes<'_> { 294 fn visit_qpath( 295 &mut self, 296 qpath: &rustc_hir::QPath<'_>, 297 id: rustc_hir::HirId, 298 span: Span, 299 ) { 300 if TypeAliasBounds::is_type_variable_assoc(qpath) { 301 self.err.span_help(span, fluent::lint_builtin_type_alias_bounds_help); 302 } 303 intravisit::walk_qpath(self, qpath, id) 304 } 305 } 306 307 // Let's go for a walk! 308 let mut visitor = WalkAssocTypes { err: diag }; 309 visitor.visit_ty(self.ty); 310 } 311 } 312 313 #[derive(LintDiagnostic)] 314 #[diag(lint_builtin_type_alias_where_clause)] 315 pub struct BuiltinTypeAliasWhereClause<'a, 'b> { 316 #[suggestion(code = "", applicability = "machine-applicable")] 317 pub suggestion: Span, 318 #[subdiagnostic] 319 pub sub: Option<SuggestChangingAssocTypes<'a, 'b>>, 320 } 321 322 #[derive(LintDiagnostic)] 323 #[diag(lint_builtin_type_alias_generic_bounds)] 324 pub struct BuiltinTypeAliasGenericBounds<'a, 'b> { 325 #[subdiagnostic] 326 pub suggestion: BuiltinTypeAliasGenericBoundsSuggestion, 327 #[subdiagnostic] 328 pub sub: Option<SuggestChangingAssocTypes<'a, 'b>>, 329 } 330 331 pub struct BuiltinTypeAliasGenericBoundsSuggestion { 332 pub suggestions: Vec<(Span, String)>, 333 } 334 335 impl AddToDiagnostic for BuiltinTypeAliasGenericBoundsSuggestion { add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) where F: Fn( &mut rustc_errors::Diagnostic, rustc_errors::SubdiagnosticMessage, ) -> rustc_errors::SubdiagnosticMessage,336 fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) 337 where 338 F: Fn( 339 &mut rustc_errors::Diagnostic, 340 rustc_errors::SubdiagnosticMessage, 341 ) -> rustc_errors::SubdiagnosticMessage, 342 { 343 diag.multipart_suggestion( 344 fluent::lint_suggestion, 345 self.suggestions, 346 Applicability::MachineApplicable, 347 ); 348 } 349 } 350 351 #[derive(LintDiagnostic)] 352 #[diag(lint_builtin_trivial_bounds)] 353 pub struct BuiltinTrivialBounds<'a> { 354 pub predicate_kind_name: &'a str, 355 pub predicate: Clause<'a>, 356 } 357 358 #[derive(LintDiagnostic)] 359 pub enum BuiltinEllipsisInclusiveRangePatternsLint { 360 #[diag(lint_builtin_ellipsis_inclusive_range_patterns)] 361 Parenthesise { 362 #[suggestion(code = "{replace}", applicability = "machine-applicable")] 363 suggestion: Span, 364 replace: String, 365 }, 366 #[diag(lint_builtin_ellipsis_inclusive_range_patterns)] 367 NonParenthesise { 368 #[suggestion(style = "short", code = "..=", applicability = "machine-applicable")] 369 suggestion: Span, 370 }, 371 } 372 373 #[derive(LintDiagnostic)] 374 #[diag(lint_builtin_unnameable_test_items)] 375 pub struct BuiltinUnnameableTestItems; 376 377 #[derive(LintDiagnostic)] 378 #[diag(lint_builtin_keyword_idents)] 379 pub struct BuiltinKeywordIdents { 380 pub kw: Ident, 381 pub next: Edition, 382 #[suggestion(code = "r#{kw}", applicability = "machine-applicable")] 383 pub suggestion: Span, 384 } 385 386 #[derive(LintDiagnostic)] 387 #[diag(lint_builtin_explicit_outlives)] 388 pub struct BuiltinExplicitOutlives { 389 pub count: usize, 390 #[subdiagnostic] 391 pub suggestion: BuiltinExplicitOutlivesSuggestion, 392 } 393 394 #[derive(Subdiagnostic)] 395 #[multipart_suggestion(lint_suggestion)] 396 pub struct BuiltinExplicitOutlivesSuggestion { 397 #[suggestion_part(code = "")] 398 pub spans: Vec<Span>, 399 #[applicability] 400 pub applicability: Applicability, 401 } 402 403 #[derive(LintDiagnostic)] 404 #[diag(lint_builtin_incomplete_features)] 405 pub struct BuiltinIncompleteFeatures { 406 pub name: Symbol, 407 #[subdiagnostic] 408 pub note: Option<BuiltinIncompleteFeaturesNote>, 409 #[subdiagnostic] 410 pub help: Option<BuiltinIncompleteFeaturesHelp>, 411 } 412 413 #[derive(Subdiagnostic)] 414 #[help(lint_help)] 415 pub struct BuiltinIncompleteFeaturesHelp; 416 417 #[derive(Subdiagnostic)] 418 #[note(lint_note)] 419 pub struct BuiltinIncompleteFeaturesNote { 420 pub n: NonZeroU32, 421 } 422 423 pub struct BuiltinUnpermittedTypeInit<'a> { 424 pub msg: DiagnosticMessage, 425 pub ty: Ty<'a>, 426 pub label: Span, 427 pub sub: BuiltinUnpermittedTypeInitSub, 428 pub tcx: TyCtxt<'a>, 429 } 430 431 impl<'a> DecorateLint<'a, ()> for BuiltinUnpermittedTypeInit<'_> { decorate_lint<'b>( self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()>432 fn decorate_lint<'b>( 433 self, 434 diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, 435 ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { 436 diag.set_arg("ty", self.ty); 437 diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label); 438 if let InhabitedPredicate::True = self.ty.inhabited_predicate(self.tcx) { 439 // Only suggest late `MaybeUninit::assume_init` initialization if the type is inhabited. 440 diag.span_label( 441 self.label, 442 fluent::lint_builtin_unpermitted_type_init_label_suggestion, 443 ); 444 } 445 self.sub.add_to_diagnostic(diag); 446 diag 447 } 448 msg(&self) -> rustc_errors::DiagnosticMessage449 fn msg(&self) -> rustc_errors::DiagnosticMessage { 450 self.msg.clone() 451 } 452 } 453 454 // FIXME(davidtwco): make translatable 455 pub struct BuiltinUnpermittedTypeInitSub { 456 pub err: InitError, 457 } 458 459 impl AddToDiagnostic for BuiltinUnpermittedTypeInitSub { add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) where F: Fn( &mut rustc_errors::Diagnostic, rustc_errors::SubdiagnosticMessage, ) -> rustc_errors::SubdiagnosticMessage,460 fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) 461 where 462 F: Fn( 463 &mut rustc_errors::Diagnostic, 464 rustc_errors::SubdiagnosticMessage, 465 ) -> rustc_errors::SubdiagnosticMessage, 466 { 467 let mut err = self.err; 468 loop { 469 if let Some(span) = err.span { 470 diag.span_note(span, err.message); 471 } else { 472 diag.note(err.message); 473 } 474 if let Some(e) = err.nested { 475 err = *e; 476 } else { 477 break; 478 } 479 } 480 } 481 } 482 483 #[derive(LintDiagnostic)] 484 pub enum BuiltinClashingExtern<'a> { 485 #[diag(lint_builtin_clashing_extern_same_name)] 486 SameName { 487 this: Symbol, 488 orig: Symbol, 489 #[label(lint_previous_decl_label)] 490 previous_decl_label: Span, 491 #[label(lint_mismatch_label)] 492 mismatch_label: Span, 493 #[subdiagnostic] 494 sub: BuiltinClashingExternSub<'a>, 495 }, 496 #[diag(lint_builtin_clashing_extern_diff_name)] 497 DiffName { 498 this: Symbol, 499 orig: Symbol, 500 #[label(lint_previous_decl_label)] 501 previous_decl_label: Span, 502 #[label(lint_mismatch_label)] 503 mismatch_label: Span, 504 #[subdiagnostic] 505 sub: BuiltinClashingExternSub<'a>, 506 }, 507 } 508 509 // FIXME(davidtwco): translatable expected/found 510 pub struct BuiltinClashingExternSub<'a> { 511 pub tcx: TyCtxt<'a>, 512 pub expected: Ty<'a>, 513 pub found: Ty<'a>, 514 } 515 516 impl AddToDiagnostic for BuiltinClashingExternSub<'_> { add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) where F: Fn( &mut rustc_errors::Diagnostic, rustc_errors::SubdiagnosticMessage, ) -> rustc_errors::SubdiagnosticMessage,517 fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) 518 where 519 F: Fn( 520 &mut rustc_errors::Diagnostic, 521 rustc_errors::SubdiagnosticMessage, 522 ) -> rustc_errors::SubdiagnosticMessage, 523 { 524 let mut expected_str = DiagnosticStyledString::new(); 525 expected_str.push(self.expected.fn_sig(self.tcx).to_string(), false); 526 let mut found_str = DiagnosticStyledString::new(); 527 found_str.push(self.found.fn_sig(self.tcx).to_string(), true); 528 diag.note_expected_found(&"", expected_str, &"", found_str); 529 } 530 } 531 532 #[derive(LintDiagnostic)] 533 #[diag(lint_builtin_deref_nullptr)] 534 pub struct BuiltinDerefNullptr { 535 #[label] 536 pub label: Span, 537 } 538 539 // FIXME: migrate fluent::lint::builtin_asm_labels 540 541 #[derive(LintDiagnostic)] 542 pub enum BuiltinSpecialModuleNameUsed { 543 #[diag(lint_builtin_special_module_name_used_lib)] 544 #[note] 545 #[help] 546 Lib, 547 #[diag(lint_builtin_special_module_name_used_main)] 548 #[note] 549 Main, 550 } 551 552 #[derive(LintDiagnostic)] 553 #[diag(lint_builtin_unexpected_cli_config_name)] 554 #[help] 555 pub struct BuiltinUnexpectedCliConfigName { 556 pub name: Symbol, 557 } 558 559 #[derive(LintDiagnostic)] 560 #[diag(lint_builtin_unexpected_cli_config_value)] 561 #[help] 562 pub struct BuiltinUnexpectedCliConfigValue { 563 pub name: Symbol, 564 pub value: Symbol, 565 } 566 567 // deref_into_dyn_supertrait.rs 568 #[derive(LintDiagnostic)] 569 #[diag(lint_supertrait_as_deref_target)] 570 pub struct SupertraitAsDerefTarget<'a> { 571 pub t: Ty<'a>, 572 pub target_principal: PolyExistentialTraitRef<'a>, 573 #[subdiagnostic] 574 pub label: Option<SupertraitAsDerefTargetLabel>, 575 } 576 577 #[derive(Subdiagnostic)] 578 #[label(lint_label)] 579 pub struct SupertraitAsDerefTargetLabel { 580 #[primary_span] 581 pub label: Span, 582 } 583 584 // enum_intrinsics_non_enums.rs 585 #[derive(LintDiagnostic)] 586 #[diag(lint_enum_intrinsics_mem_discriminant)] 587 pub struct EnumIntrinsicsMemDiscriminate<'a> { 588 pub ty_param: Ty<'a>, 589 #[note] 590 pub note: Span, 591 } 592 593 #[derive(LintDiagnostic)] 594 #[diag(lint_enum_intrinsics_mem_variant)] 595 #[note] 596 pub struct EnumIntrinsicsMemVariant<'a> { 597 pub ty_param: Ty<'a>, 598 } 599 600 // expect.rs 601 #[derive(LintDiagnostic)] 602 #[diag(lint_expectation)] 603 pub struct Expectation { 604 #[subdiagnostic] 605 pub rationale: Option<ExpectationNote>, 606 #[note] 607 pub note: Option<()>, 608 } 609 610 #[derive(Subdiagnostic)] 611 #[note(lint_rationale)] 612 pub struct ExpectationNote { 613 pub rationale: Symbol, 614 } 615 616 // for_loops_over_fallibles.rs 617 #[derive(LintDiagnostic)] 618 #[diag(lint_for_loops_over_fallibles)] 619 pub struct ForLoopsOverFalliblesDiag<'a> { 620 pub article: &'static str, 621 pub ty: &'static str, 622 #[subdiagnostic] 623 pub sub: ForLoopsOverFalliblesLoopSub<'a>, 624 #[subdiagnostic] 625 pub question_mark: Option<ForLoopsOverFalliblesQuestionMark>, 626 #[subdiagnostic] 627 pub suggestion: ForLoopsOverFalliblesSuggestion<'a>, 628 } 629 630 #[derive(Subdiagnostic)] 631 pub enum ForLoopsOverFalliblesLoopSub<'a> { 632 #[suggestion(lint_remove_next, code = ".by_ref()", applicability = "maybe-incorrect")] 633 RemoveNext { 634 #[primary_span] 635 suggestion: Span, 636 recv_snip: String, 637 }, 638 #[multipart_suggestion(lint_use_while_let, applicability = "maybe-incorrect")] 639 UseWhileLet { 640 #[suggestion_part(code = "while let {var}(")] 641 start_span: Span, 642 #[suggestion_part(code = ") = ")] 643 end_span: Span, 644 var: &'a str, 645 }, 646 } 647 648 #[derive(Subdiagnostic)] 649 #[suggestion(lint_use_question_mark, code = "?", applicability = "maybe-incorrect")] 650 pub struct ForLoopsOverFalliblesQuestionMark { 651 #[primary_span] 652 pub suggestion: Span, 653 } 654 655 #[derive(Subdiagnostic)] 656 #[multipart_suggestion(lint_suggestion, applicability = "maybe-incorrect")] 657 pub struct ForLoopsOverFalliblesSuggestion<'a> { 658 pub var: &'a str, 659 #[suggestion_part(code = "if let {var}(")] 660 pub start_span: Span, 661 #[suggestion_part(code = ") = ")] 662 pub end_span: Span, 663 } 664 665 // drop_forget_useless.rs 666 #[derive(LintDiagnostic)] 667 #[diag(lint_dropping_references)] 668 #[note] 669 pub struct DropRefDiag<'a> { 670 pub arg_ty: Ty<'a>, 671 #[label] 672 pub label: Span, 673 } 674 675 #[derive(LintDiagnostic)] 676 #[diag(lint_dropping_copy_types)] 677 #[note] 678 pub struct DropCopyDiag<'a> { 679 pub arg_ty: Ty<'a>, 680 #[label] 681 pub label: Span, 682 } 683 684 #[derive(LintDiagnostic)] 685 #[diag(lint_forgetting_references)] 686 #[note] 687 pub struct ForgetRefDiag<'a> { 688 pub arg_ty: Ty<'a>, 689 #[label] 690 pub label: Span, 691 } 692 693 #[derive(LintDiagnostic)] 694 #[diag(lint_forgetting_copy_types)] 695 #[note] 696 pub struct ForgetCopyDiag<'a> { 697 pub arg_ty: Ty<'a>, 698 #[label] 699 pub label: Span, 700 } 701 702 #[derive(LintDiagnostic)] 703 #[diag(lint_undropped_manually_drops)] 704 pub struct UndroppedManuallyDropsDiag<'a> { 705 pub arg_ty: Ty<'a>, 706 #[label] 707 pub label: Span, 708 #[subdiagnostic] 709 pub suggestion: UndroppedManuallyDropsSuggestion, 710 } 711 712 #[derive(Subdiagnostic)] 713 #[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")] 714 pub struct UndroppedManuallyDropsSuggestion { 715 #[suggestion_part(code = "std::mem::ManuallyDrop::into_inner(")] 716 pub start_span: Span, 717 #[suggestion_part(code = ")")] 718 pub end_span: Span, 719 } 720 721 // invalid_from_utf8.rs 722 #[derive(LintDiagnostic)] 723 pub enum InvalidFromUtf8Diag { 724 #[diag(lint_invalid_from_utf8_unchecked)] 725 Unchecked { 726 method: String, 727 valid_up_to: usize, 728 #[label] 729 label: Span, 730 }, 731 #[diag(lint_invalid_from_utf8_checked)] 732 Checked { 733 method: String, 734 valid_up_to: usize, 735 #[label] 736 label: Span, 737 }, 738 } 739 740 // reference_casting.rs 741 #[derive(LintDiagnostic)] 742 #[diag(lint_invalid_reference_casting)] 743 pub struct InvalidReferenceCastingDiag; 744 745 // hidden_unicode_codepoints.rs 746 #[derive(LintDiagnostic)] 747 #[diag(lint_hidden_unicode_codepoints)] 748 #[note] 749 pub struct HiddenUnicodeCodepointsDiag<'a> { 750 pub label: &'a str, 751 pub count: usize, 752 #[label] 753 pub span_label: Span, 754 #[subdiagnostic] 755 pub labels: Option<HiddenUnicodeCodepointsDiagLabels>, 756 #[subdiagnostic] 757 pub sub: HiddenUnicodeCodepointsDiagSub, 758 } 759 760 pub struct HiddenUnicodeCodepointsDiagLabels { 761 pub spans: Vec<(char, Span)>, 762 } 763 764 impl AddToDiagnostic for HiddenUnicodeCodepointsDiagLabels { add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) where F: Fn( &mut rustc_errors::Diagnostic, rustc_errors::SubdiagnosticMessage, ) -> rustc_errors::SubdiagnosticMessage,765 fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) 766 where 767 F: Fn( 768 &mut rustc_errors::Diagnostic, 769 rustc_errors::SubdiagnosticMessage, 770 ) -> rustc_errors::SubdiagnosticMessage, 771 { 772 for (c, span) in self.spans { 773 diag.span_label(span, format!("{:?}", c)); 774 } 775 } 776 } 777 778 pub enum HiddenUnicodeCodepointsDiagSub { 779 Escape { spans: Vec<(char, Span)> }, 780 NoEscape { spans: Vec<(char, Span)> }, 781 } 782 783 // Used because of multiple multipart_suggestion and note 784 impl AddToDiagnostic for HiddenUnicodeCodepointsDiagSub { add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) where F: Fn( &mut rustc_errors::Diagnostic, rustc_errors::SubdiagnosticMessage, ) -> rustc_errors::SubdiagnosticMessage,785 fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) 786 where 787 F: Fn( 788 &mut rustc_errors::Diagnostic, 789 rustc_errors::SubdiagnosticMessage, 790 ) -> rustc_errors::SubdiagnosticMessage, 791 { 792 match self { 793 HiddenUnicodeCodepointsDiagSub::Escape { spans } => { 794 diag.multipart_suggestion_with_style( 795 fluent::lint_suggestion_remove, 796 spans.iter().map(|(_, span)| (*span, "".to_string())).collect(), 797 Applicability::MachineApplicable, 798 SuggestionStyle::HideCodeAlways, 799 ); 800 diag.multipart_suggestion( 801 fluent::lint_suggestion_escape, 802 spans 803 .into_iter() 804 .map(|(c, span)| { 805 let c = format!("{:?}", c); 806 (span, c[1..c.len() - 1].to_string()) 807 }) 808 .collect(), 809 Applicability::MachineApplicable, 810 ); 811 } 812 HiddenUnicodeCodepointsDiagSub::NoEscape { spans } => { 813 // FIXME: in other suggestions we've reversed the inner spans of doc comments. We 814 // should do the same here to provide the same good suggestions as we do for 815 // literals above. 816 diag.set_arg( 817 "escaped", 818 spans 819 .into_iter() 820 .map(|(c, _)| format!("{:?}", c)) 821 .collect::<Vec<String>>() 822 .join(", "), 823 ); 824 diag.note(fluent::lint_suggestion_remove); 825 diag.note(fluent::lint_no_suggestion_note_escape); 826 } 827 } 828 } 829 } 830 831 // map_unit_fn.rs 832 #[derive(LintDiagnostic)] 833 #[diag(lint_map_unit_fn)] 834 #[note] 835 pub struct MappingToUnit { 836 #[label(lint_function_label)] 837 pub function_label: Span, 838 #[label(lint_argument_label)] 839 pub argument_label: Span, 840 #[label(lint_map_label)] 841 pub map_label: Span, 842 #[suggestion(style = "verbose", code = "{replace}", applicability = "maybe-incorrect")] 843 pub suggestion: Span, 844 pub replace: String, 845 } 846 847 // internal.rs 848 #[derive(LintDiagnostic)] 849 #[diag(lint_default_hash_types)] 850 #[note] 851 pub struct DefaultHashTypesDiag<'a> { 852 pub preferred: &'a str, 853 pub used: Symbol, 854 } 855 856 #[derive(LintDiagnostic)] 857 #[diag(lint_query_instability)] 858 #[note] 859 pub struct QueryInstability { 860 pub query: Symbol, 861 } 862 863 #[derive(LintDiagnostic)] 864 #[diag(lint_tykind_kind)] 865 pub struct TykindKind { 866 #[suggestion(code = "ty", applicability = "maybe-incorrect")] 867 pub suggestion: Span, 868 } 869 870 #[derive(LintDiagnostic)] 871 #[diag(lint_tykind)] 872 #[help] 873 pub struct TykindDiag; 874 875 #[derive(LintDiagnostic)] 876 #[diag(lint_ty_qualified)] 877 pub struct TyQualified { 878 pub ty: String, 879 #[suggestion(code = "{ty}", applicability = "maybe-incorrect")] 880 pub suggestion: Span, 881 } 882 883 #[derive(LintDiagnostic)] 884 #[diag(lint_lintpass_by_hand)] 885 #[help] 886 pub struct LintPassByHand; 887 888 #[derive(LintDiagnostic)] 889 #[diag(lint_non_existent_doc_keyword)] 890 #[help] 891 pub struct NonExistentDocKeyword { 892 pub keyword: Symbol, 893 } 894 895 #[derive(LintDiagnostic)] 896 #[diag(lint_diag_out_of_impl)] 897 pub struct DiagOutOfImpl; 898 899 #[derive(LintDiagnostic)] 900 #[diag(lint_untranslatable_diag)] 901 pub struct UntranslatableDiag; 902 903 #[derive(LintDiagnostic)] 904 #[diag(lint_trivial_untranslatable_diag)] 905 pub struct UntranslatableDiagnosticTrivial; 906 907 #[derive(LintDiagnostic)] 908 #[diag(lint_bad_opt_access)] 909 pub struct BadOptAccessDiag<'a> { 910 pub msg: &'a str, 911 } 912 913 // let_underscore.rs 914 #[derive(LintDiagnostic)] 915 pub enum NonBindingLet { 916 #[diag(lint_non_binding_let_on_sync_lock)] 917 SyncLock { 918 #[subdiagnostic] 919 sub: NonBindingLetSub, 920 }, 921 #[diag(lint_non_binding_let_on_drop_type)] 922 DropType { 923 #[subdiagnostic] 924 sub: NonBindingLetSub, 925 }, 926 } 927 928 pub struct NonBindingLetSub { 929 pub suggestion: Span, 930 pub multi_suggestion_start: Span, 931 pub multi_suggestion_end: Span, 932 } 933 934 impl AddToDiagnostic for NonBindingLetSub { add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) where F: Fn( &mut rustc_errors::Diagnostic, rustc_errors::SubdiagnosticMessage, ) -> rustc_errors::SubdiagnosticMessage,935 fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) 936 where 937 F: Fn( 938 &mut rustc_errors::Diagnostic, 939 rustc_errors::SubdiagnosticMessage, 940 ) -> rustc_errors::SubdiagnosticMessage, 941 { 942 diag.span_suggestion_verbose( 943 self.suggestion, 944 fluent::lint_non_binding_let_suggestion, 945 "_unused", 946 Applicability::MachineApplicable, 947 ); 948 diag.multipart_suggestion( 949 fluent::lint_non_binding_let_multi_suggestion, 950 vec![ 951 (self.multi_suggestion_start, "drop(".to_string()), 952 (self.multi_suggestion_end, ")".to_string()), 953 ], 954 Applicability::MachineApplicable, 955 ); 956 } 957 } 958 959 // levels.rs 960 #[derive(LintDiagnostic)] 961 #[diag(lint_overruled_attribute)] 962 pub struct OverruledAttributeLint<'a> { 963 #[label] 964 pub overruled: Span, 965 pub lint_level: &'a str, 966 pub lint_source: Symbol, 967 #[subdiagnostic] 968 pub sub: OverruledAttributeSub, 969 } 970 971 #[derive(LintDiagnostic)] 972 #[diag(lint_deprecated_lint_name)] 973 pub struct DeprecatedLintName<'a> { 974 pub name: String, 975 #[suggestion(code = "{replace}", applicability = "machine-applicable")] 976 pub suggestion: Span, 977 pub replace: &'a str, 978 } 979 980 // FIXME: Non-translatable msg 981 #[derive(LintDiagnostic)] 982 #[diag(lint_renamed_or_removed_lint)] 983 pub struct RenamedOrRemovedLint<'a> { 984 pub msg: &'a str, 985 #[subdiagnostic] 986 pub suggestion: Option<RenamedOrRemovedLintSuggestion<'a>>, 987 } 988 989 #[derive(Subdiagnostic)] 990 #[suggestion(lint_suggestion, code = "{replace}", applicability = "machine-applicable")] 991 pub struct RenamedOrRemovedLintSuggestion<'a> { 992 #[primary_span] 993 pub suggestion: Span, 994 pub replace: &'a str, 995 } 996 997 #[derive(LintDiagnostic)] 998 #[diag(lint_unknown_lint)] 999 pub struct UnknownLint { 1000 pub name: String, 1001 #[subdiagnostic] 1002 pub suggestion: Option<UnknownLintSuggestion>, 1003 } 1004 1005 #[derive(Subdiagnostic)] 1006 #[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")] 1007 pub struct UnknownLintSuggestion { 1008 #[primary_span] 1009 pub suggestion: Span, 1010 pub replace: Symbol, 1011 } 1012 1013 #[derive(LintDiagnostic)] 1014 #[diag(lint_ignored_unless_crate_specified)] 1015 pub struct IgnoredUnlessCrateSpecified<'a> { 1016 pub level: &'a str, 1017 pub name: Symbol, 1018 } 1019 1020 // methods.rs 1021 #[derive(LintDiagnostic)] 1022 #[diag(lint_cstring_ptr)] 1023 #[note] 1024 #[help] 1025 pub struct CStringPtr { 1026 #[label(lint_as_ptr_label)] 1027 pub as_ptr: Span, 1028 #[label(lint_unwrap_label)] 1029 pub unwrap: Span, 1030 } 1031 1032 // multiple_supertrait_upcastable.rs 1033 #[derive(LintDiagnostic)] 1034 #[diag(lint_multiple_supertrait_upcastable)] 1035 pub struct MultipleSupertraitUpcastable { 1036 pub ident: Ident, 1037 } 1038 1039 // non_ascii_idents.rs 1040 #[derive(LintDiagnostic)] 1041 #[diag(lint_identifier_non_ascii_char)] 1042 pub struct IdentifierNonAsciiChar; 1043 1044 #[derive(LintDiagnostic)] 1045 #[diag(lint_identifier_uncommon_codepoints)] 1046 pub struct IdentifierUncommonCodepoints; 1047 1048 #[derive(LintDiagnostic)] 1049 #[diag(lint_confusable_identifier_pair)] 1050 pub struct ConfusableIdentifierPair { 1051 pub existing_sym: Symbol, 1052 pub sym: Symbol, 1053 #[label] 1054 pub label: Span, 1055 } 1056 1057 #[derive(LintDiagnostic)] 1058 #[diag(lint_mixed_script_confusables)] 1059 #[note(lint_includes_note)] 1060 #[note] 1061 pub struct MixedScriptConfusables { 1062 pub set: String, 1063 pub includes: String, 1064 } 1065 1066 // non_fmt_panic.rs 1067 pub struct NonFmtPanicUnused { 1068 pub count: usize, 1069 pub suggestion: Option<Span>, 1070 } 1071 1072 // Used because of two suggestions based on one Option<Span> 1073 impl<'a> DecorateLint<'a, ()> for NonFmtPanicUnused { decorate_lint<'b>( self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()>1074 fn decorate_lint<'b>( 1075 self, 1076 diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, 1077 ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { 1078 diag.set_arg("count", self.count); 1079 diag.note(fluent::lint_note); 1080 if let Some(span) = self.suggestion { 1081 diag.span_suggestion( 1082 span.shrink_to_hi(), 1083 fluent::lint_add_args_suggestion, 1084 ", ...", 1085 Applicability::HasPlaceholders, 1086 ); 1087 diag.span_suggestion( 1088 span.shrink_to_lo(), 1089 fluent::lint_add_fmt_suggestion, 1090 "\"{}\", ", 1091 Applicability::MachineApplicable, 1092 ); 1093 } 1094 diag 1095 } 1096 msg(&self) -> rustc_errors::DiagnosticMessage1097 fn msg(&self) -> rustc_errors::DiagnosticMessage { 1098 fluent::lint_non_fmt_panic_unused 1099 } 1100 } 1101 1102 #[derive(LintDiagnostic)] 1103 #[diag(lint_non_fmt_panic_braces)] 1104 #[note] 1105 pub struct NonFmtPanicBraces { 1106 pub count: usize, 1107 #[suggestion(code = "\"{{}}\", ", applicability = "machine-applicable")] 1108 pub suggestion: Option<Span>, 1109 } 1110 1111 // nonstandard_style.rs 1112 #[derive(LintDiagnostic)] 1113 #[diag(lint_non_camel_case_type)] 1114 pub struct NonCamelCaseType<'a> { 1115 pub sort: &'a str, 1116 pub name: &'a str, 1117 #[subdiagnostic] 1118 pub sub: NonCamelCaseTypeSub, 1119 } 1120 1121 #[derive(Subdiagnostic)] 1122 pub enum NonCamelCaseTypeSub { 1123 #[label(lint_label)] 1124 Label { 1125 #[primary_span] 1126 span: Span, 1127 }, 1128 #[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")] 1129 Suggestion { 1130 #[primary_span] 1131 span: Span, 1132 replace: String, 1133 }, 1134 } 1135 1136 #[derive(LintDiagnostic)] 1137 #[diag(lint_non_snake_case)] 1138 pub struct NonSnakeCaseDiag<'a> { 1139 pub sort: &'a str, 1140 pub name: &'a str, 1141 pub sc: String, 1142 #[subdiagnostic] 1143 pub sub: NonSnakeCaseDiagSub, 1144 } 1145 1146 pub enum NonSnakeCaseDiagSub { 1147 Label { span: Span }, 1148 Help, 1149 RenameOrConvertSuggestion { span: Span, suggestion: Ident }, 1150 ConvertSuggestion { span: Span, suggestion: String }, 1151 SuggestionAndNote { span: Span }, 1152 } 1153 1154 impl AddToDiagnostic for NonSnakeCaseDiagSub { add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) where F: Fn( &mut rustc_errors::Diagnostic, rustc_errors::SubdiagnosticMessage, ) -> rustc_errors::SubdiagnosticMessage,1155 fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) 1156 where 1157 F: Fn( 1158 &mut rustc_errors::Diagnostic, 1159 rustc_errors::SubdiagnosticMessage, 1160 ) -> rustc_errors::SubdiagnosticMessage, 1161 { 1162 match self { 1163 NonSnakeCaseDiagSub::Label { span } => { 1164 diag.span_label(span, fluent::lint_label); 1165 } 1166 NonSnakeCaseDiagSub::Help => { 1167 diag.help(fluent::lint_help); 1168 } 1169 NonSnakeCaseDiagSub::ConvertSuggestion { span, suggestion } => { 1170 diag.span_suggestion( 1171 span, 1172 fluent::lint_convert_suggestion, 1173 suggestion, 1174 Applicability::MaybeIncorrect, 1175 ); 1176 } 1177 NonSnakeCaseDiagSub::RenameOrConvertSuggestion { span, suggestion } => { 1178 diag.span_suggestion( 1179 span, 1180 fluent::lint_rename_or_convert_suggestion, 1181 suggestion, 1182 Applicability::MaybeIncorrect, 1183 ); 1184 } 1185 NonSnakeCaseDiagSub::SuggestionAndNote { span } => { 1186 diag.note(fluent::lint_cannot_convert_note); 1187 diag.span_suggestion( 1188 span, 1189 fluent::lint_rename_suggestion, 1190 "", 1191 Applicability::MaybeIncorrect, 1192 ); 1193 } 1194 } 1195 } 1196 } 1197 1198 #[derive(LintDiagnostic)] 1199 #[diag(lint_non_upper_case_global)] 1200 pub struct NonUpperCaseGlobal<'a> { 1201 pub sort: &'a str, 1202 pub name: &'a str, 1203 #[subdiagnostic] 1204 pub sub: NonUpperCaseGlobalSub, 1205 } 1206 1207 #[derive(Subdiagnostic)] 1208 pub enum NonUpperCaseGlobalSub { 1209 #[label(lint_label)] 1210 Label { 1211 #[primary_span] 1212 span: Span, 1213 }, 1214 #[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")] 1215 Suggestion { 1216 #[primary_span] 1217 span: Span, 1218 replace: String, 1219 }, 1220 } 1221 1222 // noop_method_call.rs 1223 #[derive(LintDiagnostic)] 1224 #[diag(lint_noop_method_call)] 1225 #[note] 1226 pub struct NoopMethodCallDiag<'a> { 1227 pub method: Symbol, 1228 pub receiver_ty: Ty<'a>, 1229 #[label] 1230 pub label: Span, 1231 } 1232 1233 #[derive(LintDiagnostic)] 1234 #[diag(lint_suspicious_double_ref_deref)] 1235 pub struct SuspiciousDoubleRefDerefDiag<'a> { 1236 pub ty: Ty<'a>, 1237 } 1238 1239 #[derive(LintDiagnostic)] 1240 #[diag(lint_suspicious_double_ref_clone)] 1241 pub struct SuspiciousDoubleRefCloneDiag<'a> { 1242 pub ty: Ty<'a>, 1243 } 1244 1245 // pass_by_value.rs 1246 #[derive(LintDiagnostic)] 1247 #[diag(lint_pass_by_value)] 1248 pub struct PassByValueDiag { 1249 pub ty: String, 1250 #[suggestion(code = "{ty}", applicability = "maybe-incorrect")] 1251 pub suggestion: Span, 1252 } 1253 1254 // redundant_semicolon.rs 1255 #[derive(LintDiagnostic)] 1256 #[diag(lint_redundant_semicolons)] 1257 pub struct RedundantSemicolonsDiag { 1258 pub multiple: bool, 1259 #[suggestion(code = "", applicability = "maybe-incorrect")] 1260 pub suggestion: Span, 1261 } 1262 1263 // traits.rs 1264 pub struct DropTraitConstraintsDiag<'a> { 1265 pub predicate: Clause<'a>, 1266 pub tcx: TyCtxt<'a>, 1267 pub def_id: DefId, 1268 } 1269 1270 // Needed for def_path_str 1271 impl<'a> DecorateLint<'a, ()> for DropTraitConstraintsDiag<'_> { decorate_lint<'b>( self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()>1272 fn decorate_lint<'b>( 1273 self, 1274 diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, 1275 ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { 1276 diag.set_arg("predicate", self.predicate); 1277 diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id)) 1278 } 1279 msg(&self) -> rustc_errors::DiagnosticMessage1280 fn msg(&self) -> rustc_errors::DiagnosticMessage { 1281 fluent::lint_drop_trait_constraints 1282 } 1283 } 1284 1285 pub struct DropGlue<'a> { 1286 pub tcx: TyCtxt<'a>, 1287 pub def_id: DefId, 1288 } 1289 1290 // Needed for def_path_str 1291 impl<'a> DecorateLint<'a, ()> for DropGlue<'_> { decorate_lint<'b>( self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()>1292 fn decorate_lint<'b>( 1293 self, 1294 diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, 1295 ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { 1296 diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id)) 1297 } 1298 msg(&self) -> rustc_errors::DiagnosticMessage1299 fn msg(&self) -> rustc_errors::DiagnosticMessage { 1300 fluent::lint_drop_glue 1301 } 1302 } 1303 1304 // types.rs 1305 #[derive(LintDiagnostic)] 1306 #[diag(lint_range_endpoint_out_of_range)] 1307 pub struct RangeEndpointOutOfRange<'a> { 1308 pub ty: &'a str, 1309 #[subdiagnostic] 1310 pub sub: UseInclusiveRange<'a>, 1311 } 1312 1313 #[derive(Subdiagnostic)] 1314 pub enum UseInclusiveRange<'a> { 1315 #[suggestion( 1316 lint_range_use_inclusive_range, 1317 code = "{start}..={literal}{suffix}", 1318 applicability = "machine-applicable" 1319 )] 1320 WithoutParen { 1321 #[primary_span] 1322 sugg: Span, 1323 start: String, 1324 literal: u128, 1325 suffix: &'a str, 1326 }, 1327 #[multipart_suggestion(lint_range_use_inclusive_range, applicability = "machine-applicable")] 1328 WithParen { 1329 #[suggestion_part(code = "=")] 1330 eq_sugg: Span, 1331 #[suggestion_part(code = "{literal}{suffix}")] 1332 lit_sugg: Span, 1333 literal: u128, 1334 suffix: &'a str, 1335 }, 1336 } 1337 1338 #[derive(LintDiagnostic)] 1339 #[diag(lint_overflowing_bin_hex)] 1340 pub struct OverflowingBinHex<'a> { 1341 pub ty: &'a str, 1342 pub lit: String, 1343 pub dec: u128, 1344 pub actually: String, 1345 #[subdiagnostic] 1346 pub sign: OverflowingBinHexSign, 1347 #[subdiagnostic] 1348 pub sub: Option<OverflowingBinHexSub<'a>>, 1349 #[subdiagnostic] 1350 pub sign_bit_sub: Option<OverflowingBinHexSignBitSub<'a>>, 1351 } 1352 1353 pub enum OverflowingBinHexSign { 1354 Positive, 1355 Negative, 1356 } 1357 1358 impl AddToDiagnostic for OverflowingBinHexSign { add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) where F: Fn( &mut rustc_errors::Diagnostic, rustc_errors::SubdiagnosticMessage, ) -> rustc_errors::SubdiagnosticMessage,1359 fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) 1360 where 1361 F: Fn( 1362 &mut rustc_errors::Diagnostic, 1363 rustc_errors::SubdiagnosticMessage, 1364 ) -> rustc_errors::SubdiagnosticMessage, 1365 { 1366 match self { 1367 OverflowingBinHexSign::Positive => { 1368 diag.note(fluent::lint_positive_note); 1369 } 1370 OverflowingBinHexSign::Negative => { 1371 diag.note(fluent::lint_negative_note); 1372 diag.note(fluent::lint_negative_becomes_note); 1373 } 1374 } 1375 } 1376 } 1377 1378 #[derive(Subdiagnostic)] 1379 pub enum OverflowingBinHexSub<'a> { 1380 #[suggestion( 1381 lint_suggestion, 1382 code = "{sans_suffix}{suggestion_ty}", 1383 applicability = "machine-applicable" 1384 )] 1385 Suggestion { 1386 #[primary_span] 1387 span: Span, 1388 suggestion_ty: &'a str, 1389 sans_suffix: &'a str, 1390 }, 1391 #[help(lint_help)] 1392 Help { suggestion_ty: &'a str }, 1393 } 1394 1395 #[derive(Subdiagnostic)] 1396 #[suggestion( 1397 lint_sign_bit_suggestion, 1398 code = "{lit_no_suffix}{uint_ty} as {int_ty}", 1399 applicability = "maybe-incorrect" 1400 )] 1401 pub struct OverflowingBinHexSignBitSub<'a> { 1402 #[primary_span] 1403 pub span: Span, 1404 pub lit_no_suffix: &'a str, 1405 pub negative_val: String, 1406 pub uint_ty: &'a str, 1407 pub int_ty: &'a str, 1408 } 1409 1410 #[derive(LintDiagnostic)] 1411 #[diag(lint_overflowing_int)] 1412 #[note] 1413 pub struct OverflowingInt<'a> { 1414 pub ty: &'a str, 1415 pub lit: String, 1416 pub min: i128, 1417 pub max: u128, 1418 #[subdiagnostic] 1419 pub help: Option<OverflowingIntHelp<'a>>, 1420 } 1421 1422 #[derive(Subdiagnostic)] 1423 #[help(lint_help)] 1424 pub struct OverflowingIntHelp<'a> { 1425 pub suggestion_ty: &'a str, 1426 } 1427 1428 #[derive(LintDiagnostic)] 1429 #[diag(lint_only_cast_u8_to_char)] 1430 pub struct OnlyCastu8ToChar { 1431 #[suggestion(code = "'\\u{{{literal:X}}}'", applicability = "machine-applicable")] 1432 pub span: Span, 1433 pub literal: u128, 1434 } 1435 1436 #[derive(LintDiagnostic)] 1437 #[diag(lint_overflowing_uint)] 1438 #[note] 1439 pub struct OverflowingUInt<'a> { 1440 pub ty: &'a str, 1441 pub lit: String, 1442 pub min: u128, 1443 pub max: u128, 1444 } 1445 1446 #[derive(LintDiagnostic)] 1447 #[diag(lint_overflowing_literal)] 1448 #[note] 1449 pub struct OverflowingLiteral<'a> { 1450 pub ty: &'a str, 1451 pub lit: String, 1452 } 1453 1454 #[derive(LintDiagnostic)] 1455 #[diag(lint_unused_comparisons)] 1456 pub struct UnusedComparisons; 1457 1458 #[derive(LintDiagnostic)] 1459 pub enum InvalidNanComparisons { 1460 #[diag(lint_invalid_nan_comparisons_eq_ne)] 1461 EqNe { 1462 #[subdiagnostic] 1463 suggestion: InvalidNanComparisonsSuggestion, 1464 }, 1465 #[diag(lint_invalid_nan_comparisons_lt_le_gt_ge)] 1466 LtLeGtGe, 1467 } 1468 1469 #[derive(Subdiagnostic)] 1470 pub enum InvalidNanComparisonsSuggestion { 1471 #[multipart_suggestion( 1472 lint_suggestion, 1473 style = "verbose", 1474 applicability = "machine-applicable" 1475 )] 1476 Spanful { 1477 #[suggestion_part(code = "!")] 1478 neg: Option<Span>, 1479 #[suggestion_part(code = ".is_nan()")] 1480 float: Span, 1481 #[suggestion_part(code = "")] 1482 nan_plus_binop: Span, 1483 }, 1484 #[help(lint_suggestion)] 1485 Spanless, 1486 } 1487 1488 pub struct ImproperCTypes<'a> { 1489 pub ty: Ty<'a>, 1490 pub desc: &'a str, 1491 pub label: Span, 1492 pub help: Option<DiagnosticMessage>, 1493 pub note: DiagnosticMessage, 1494 pub span_note: Option<Span>, 1495 } 1496 1497 // Used because of the complexity of Option<DiagnosticMessage>, DiagnosticMessage, and Option<Span> 1498 impl<'a> DecorateLint<'a, ()> for ImproperCTypes<'_> { decorate_lint<'b>( self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()>1499 fn decorate_lint<'b>( 1500 self, 1501 diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, 1502 ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { 1503 diag.set_arg("ty", self.ty); 1504 diag.set_arg("desc", self.desc); 1505 diag.span_label(self.label, fluent::lint_label); 1506 if let Some(help) = self.help { 1507 diag.help(help); 1508 } 1509 diag.note(self.note); 1510 if let Some(note) = self.span_note { 1511 diag.span_note(note, fluent::lint_note); 1512 } 1513 diag 1514 } 1515 msg(&self) -> rustc_errors::DiagnosticMessage1516 fn msg(&self) -> rustc_errors::DiagnosticMessage { 1517 fluent::lint_improper_ctypes 1518 } 1519 } 1520 1521 #[derive(LintDiagnostic)] 1522 #[diag(lint_variant_size_differences)] 1523 pub struct VariantSizeDifferencesDiag { 1524 pub largest: u64, 1525 } 1526 1527 #[derive(LintDiagnostic)] 1528 #[diag(lint_atomic_ordering_load)] 1529 #[help] 1530 pub struct AtomicOrderingLoad; 1531 1532 #[derive(LintDiagnostic)] 1533 #[diag(lint_atomic_ordering_store)] 1534 #[help] 1535 pub struct AtomicOrderingStore; 1536 1537 #[derive(LintDiagnostic)] 1538 #[diag(lint_atomic_ordering_fence)] 1539 #[help] 1540 pub struct AtomicOrderingFence; 1541 1542 #[derive(LintDiagnostic)] 1543 #[diag(lint_atomic_ordering_invalid)] 1544 #[help] 1545 pub struct InvalidAtomicOrderingDiag { 1546 pub method: Symbol, 1547 #[label] 1548 pub fail_order_arg_span: Span, 1549 } 1550 1551 // unused.rs 1552 #[derive(LintDiagnostic)] 1553 #[diag(lint_unused_op)] 1554 pub struct UnusedOp<'a> { 1555 pub op: &'a str, 1556 #[label] 1557 pub label: Span, 1558 #[subdiagnostic] 1559 pub suggestion: UnusedOpSuggestion, 1560 } 1561 1562 #[derive(Subdiagnostic)] 1563 pub enum UnusedOpSuggestion { 1564 #[suggestion( 1565 lint_suggestion, 1566 style = "verbose", 1567 code = "let _ = ", 1568 applicability = "maybe-incorrect" 1569 )] 1570 NormalExpr { 1571 #[primary_span] 1572 span: Span, 1573 }, 1574 #[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")] 1575 BlockTailExpr { 1576 #[suggestion_part(code = "let _ = ")] 1577 before_span: Span, 1578 #[suggestion_part(code = ";")] 1579 after_span: Span, 1580 }, 1581 } 1582 1583 #[derive(LintDiagnostic)] 1584 #[diag(lint_unused_result)] 1585 pub struct UnusedResult<'a> { 1586 pub ty: Ty<'a>, 1587 } 1588 1589 // FIXME(davidtwco): this isn't properly translatable because of the 1590 // pre/post strings 1591 #[derive(LintDiagnostic)] 1592 #[diag(lint_unused_closure)] 1593 #[note] 1594 pub struct UnusedClosure<'a> { 1595 pub count: usize, 1596 pub pre: &'a str, 1597 pub post: &'a str, 1598 } 1599 1600 // FIXME(davidtwco): this isn't properly translatable because of the 1601 // pre/post strings 1602 #[derive(LintDiagnostic)] 1603 #[diag(lint_unused_generator)] 1604 #[note] 1605 pub struct UnusedGenerator<'a> { 1606 pub count: usize, 1607 pub pre: &'a str, 1608 pub post: &'a str, 1609 } 1610 1611 // FIXME(davidtwco): this isn't properly translatable because of the pre/post 1612 // strings 1613 pub struct UnusedDef<'a, 'b> { 1614 pub pre: &'a str, 1615 pub post: &'a str, 1616 pub cx: &'a LateContext<'b>, 1617 pub def_id: DefId, 1618 pub note: Option<Symbol>, 1619 pub suggestion: Option<UnusedDefSuggestion>, 1620 } 1621 1622 #[derive(Subdiagnostic)] 1623 1624 pub enum UnusedDefSuggestion { 1625 #[suggestion( 1626 lint_suggestion, 1627 style = "verbose", 1628 code = "let _ = ", 1629 applicability = "maybe-incorrect" 1630 )] 1631 NormalExpr { 1632 #[primary_span] 1633 span: Span, 1634 }, 1635 #[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")] 1636 BlockTailExpr { 1637 #[suggestion_part(code = "let _ = ")] 1638 before_span: Span, 1639 #[suggestion_part(code = ";")] 1640 after_span: Span, 1641 }, 1642 } 1643 1644 // Needed because of def_path_str 1645 impl<'a> DecorateLint<'a, ()> for UnusedDef<'_, '_> { decorate_lint<'b>( self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()>1646 fn decorate_lint<'b>( 1647 self, 1648 diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, 1649 ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { 1650 diag.set_arg("pre", self.pre); 1651 diag.set_arg("post", self.post); 1652 diag.set_arg("def", self.cx.tcx.def_path_str(self.def_id)); 1653 // check for #[must_use = "..."] 1654 if let Some(note) = self.note { 1655 diag.note(note.to_string()); 1656 } 1657 if let Some(sugg) = self.suggestion { 1658 diag.subdiagnostic(sugg); 1659 } 1660 diag 1661 } 1662 msg(&self) -> rustc_errors::DiagnosticMessage1663 fn msg(&self) -> rustc_errors::DiagnosticMessage { 1664 fluent::lint_unused_def 1665 } 1666 } 1667 1668 #[derive(LintDiagnostic)] 1669 #[diag(lint_path_statement_drop)] 1670 pub struct PathStatementDrop { 1671 #[subdiagnostic] 1672 pub sub: PathStatementDropSub, 1673 } 1674 1675 #[derive(Subdiagnostic)] 1676 pub enum PathStatementDropSub { 1677 #[suggestion(lint_suggestion, code = "drop({snippet});", applicability = "machine-applicable")] 1678 Suggestion { 1679 #[primary_span] 1680 span: Span, 1681 snippet: String, 1682 }, 1683 #[help(lint_help)] 1684 Help { 1685 #[primary_span] 1686 span: Span, 1687 }, 1688 } 1689 1690 #[derive(LintDiagnostic)] 1691 #[diag(lint_path_statement_no_effect)] 1692 pub struct PathStatementNoEffect; 1693 1694 #[derive(LintDiagnostic)] 1695 #[diag(lint_unused_delim)] 1696 pub struct UnusedDelim<'a> { 1697 pub delim: &'static str, 1698 pub item: &'a str, 1699 #[subdiagnostic] 1700 pub suggestion: Option<UnusedDelimSuggestion>, 1701 } 1702 1703 #[derive(Subdiagnostic)] 1704 #[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")] 1705 pub struct UnusedDelimSuggestion { 1706 #[suggestion_part(code = "{start_replace}")] 1707 pub start_span: Span, 1708 pub start_replace: &'static str, 1709 #[suggestion_part(code = "{end_replace}")] 1710 pub end_span: Span, 1711 pub end_replace: &'static str, 1712 } 1713 1714 #[derive(LintDiagnostic)] 1715 #[diag(lint_unused_import_braces)] 1716 pub struct UnusedImportBracesDiag { 1717 pub node: Symbol, 1718 } 1719 1720 #[derive(LintDiagnostic)] 1721 #[diag(lint_unused_allocation)] 1722 pub struct UnusedAllocationDiag; 1723 1724 #[derive(LintDiagnostic)] 1725 #[diag(lint_unused_allocation_mut)] 1726 pub struct UnusedAllocationMutDiag; 1727