|
3 | 3 |
|
4 | 4 | use crate::lints::{
|
5 | 5 | BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand, NonExistantDocKeyword,
|
6 |
| - QueryInstability, TyQualified, TykindDiag, TykindKind, UntranslatableDiag, |
| 6 | + QueryInstability, StringInDiagnostic, TyQualified, TykindDiag, TykindKind, UntranslatableDiag, |
7 | 7 | };
|
8 | 8 | use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
9 | 9 | use rustc_ast as ast;
|
@@ -338,7 +338,14 @@ declare_tool_lint! {
|
338 | 338 | report_in_external_macro: true
|
339 | 339 | }
|
340 | 340 |
|
341 |
| -declare_lint_pass!(Diagnostics => [ UNTRANSLATABLE_DIAGNOSTIC, DIAGNOSTIC_OUTSIDE_OF_IMPL ]); |
| 341 | +declare_tool_lint! { |
| 342 | + pub rustc::STRING_IN_DIAGNOSTIC, |
| 343 | + Warn, |
| 344 | + "prevent the use of `String` in diagnostics, which could indicate incorrect eager conversion", |
| 345 | + report_in_external_macro: true |
| 346 | +} |
| 347 | + |
| 348 | +declare_lint_pass!(Diagnostics => [ UNTRANSLATABLE_DIAGNOSTIC, DIAGNOSTIC_OUTSIDE_OF_IMPL, STRING_IN_DIAGNOSTIC ]); |
342 | 349 |
|
343 | 350 | impl LateLintPass<'_> for Diagnostics {
|
344 | 351 | fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
@@ -395,6 +402,29 @@ impl LateLintPass<'_> for Diagnostics {
|
395 | 402 | }
|
396 | 403 | }
|
397 | 404 |
|
| 405 | +impl EarlyLintPass for Diagnostics { |
| 406 | + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) { |
| 407 | + if cx.sess().find_by_name(&item.attrs, sym::diag).is_none() { |
| 408 | + return; |
| 409 | + } |
| 410 | + |
| 411 | + let variants = match &item.kind { |
| 412 | + ast::ItemKind::Struct(variant, _) => vec![variant], |
| 413 | + ast::ItemKind::Enum(enum_def, _) => enum_def.variants.iter().map(|v| &v.data).collect(), |
| 414 | + _ => vec![], |
| 415 | + }; |
| 416 | + |
| 417 | + for field in variants.iter().flat_map(|d| d.fields()) { |
| 418 | + if let ast::TyKind::Path(_, path) = &field.ty.kind |
| 419 | + && let [path] = path.segments.as_ref() |
| 420 | + && path.ident.name == sym::String |
| 421 | + { |
| 422 | + cx.emit_spanned_lint(STRING_IN_DIAGNOSTIC, path.span(), StringInDiagnostic); |
| 423 | + } |
| 424 | + } |
| 425 | + } |
| 426 | +} |
| 427 | + |
398 | 428 | declare_tool_lint! {
|
399 | 429 | pub rustc::BAD_OPT_ACCESS,
|
400 | 430 | Deny,
|
|
0 commit comments