Skip to content

Commit 540eaf9

Browse files
committed
errors: introduce DecorateLint
Add a new trait to be generated by diagnostic derives which uses a `LintDiagnosticBuilder`. Signed-off-by: David Wood <[email protected]>
1 parent 2874f09 commit 540eaf9

File tree

6 files changed

+58
-6
lines changed

6 files changed

+58
-6
lines changed

compiler/rustc_errors/src/diagnostic.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::snippet::Style;
22
use crate::{
3-
CodeSuggestion, DiagnosticMessage, Level, MultiSpan, SubdiagnosticMessage, Substitution,
4-
SubstitutionPart, SuggestionStyle,
3+
CodeSuggestion, DiagnosticMessage, EmissionGuarantee, Level, LintDiagnosticBuilder, MultiSpan,
4+
SubdiagnosticMessage, Substitution, SubstitutionPart, SuggestionStyle,
55
};
66
use rustc_data_structures::stable_map::FxHashMap;
77
use rustc_error_messages::FluentValue;
@@ -168,6 +168,14 @@ pub trait AddSubdiagnostic {
168168
fn add_to_diagnostic(self, diag: &mut Diagnostic);
169169
}
170170

171+
/// Trait implemented by lint types. This should not be implemented manually. Instead, use
172+
/// `#[derive(LintDiagnostic)]` -- see [rustc_macros::LintDiagnostic].
173+
#[rustc_diagnostic_item = "DecorateLint"]
174+
pub trait DecorateLint<'a, G: EmissionGuarantee> {
175+
/// Decorate and emit a lint.
176+
fn decorate_lint(self, diag: LintDiagnosticBuilder<'a, G>);
177+
}
178+
171179
#[must_use]
172180
#[derive(Clone, Debug, Encodable, Decodable)]
173181
pub struct Diagnostic {

compiler/rustc_errors/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ impl fmt::Display for ExplicitBug {
370370
impl error::Error for ExplicitBug {}
371371

372372
pub use diagnostic::{
373-
AddSubdiagnostic, Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId,
373+
AddSubdiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId,
374374
DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
375375
};
376376
pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, LintDiagnosticBuilder};

compiler/rustc_lint/src/context.rs

+21-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
2222
use rustc_data_structures::fx::FxHashMap;
2323
use rustc_data_structures::sync;
2424
use rustc_errors::{add_elided_lifetime_in_path_suggestion, struct_span_err};
25-
use rustc_errors::{Applicability, LintDiagnosticBuilder, MultiSpan, SuggestionStyle};
25+
use rustc_errors::{
26+
Applicability, DecorateLint, LintDiagnosticBuilder, MultiSpan, SuggestionStyle,
27+
};
2628
use rustc_hir as hir;
2729
use rustc_hir::def::Res;
2830
use rustc_hir::def_id::{CrateNum, DefId};
@@ -870,6 +872,17 @@ pub trait LintContext: Sized {
870872
decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>),
871873
);
872874

875+
/// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`,
876+
/// typically generated by `#[derive(LintDiagnostic)]`).
877+
fn emit_spanned_lint<S: Into<MultiSpan>>(
878+
&self,
879+
lint: &'static Lint,
880+
span: S,
881+
decorator: impl for<'a> DecorateLint<'a, ()>,
882+
) {
883+
self.lookup(lint, Some(span), |diag| decorator.decorate_lint(diag));
884+
}
885+
873886
fn struct_span_lint<S: Into<MultiSpan>>(
874887
&self,
875888
lint: &'static Lint,
@@ -878,6 +891,13 @@ pub trait LintContext: Sized {
878891
) {
879892
self.lookup(lint, Some(span), decorate);
880893
}
894+
895+
/// Emit a lint from a lint struct (some type that implements `DecorateLint`, typically
896+
/// generated by `#[derive(LintDiagnostic)]`).
897+
fn emit_lint(&self, lint: &'static Lint, decorator: impl for<'a> DecorateLint<'a, ()>) {
898+
self.lookup(lint, None as Option<Span>, |diag| decorator.decorate_lint(diag));
899+
}
900+
881901
/// Emit a lint at the appropriate level, with no associated span.
882902
fn lint(
883903
&self,

compiler/rustc_lint/src/internal.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ impl LateLintPass<'_> for Diagnostics {
414414
let Impl { of_trait: Some(of_trait), .. } = impl_ &&
415415
let Some(def_id) = of_trait.trait_def_id() &&
416416
let Some(name) = cx.tcx.get_diagnostic_name(def_id) &&
417-
matches!(name, sym::SessionDiagnostic | sym::AddSubdiagnostic)
417+
matches!(name, sym::SessionDiagnostic | sym::AddSubdiagnostic | sym::DecorateLint)
418418
{
419419
found_impl = true;
420420
break;

compiler/rustc_middle/src/ty/context.rs

+24-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
3434
use rustc_data_structures::steal::Steal;
3535
use rustc_data_structures::sync::{self, Lock, Lrc, WorkerLocal};
3636
use rustc_data_structures::vec_map::VecMap;
37-
use rustc_errors::{ErrorGuaranteed, LintDiagnosticBuilder, MultiSpan};
37+
use rustc_errors::{DecorateLint, ErrorGuaranteed, LintDiagnosticBuilder, MultiSpan};
3838
use rustc_hir as hir;
3939
use rustc_hir::def::{DefKind, Res};
4040
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
@@ -2787,6 +2787,18 @@ impl<'tcx> TyCtxt<'tcx> {
27872787
}
27882788
}
27892789

2790+
/// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`,
2791+
/// typically generated by `#[derive(LintDiagnostic)]`).
2792+
pub fn emit_spanned_lint(
2793+
self,
2794+
lint: &'static Lint,
2795+
hir_id: HirId,
2796+
span: impl Into<MultiSpan>,
2797+
decorator: impl for<'a> DecorateLint<'a, ()>,
2798+
) {
2799+
self.struct_span_lint_hir(lint, hir_id, span, |diag| decorator.decorate_lint(diag))
2800+
}
2801+
27902802
pub fn struct_span_lint_hir(
27912803
self,
27922804
lint: &'static Lint,
@@ -2798,6 +2810,17 @@ impl<'tcx> TyCtxt<'tcx> {
27982810
struct_lint_level(self.sess, lint, level, src, Some(span.into()), decorate);
27992811
}
28002812

2813+
/// Emit a lint from a lint struct (some type that implements `DecorateLint`, typically
2814+
/// generated by `#[derive(LintDiagnostic)]`).
2815+
pub fn emit_lint(
2816+
self,
2817+
lint: &'static Lint,
2818+
id: HirId,
2819+
decorator: impl for<'a> DecorateLint<'a, ()>,
2820+
) {
2821+
self.struct_lint_node(lint, id, |diag| decorator.decorate_lint(diag))
2822+
}
2823+
28012824
pub fn struct_lint_node(
28022825
self,
28032826
lint: &'static Lint,

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ symbols! {
173173
DebugTuple,
174174
Decodable,
175175
Decoder,
176+
DecorateLint,
176177
Default,
177178
Deref,
178179
DiagnosticMessage,

0 commit comments

Comments
 (0)