diff options
| author | Urgau <urgau@numericable.fr> | 2024-12-14 17:33:57 +0100 |
|---|---|---|
| committer | Urgau <urgau@numericable.fr> | 2024-12-15 00:25:05 +0100 |
| commit | ab780fa48aa49463301620ec825da3376c0171a3 (patch) | |
| tree | c8d22b61536ab589154478ac2ebd625b29a85968 | |
| parent | 0aeaa5eb22180fdf12a8489e63c4daa18da6f236 (diff) | |
| download | rust-ab780fa48aa49463301620ec825da3376c0171a3.tar.gz rust-ab780fa48aa49463301620ec825da3376c0171a3.zip | |
Access `TyCtxt` from early diagnostic decoration
| -rw-r--r-- | compiler/rustc_interface/src/passes.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/context.rs | 36 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/early.rs | 65 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/early/diagnostics.rs (renamed from compiler/rustc_lint/src/context/diagnostics.rs) | 8 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/early/diagnostics/check_cfg.rs (renamed from compiler/rustc_lint/src/context/diagnostics/check_cfg.rs) | 0 |
5 files changed, 62 insertions, 49 deletions
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 430bc7db077..f8351a81bec 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -76,6 +76,7 @@ fn pre_expansion_lint<'a>( || { rustc_lint::check_ast_node( sess, + None, features, true, lint_store, @@ -310,6 +311,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) { let lint_store = unerased_lint_store(tcx.sess); rustc_lint::check_ast_node( sess, + Some(tcx), tcx.features(), false, lint_store, diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 44c7888a530..d8d901698d6 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -20,7 +20,7 @@ use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, Printer, with_no_trimmed_paths}; use rustc_middle::ty::{self, GenericArg, RegisteredTools, Ty, TyCtxt, TypingEnv, TypingMode}; use rustc_session::lint::{ - BuiltinLintDiag, FutureIncompatibleInfo, Level, Lint, LintBuffer, LintExpectationId, LintId, + FutureIncompatibleInfo, Level, Lint, LintBuffer, LintExpectationId, LintId, }; use rustc_session::{LintStoreMarker, Session}; use rustc_span::Span; @@ -33,8 +33,6 @@ use self::TargetLint::*; use crate::levels::LintLevelsBuilder; use crate::passes::{EarlyLintPassObject, LateLintPassObject}; -mod diagnostics; - type EarlyLintPassFactory = dyn Fn() -> EarlyLintPassObject + sync::DynSend + sync::DynSync; type LateLintPassFactory = dyn for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx> + sync::DynSend + sync::DynSync; @@ -511,38 +509,6 @@ pub struct EarlyContext<'a> { pub buffered: LintBuffer, } -impl EarlyContext<'_> { - /// Emit a lint at the appropriate level, with an associated span and an existing - /// diagnostic. - /// - /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature - #[rustc_lint_diagnostics] - pub fn span_lint_with_diagnostics( - &self, - lint: &'static Lint, - span: MultiSpan, - diagnostic: BuiltinLintDiag, - ) { - self.opt_span_lint_with_diagnostics(lint, Some(span), diagnostic); - } - - /// 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] - pub fn opt_span_lint_with_diagnostics( - &self, - lint: &'static Lint, - span: Option<MultiSpan>, - diagnostic: BuiltinLintDiag, - ) { - self.opt_span_lint(lint, span, |diag| { - diagnostics::decorate_lint(self.sess(), diagnostic, diag); - }); - } -} - pub trait LintContext { fn sess(&self) -> &Session; diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index a68a2a7f983..6d1081700d7 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -8,36 +8,73 @@ use rustc_ast::ptr::P; use rustc_ast::visit::{self as ast_visit, Visitor, walk_list}; use rustc_ast::{self as ast, HasAttrs}; use rustc_data_structures::stack::ensure_sufficient_stack; +use rustc_errors::MultiSpan; use rustc_feature::Features; -use rustc_middle::ty::RegisteredTools; +use rustc_middle::ty::{RegisteredTools, TyCtxt}; use rustc_session::Session; -use rustc_session::lint::{BufferedEarlyLint, LintBuffer, LintPass}; +use rustc_session::lint::{BufferedEarlyLint, BuiltinLintDiag, LintBuffer, LintPass}; use rustc_span::Span; use rustc_span::symbol::Ident; use tracing::debug; -use crate::context::{EarlyContext, LintStore}; +use crate::Lint; +use crate::context::{EarlyContext, LintContext, LintStore}; use crate::passes::{EarlyLintPass, EarlyLintPassObject}; +mod diagnostics; + macro_rules! lint_callback { ($cx:expr, $f:ident, $($args:expr),*) => ({ $cx.pass.$f(&$cx.context, $($args),*); }) } /// Implements the AST traversal for early lint passes. `T` provides the /// `check_*` methods. -pub struct EarlyContextAndPass<'a, T: EarlyLintPass> { +pub struct EarlyContextAndPass<'a, 'b, T: EarlyLintPass> { context: EarlyContext<'a>, + tcx: Option<TyCtxt<'b>>, pass: T, } -impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> { +impl<T: EarlyLintPass> EarlyContextAndPass<'_, '_, T> { + /// Emit a lint at the appropriate level, with an associated span and an existing + /// diagnostic. + /// + /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature + #[rustc_lint_diagnostics] + pub fn span_lint_with_diagnostics( + &self, + lint: &'static Lint, + span: MultiSpan, + diagnostic: BuiltinLintDiag, + ) { + self.opt_span_lint_with_diagnostics(lint, Some(span), diagnostic); + } + + /// 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] + pub fn opt_span_lint_with_diagnostics( + &self, + lint: &'static Lint, + span: Option<MultiSpan>, + diagnostic: BuiltinLintDiag, + ) { + self.context.opt_span_lint(lint, span, |diag| { + diagnostics::decorate_lint(self.context.sess(), self.tcx, diagnostic, diag); + }); + } +} + +impl<'a, 'b, T: EarlyLintPass> EarlyContextAndPass<'a, 'b, T> { // This always-inlined function is for the hot call site. #[inline(always)] #[allow(rustc::diagnostic_outside_of_impl)] 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.opt_span_lint_with_diagnostics(lint_id.lint, span, diagnostic); + self.opt_span_lint_with_diagnostics(lint_id.lint, span, diagnostic); } } @@ -67,7 +104,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> { } } -impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> { +impl<'a, 'b, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, 'b, T> { fn visit_coroutine_kind(&mut self, coroutine_kind: &'a ast::CoroutineKind) -> Self::Result { self.check_id(coroutine_kind.closure_id()); } @@ -313,7 +350,7 @@ pub trait EarlyCheckNode<'a>: Copy { fn attrs<'b>(self) -> &'b [ast::Attribute] where 'a: 'b; - fn check<'b, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'b, T>) + fn check<'b, 'c, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'b, 'c, T>) where 'a: 'b; } @@ -328,7 +365,7 @@ impl<'a> EarlyCheckNode<'a> for (&'a ast::Crate, &'a [ast::Attribute]) { { self.1 } - fn check<'b, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'b, T>) + fn check<'b, 'c, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'b, 'c, T>) where 'a: 'b, { @@ -348,7 +385,7 @@ impl<'a> EarlyCheckNode<'a> for (ast::NodeId, &'a [ast::Attribute], &'a [P<ast:: { self.1 } - fn check<'b, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'b, T>) + fn check<'b, 'c, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'b, 'c, T>) where 'a: 'b, { @@ -359,6 +396,7 @@ impl<'a> EarlyCheckNode<'a> for (ast::NodeId, &'a [ast::Attribute], &'a [P<ast:: pub fn check_ast_node<'a>( sess: &Session, + tcx: Option<TyCtxt<'_>>, features: &Features, pre_expansion: bool, lint_store: &LintStore, @@ -382,22 +420,23 @@ pub fn check_ast_node<'a>( let passes = if pre_expansion { &lint_store.pre_expansion_passes } else { &lint_store.early_passes }; if passes.is_empty() { - check_ast_node_inner(sess, check_node, context, builtin_lints); + check_ast_node_inner(sess, tcx, check_node, context, builtin_lints); } else { let mut passes: Vec<_> = passes.iter().map(|mk_pass| (mk_pass)()).collect(); passes.push(Box::new(builtin_lints)); let pass = RuntimeCombinedEarlyLintPass { passes: &mut passes[..] }; - check_ast_node_inner(sess, check_node, context, pass); + check_ast_node_inner(sess, tcx, check_node, context, pass); } } fn check_ast_node_inner<'a, T: EarlyLintPass>( sess: &Session, + tcx: Option<TyCtxt<'_>>, check_node: impl EarlyCheckNode<'a>, context: EarlyContext<'_>, pass: T, ) { - let mut cx = EarlyContextAndPass { context, pass }; + let mut cx = EarlyContextAndPass { context, tcx, pass }; cx.with_lint_attrs(check_node.id(), check_node.attrs(), |cx| check_node.check(cx)); diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index a3731e31c2b..7f136672a47 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -8,6 +8,7 @@ use rustc_errors::{ Applicability, Diag, DiagArgValue, LintDiagnostic, elided_lifetime_in_path_suggestion, }; use rustc_middle::middle::stability; +use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_session::lint::{BuiltinLintDiag, ElidedLifetimeResolution}; use rustc_span::BytePos; @@ -18,7 +19,12 @@ use crate::lints::{self, ElidedNamedLifetime}; mod check_cfg; -pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Diag<'_, ()>) { +pub(super) fn decorate_lint( + sess: &Session, + _tcx: Option<TyCtxt<'_>>, + diagnostic: BuiltinLintDiag, + diag: &mut Diag<'_, ()>, +) { match diagnostic { BuiltinLintDiag::UnicodeTextFlow(comment_span, content) => { let spans: Vec<_> = content diff --git a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs b/compiler/rustc_lint/src/early/diagnostics/check_cfg.rs index 63a722f6067..63a722f6067 100644 --- a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs +++ b/compiler/rustc_lint/src/early/diagnostics/check_cfg.rs |
