Skip to content

Commit

Permalink
Preapare for diag structs for buffered lints
Browse files Browse the repository at this point in the history
  • Loading branch information
Xiretza committed Apr 16, 2024
1 parent afc694c commit b41bc78
Showing 3 changed files with 91 additions and 19 deletions.
19 changes: 7 additions & 12 deletions compiler/rustc_lint/src/context.rs
Original file line number Diff line number Diff line change
@@ -524,29 +524,24 @@ pub struct EarlyContext<'a> {
pub buffered: LintBuffer,
}

pub trait LintContext {
fn sess(&self) -> &Session;

impl<'c> EarlyContext<'c> {
/// Emit a lint at the appropriate level, with an optional associated span and an existing
/// diagnostic.
///
/// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
#[rustc_lint_diagnostics]
fn span_lint_with_diagnostics(
pub fn span_lint_with_diagnostics(
&self,
lint: &'static Lint,
span: Option<impl Into<MultiSpan>>,
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
diagnostic: BuiltinLintDiag,
) {
// We first generate a blank diagnostic.
self.opt_span_lint(lint, span, diagnostics::builtin_message(&diagnostic), |db| {
// Now, set up surrounding context.
diagnostics::builtin(self.sess(), diagnostic, db);
// Rewrap `db`, and pass control to the user.
decorate(db)
});
diagnostics::emit_buffered_lint(self, lint, span, diagnostic)
}
}

pub trait LintContext {
fn sess(&self) -> &Session;

// FIXME: These methods should not take an Into<MultiSpan> -- instead, callers should need to
// set the span in their `decorate` function (preferably using set_span).
87 changes: 82 additions & 5 deletions compiler/rustc_lint/src/context/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -2,23 +2,25 @@
#![allow(rustc::untranslatable_diagnostic)]

use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
use rustc_errors::{add_elided_lifetime_in_path_suggestion, pluralize, Diag, DiagMessage};
use rustc_errors::{
add_elided_lifetime_in_path_suggestion, pluralize, Diag, DiagMessage, MultiSpan,
};
use rustc_errors::{Applicability, SuggestionStyle};
use rustc_middle::middle::stability;
use rustc_session::lint::BuiltinLintDiag;
use rustc_session::lint::{BuiltinLintDiag, Lint};
use rustc_session::Session;
use rustc_span::BytePos;

use std::fmt::Write;

use crate::fluent_generated as fluent;
use crate::{fluent_generated as fluent, LintContext};

mod check_cfg;

#[cfg(test)]
mod tests;

pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Diag<'_, ()>) {
fn buffered_decorate(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Diag<'_, ()>) {
match diagnostic {
BuiltinLintDiag::UnicodeTextFlow(span, content) => {
let spans: Vec<_> = content
@@ -380,7 +382,7 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di
}
}

pub(super) fn builtin_message(diagnostic: &BuiltinLintDiag) -> DiagMessage {
fn buffered_message(diagnostic: &BuiltinLintDiag) -> DiagMessage {
match diagnostic {
BuiltinLintDiag::AbsPathWithModule(_) => fluent::lint_abs_path_with_module,
BuiltinLintDiag::ProcMacroDeriveResolutionFallback { ns, ident, .. } => {
@@ -537,6 +539,81 @@ pub(super) fn builtin_message(diagnostic: &BuiltinLintDiag) -> DiagMessage {
}
}

pub(super) fn emit_buffered_lint<C: LintContext + ?Sized>(
ctx: &C,
lint: &'static Lint,
span: Option<impl Into<MultiSpan>>,
diagnostic: BuiltinLintDiag,
) {
match diagnostic {
BuiltinLintDiag::AbsPathWithModule(_)
| BuiltinLintDiag::ProcMacroDeriveResolutionFallback { .. }
| BuiltinLintDiag::MacroExpandedMacroExportsAccessedByAbsolutePaths(_)
| BuiltinLintDiag::ElidedLifetimesInPaths(_, _, _, _)
| BuiltinLintDiag::UnknownCrateTypes(_, _, _)
| BuiltinLintDiag::UnusedImports { .. }
| BuiltinLintDiag::RedundantImport(_, _)
| BuiltinLintDiag::DeprecatedMacro { .. }
| BuiltinLintDiag::MissingAbi(_, _)
| BuiltinLintDiag::UnusedDocComment(_)
| BuiltinLintDiag::UnusedBuiltinAttribute { .. }
| BuiltinLintDiag::PatternsInFnsWithoutBody { .. }
| BuiltinLintDiag::LegacyDeriveHelpers(_)
| BuiltinLintDiag::ProcMacroBackCompat(_)
| BuiltinLintDiag::OrPatternsBackCompat(_, _)
| BuiltinLintDiag::ReservedPrefix(_, _)
| BuiltinLintDiag::TrailingMacro(_, _)
| BuiltinLintDiag::BreakWithLabelAndLoop(_)
| BuiltinLintDiag::UnicodeTextFlow(_, _)
| BuiltinLintDiag::UnexpectedCfgName(_, _)
| BuiltinLintDiag::UnexpectedCfgValue(_, _)
| BuiltinLintDiag::DeprecatedWhereclauseLocation(_)
| BuiltinLintDiag::SingleUseLifetime { .. }
| BuiltinLintDiag::NamedArgumentUsedPositionally { .. }
| BuiltinLintDiag::ByteSliceInPackedStructWithDerive { .. }
| BuiltinLintDiag::UnusedExternCrate { .. }
| BuiltinLintDiag::ExternCrateNotIdiomatic { .. }
| BuiltinLintDiag::AmbiguousGlobImports { .. }
| BuiltinLintDiag::AmbiguousGlobReexports { .. }
| BuiltinLintDiag::HiddenGlobReexports { .. }
| BuiltinLintDiag::UnusedQualifications { .. }
| BuiltinLintDiag::AssociatedConstElidedLifetime { .. }
| BuiltinLintDiag::RedundantImportVisibility { .. }
| BuiltinLintDiag::InvalidCrateTypeValue
| BuiltinLintDiag::MacroUseDeprecated
| BuiltinLintDiag::UnusedMacroUse
| BuiltinLintDiag::PrivateExternCrateReexport(_)
| BuiltinLintDiag::UnusedLabel
| BuiltinLintDiag::MacroIsPrivate(_)
| BuiltinLintDiag::UnusedMacroDefinition(_)
| BuiltinLintDiag::MacroRuleNeverUsed(_, _)
| BuiltinLintDiag::UnstableFeature(_)
| BuiltinLintDiag::AvoidUsingIntelSyntax
| BuiltinLintDiag::AvoidUsingAttSyntax
| BuiltinLintDiag::IncompleteInclude
| BuiltinLintDiag::UnnameableTestItems
| BuiltinLintDiag::DuplicateMacroAttribute
| BuiltinLintDiag::CfgAttrNoAttributes
| BuiltinLintDiag::CrateTypeInCfgAttr
| BuiltinLintDiag::CrateNameInCfgAttr
| BuiltinLintDiag::MissingFragmentSpecifier
| BuiltinLintDiag::MetaVariableStillRepeating(_)
| BuiltinLintDiag::MetaVariableWrongOperator
| BuiltinLintDiag::DuplicateMatcherBinding
| BuiltinLintDiag::UnknownMacroVariable(_)
| BuiltinLintDiag::UnusedExternCrate2 { .. }
| BuiltinLintDiag::WasmCAbi
| BuiltinLintDiag::IllFormedAttributeInput { .. }
| BuiltinLintDiag::InnerAttributeUnstable { .. }
| BuiltinLintDiag::UnknownDiagnosticAttribute => {
ctx.opt_span_lint(lint, span, buffered_message(&diagnostic), |db| {
// Now, set up surrounding context.
buffered_decorate(ctx.sess(), diagnostic, db);
})
}
}
}

/// Convert the given number into the corresponding ordinal
pub(crate) fn ordinalize(v: usize) -> String {
let suffix = match ((11..=13).contains(&(v % 100)), v % 10) {
4 changes: 2 additions & 2 deletions compiler/rustc_lint/src/early.rs
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@
//! upon. As the ast is traversed, this keeps track of the current lint level
//! for all lint attributes.
use crate::context::{EarlyContext, LintContext, LintStore};
use crate::context::{EarlyContext, LintStore};
use crate::passes::{EarlyLintPass, EarlyLintPassObject};
use rustc_ast::ptr::P;
use rustc_ast::visit::{self as ast_visit, walk_list, Visitor};
@@ -45,7 +45,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
fn inlined_check_id(&mut self, id: ast::NodeId) {
for early_lint in self.context.buffered.take(id) {
let BufferedEarlyLint { span, node_id: _, lint_id, diagnostic } = early_lint;
self.context.span_lint_with_diagnostics(lint_id.lint, Some(span), |_| {}, diagnostic);
self.context.span_lint_with_diagnostics(lint_id.lint, Some(span), diagnostic);
}
}

0 comments on commit b41bc78

Please sign in to comment.