Skip to content

Commit 264c198

Browse files
committed
Add lint for String in diagnostic implementation
1 parent 26c9868 commit 264c198

File tree

5 files changed

+42
-2
lines changed

5 files changed

+42
-2
lines changed

compiler/rustc_lint/locales/en-US.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ lint_non_existant_doc_keyword = found non-existing keyword `{$keyword}` used in
9090
lint_diag_out_of_impl =
9191
diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
9292
93+
lint_string_in_diag = use of String in diagnostic
94+
.note = this could indicate incorrectly eagerly converting to a string
95+
9396
lint_untranslatable_diag = diagnostics should be created using translatable messages
9497
9598
lint_bad_opt_access = {$msg}

compiler/rustc_lint/src/internal.rs

+32-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
44
use crate::lints::{
55
BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand, NonExistantDocKeyword,
6-
QueryInstability, TyQualified, TykindDiag, TykindKind, UntranslatableDiag,
6+
QueryInstability, StringInDiagnostic, TyQualified, TykindDiag, TykindKind, UntranslatableDiag,
77
};
88
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
99
use rustc_ast as ast;
@@ -338,7 +338,14 @@ declare_tool_lint! {
338338
report_in_external_macro: true
339339
}
340340

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 ]);
342349

343350
impl LateLintPass<'_> for Diagnostics {
344351
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
@@ -395,6 +402,29 @@ impl LateLintPass<'_> for Diagnostics {
395402
}
396403
}
397404

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+
398428
declare_tool_lint! {
399429
pub rustc::BAD_OPT_ACCESS,
400430
Deny,

compiler/rustc_lint/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,7 @@ fn register_internals(store: &mut LintStore) {
514514
store.register_lints(&TyTyKind::get_lints());
515515
store.register_late_pass(|_| Box::new(TyTyKind));
516516
store.register_lints(&Diagnostics::get_lints());
517+
store.register_early_pass(|| Box::new(Diagnostics));
517518
store.register_late_pass(|_| Box::new(Diagnostics));
518519
store.register_lints(&BadOptAccess::get_lints());
519520
store.register_late_pass(|_| Box::new(BadOptAccess));

compiler/rustc_lint/src/lints.rs

+5
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,11 @@ pub struct NonExistantDocKeyword {
800800
#[diag(lint_diag_out_of_impl)]
801801
pub struct DiagOutOfImpl;
802802

803+
#[derive(LintDiagnostic)]
804+
#[diag(lint_string_in_diag)]
805+
#[note]
806+
pub struct StringInDiagnostic;
807+
803808
#[derive(LintDiagnostic)]
804809
#[diag(lint_untranslatable_diag)]
805810
pub struct UntranslatableDiag;

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,7 @@ symbols! {
608608
derive_default_enum,
609609
destruct,
610610
destructuring_assignment,
611+
diag,
611612
diagnostic,
612613
direct,
613614
discriminant_kind,

0 commit comments

Comments
 (0)