Skip to content

Commit ab780fa

Browse files
committed
Access TyCtxt from early diagnostic decoration
1 parent 0aeaa5e commit ab780fa

File tree

5 files changed

+62
-49
lines changed

5 files changed

+62
-49
lines changed

Diff for: compiler/rustc_interface/src/passes.rs

+2
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ fn pre_expansion_lint<'a>(
7676
|| {
7777
rustc_lint::check_ast_node(
7878
sess,
79+
None,
7980
features,
8081
true,
8182
lint_store,
@@ -310,6 +311,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
310311
let lint_store = unerased_lint_store(tcx.sess);
311312
rustc_lint::check_ast_node(
312313
sess,
314+
Some(tcx),
313315
tcx.features(),
314316
false,
315317
lint_store,

Diff for: compiler/rustc_lint/src/context.rs

+1-35
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
2020
use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, Printer, with_no_trimmed_paths};
2121
use rustc_middle::ty::{self, GenericArg, RegisteredTools, Ty, TyCtxt, TypingEnv, TypingMode};
2222
use rustc_session::lint::{
23-
BuiltinLintDiag, FutureIncompatibleInfo, Level, Lint, LintBuffer, LintExpectationId, LintId,
23+
FutureIncompatibleInfo, Level, Lint, LintBuffer, LintExpectationId, LintId,
2424
};
2525
use rustc_session::{LintStoreMarker, Session};
2626
use rustc_span::Span;
@@ -33,8 +33,6 @@ use self::TargetLint::*;
3333
use crate::levels::LintLevelsBuilder;
3434
use crate::passes::{EarlyLintPassObject, LateLintPassObject};
3535

36-
mod diagnostics;
37-
3836
type EarlyLintPassFactory = dyn Fn() -> EarlyLintPassObject + sync::DynSend + sync::DynSync;
3937
type LateLintPassFactory =
4038
dyn for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx> + sync::DynSend + sync::DynSync;
@@ -511,38 +509,6 @@ pub struct EarlyContext<'a> {
511509
pub buffered: LintBuffer,
512510
}
513511

514-
impl EarlyContext<'_> {
515-
/// Emit a lint at the appropriate level, with an associated span and an existing
516-
/// diagnostic.
517-
///
518-
/// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
519-
#[rustc_lint_diagnostics]
520-
pub fn span_lint_with_diagnostics(
521-
&self,
522-
lint: &'static Lint,
523-
span: MultiSpan,
524-
diagnostic: BuiltinLintDiag,
525-
) {
526-
self.opt_span_lint_with_diagnostics(lint, Some(span), diagnostic);
527-
}
528-
529-
/// Emit a lint at the appropriate level, with an optional associated span and an existing
530-
/// diagnostic.
531-
///
532-
/// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
533-
#[rustc_lint_diagnostics]
534-
pub fn opt_span_lint_with_diagnostics(
535-
&self,
536-
lint: &'static Lint,
537-
span: Option<MultiSpan>,
538-
diagnostic: BuiltinLintDiag,
539-
) {
540-
self.opt_span_lint(lint, span, |diag| {
541-
diagnostics::decorate_lint(self.sess(), diagnostic, diag);
542-
});
543-
}
544-
}
545-
546512
pub trait LintContext {
547513
fn sess(&self) -> &Session;
548514

Diff for: compiler/rustc_lint/src/early.rs

+52-13
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,73 @@ use rustc_ast::ptr::P;
88
use rustc_ast::visit::{self as ast_visit, Visitor, walk_list};
99
use rustc_ast::{self as ast, HasAttrs};
1010
use rustc_data_structures::stack::ensure_sufficient_stack;
11+
use rustc_errors::MultiSpan;
1112
use rustc_feature::Features;
12-
use rustc_middle::ty::RegisteredTools;
13+
use rustc_middle::ty::{RegisteredTools, TyCtxt};
1314
use rustc_session::Session;
14-
use rustc_session::lint::{BufferedEarlyLint, LintBuffer, LintPass};
15+
use rustc_session::lint::{BufferedEarlyLint, BuiltinLintDiag, LintBuffer, LintPass};
1516
use rustc_span::Span;
1617
use rustc_span::symbol::Ident;
1718
use tracing::debug;
1819

19-
use crate::context::{EarlyContext, LintStore};
20+
use crate::Lint;
21+
use crate::context::{EarlyContext, LintContext, LintStore};
2022
use crate::passes::{EarlyLintPass, EarlyLintPassObject};
2123

24+
mod diagnostics;
25+
2226
macro_rules! lint_callback { ($cx:expr, $f:ident, $($args:expr),*) => ({
2327
$cx.pass.$f(&$cx.context, $($args),*);
2428
}) }
2529

2630
/// Implements the AST traversal for early lint passes. `T` provides the
2731
/// `check_*` methods.
28-
pub struct EarlyContextAndPass<'a, T: EarlyLintPass> {
32+
pub struct EarlyContextAndPass<'a, 'b, T: EarlyLintPass> {
2933
context: EarlyContext<'a>,
34+
tcx: Option<TyCtxt<'b>>,
3035
pass: T,
3136
}
3237

33-
impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
38+
impl<T: EarlyLintPass> EarlyContextAndPass<'_, '_, T> {
39+
/// Emit a lint at the appropriate level, with an associated span and an existing
40+
/// diagnostic.
41+
///
42+
/// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
43+
#[rustc_lint_diagnostics]
44+
pub fn span_lint_with_diagnostics(
45+
&self,
46+
lint: &'static Lint,
47+
span: MultiSpan,
48+
diagnostic: BuiltinLintDiag,
49+
) {
50+
self.opt_span_lint_with_diagnostics(lint, Some(span), diagnostic);
51+
}
52+
53+
/// Emit a lint at the appropriate level, with an optional associated span and an existing
54+
/// diagnostic.
55+
///
56+
/// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
57+
#[rustc_lint_diagnostics]
58+
pub fn opt_span_lint_with_diagnostics(
59+
&self,
60+
lint: &'static Lint,
61+
span: Option<MultiSpan>,
62+
diagnostic: BuiltinLintDiag,
63+
) {
64+
self.context.opt_span_lint(lint, span, |diag| {
65+
diagnostics::decorate_lint(self.context.sess(), self.tcx, diagnostic, diag);
66+
});
67+
}
68+
}
69+
70+
impl<'a, 'b, T: EarlyLintPass> EarlyContextAndPass<'a, 'b, T> {
3471
// This always-inlined function is for the hot call site.
3572
#[inline(always)]
3673
#[allow(rustc::diagnostic_outside_of_impl)]
3774
fn inlined_check_id(&mut self, id: ast::NodeId) {
3875
for early_lint in self.context.buffered.take(id) {
3976
let BufferedEarlyLint { span, node_id: _, lint_id, diagnostic } = early_lint;
40-
self.context.opt_span_lint_with_diagnostics(lint_id.lint, span, diagnostic);
77+
self.opt_span_lint_with_diagnostics(lint_id.lint, span, diagnostic);
4178
}
4279
}
4380

@@ -67,7 +104,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
67104
}
68105
}
69106

70-
impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> {
107+
impl<'a, 'b, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, 'b, T> {
71108
fn visit_coroutine_kind(&mut self, coroutine_kind: &'a ast::CoroutineKind) -> Self::Result {
72109
self.check_id(coroutine_kind.closure_id());
73110
}
@@ -313,7 +350,7 @@ pub trait EarlyCheckNode<'a>: Copy {
313350
fn attrs<'b>(self) -> &'b [ast::Attribute]
314351
where
315352
'a: 'b;
316-
fn check<'b, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'b, T>)
353+
fn check<'b, 'c, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'b, 'c, T>)
317354
where
318355
'a: 'b;
319356
}
@@ -328,7 +365,7 @@ impl<'a> EarlyCheckNode<'a> for (&'a ast::Crate, &'a [ast::Attribute]) {
328365
{
329366
self.1
330367
}
331-
fn check<'b, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'b, T>)
368+
fn check<'b, 'c, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'b, 'c, T>)
332369
where
333370
'a: 'b,
334371
{
@@ -348,7 +385,7 @@ impl<'a> EarlyCheckNode<'a> for (ast::NodeId, &'a [ast::Attribute], &'a [P<ast::
348385
{
349386
self.1
350387
}
351-
fn check<'b, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'b, T>)
388+
fn check<'b, 'c, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'b, 'c, T>)
352389
where
353390
'a: 'b,
354391
{
@@ -359,6 +396,7 @@ impl<'a> EarlyCheckNode<'a> for (ast::NodeId, &'a [ast::Attribute], &'a [P<ast::
359396

360397
pub fn check_ast_node<'a>(
361398
sess: &Session,
399+
tcx: Option<TyCtxt<'_>>,
362400
features: &Features,
363401
pre_expansion: bool,
364402
lint_store: &LintStore,
@@ -382,22 +420,23 @@ pub fn check_ast_node<'a>(
382420
let passes =
383421
if pre_expansion { &lint_store.pre_expansion_passes } else { &lint_store.early_passes };
384422
if passes.is_empty() {
385-
check_ast_node_inner(sess, check_node, context, builtin_lints);
423+
check_ast_node_inner(sess, tcx, check_node, context, builtin_lints);
386424
} else {
387425
let mut passes: Vec<_> = passes.iter().map(|mk_pass| (mk_pass)()).collect();
388426
passes.push(Box::new(builtin_lints));
389427
let pass = RuntimeCombinedEarlyLintPass { passes: &mut passes[..] };
390-
check_ast_node_inner(sess, check_node, context, pass);
428+
check_ast_node_inner(sess, tcx, check_node, context, pass);
391429
}
392430
}
393431

394432
fn check_ast_node_inner<'a, T: EarlyLintPass>(
395433
sess: &Session,
434+
tcx: Option<TyCtxt<'_>>,
396435
check_node: impl EarlyCheckNode<'a>,
397436
context: EarlyContext<'_>,
398437
pass: T,
399438
) {
400-
let mut cx = EarlyContextAndPass { context, pass };
439+
let mut cx = EarlyContextAndPass { context, tcx, pass };
401440

402441
cx.with_lint_attrs(check_node.id(), check_node.attrs(), |cx| check_node.check(cx));
403442

Diff for: compiler/rustc_lint/src/context/diagnostics.rs renamed to compiler/rustc_lint/src/early/diagnostics.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_errors::{
88
Applicability, Diag, DiagArgValue, LintDiagnostic, elided_lifetime_in_path_suggestion,
99
};
1010
use rustc_middle::middle::stability;
11+
use rustc_middle::ty::TyCtxt;
1112
use rustc_session::Session;
1213
use rustc_session::lint::{BuiltinLintDiag, ElidedLifetimeResolution};
1314
use rustc_span::BytePos;
@@ -18,7 +19,12 @@ use crate::lints::{self, ElidedNamedLifetime};
1819

1920
mod check_cfg;
2021

21-
pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Diag<'_, ()>) {
22+
pub(super) fn decorate_lint(
23+
sess: &Session,
24+
_tcx: Option<TyCtxt<'_>>,
25+
diagnostic: BuiltinLintDiag,
26+
diag: &mut Diag<'_, ()>,
27+
) {
2228
match diagnostic {
2329
BuiltinLintDiag::UnicodeTextFlow(comment_span, content) => {
2430
let spans: Vec<_> = content

0 commit comments

Comments
 (0)