Skip to content

Commit 4b35cde

Browse files
committed
Support lints in early attribute parsing
1 parent 3bf6144 commit 4b35cde

File tree

11 files changed

+93
-45
lines changed

11 files changed

+93
-45
lines changed

Cargo.lock

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3791,7 +3791,6 @@ dependencies = [
37913791
"rustc_error_messages",
37923792
"rustc_fluent_macro",
37933793
"rustc_hashes",
3794-
"rustc_hir_id",
37953794
"rustc_index",
37963795
"rustc_lexer",
37973796
"rustc_lint_defs",

compiler/rustc_attr_parsing/src/interface.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,27 @@ impl<'sess> AttributeParser<'sess, Early> {
5050
target_span: Span,
5151
target_node_id: NodeId,
5252
features: Option<&'sess Features>,
53+
) -> Option<Attribute> {
54+
Self::parse_limited_should_emit(
55+
sess,
56+
attrs,
57+
sym,
58+
target_span,
59+
target_node_id,
60+
features,
61+
ShouldEmit::Nothing,
62+
)
63+
}
64+
65+
/// Usually you want `parse_limited`, which defaults to no errors.
66+
pub fn parse_limited_should_emit(
67+
sess: &'sess Session,
68+
attrs: &[ast::Attribute],
69+
sym: Symbol,
70+
target_span: Span,
71+
target_node_id: NodeId,
72+
features: Option<&'sess Features>,
73+
should_emit: ShouldEmit,
5374
) -> Option<Attribute> {
5475
let mut parsed = Self::parse_limited_all(
5576
sess,
@@ -59,7 +80,7 @@ impl<'sess> AttributeParser<'sess, Early> {
5980
target_span,
6081
target_node_id,
6182
features,
62-
ShouldEmit::Nothing,
83+
should_emit,
6384
);
6485
assert!(parsed.len() <= 1);
6586
parsed.pop()
@@ -84,9 +105,8 @@ impl<'sess> AttributeParser<'sess, Early> {
84105
target,
85106
OmitDoc::Skip,
86107
std::convert::identity,
87-
|_lint| {
88-
// FIXME: Can't emit lints here for now
89-
// This branch can be hit when an attribute produces a warning during early parsing (such as attributes on macro calls)
108+
|lint| {
109+
crate::lints::emit_attribute_lint(&lint, sess);
90110
},
91111
)
92112
}
@@ -121,8 +141,8 @@ impl<'sess> AttributeParser<'sess, Early> {
121141
cx: &mut parser,
122142
target_span,
123143
target_id: target_node_id,
124-
emit_lint: &mut |_lint| {
125-
panic!("can't emit lints here for now (nothing uses this atm)");
144+
emit_lint: &mut |lint| {
145+
crate::lints::emit_attribute_lint(&lint, sess);
126146
},
127147
},
128148
attr_span: attr.span,

compiler/rustc_attr_parsing/src/lints.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use std::borrow::Cow;
22

33
use rustc_errors::{DiagArgValue, LintEmitter};
4+
use rustc_hir::Target;
45
use rustc_hir::lints::{AttributeLint, AttributeLintKind};
5-
use rustc_hir::{HirId, Target};
66
use rustc_span::sym;
77

88
use crate::session_diagnostics;
99

10-
pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<HirId>, lint_emitter: L) {
10+
pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<L::Id>, lint_emitter: L) {
1111
let AttributeLint { id, span, kind } = lint;
1212

1313
match kind {
@@ -51,7 +51,7 @@ pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<HirId>, lint_emi
5151
*id,
5252
*span,
5353
session_diagnostics::InvalidTargetLint {
54-
name,
54+
name: name.clone(),
5555
target: target.plural_name(),
5656
applied: DiagArgValue::StrListSepByAnd(
5757
applied.into_iter().map(|i| Cow::Owned(i.to_string())).collect(),

compiler/rustc_attr_parsing/src/session_diagnostics.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -484,9 +484,9 @@ pub(crate) struct EmptyAttributeList {
484484
#[diag(attr_parsing_invalid_target_lint)]
485485
#[warning]
486486
#[help]
487-
pub(crate) struct InvalidTargetLint<'a> {
488-
pub name: &'a AttrPath,
489-
pub target: &'a str,
487+
pub(crate) struct InvalidTargetLint {
488+
pub name: AttrPath,
489+
pub target: &'static str,
490490
pub applied: DiagArgValue,
491491
pub only: &'static str,
492492
#[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]

compiler/rustc_errors/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ rustc_error_codes = { path = "../rustc_error_codes" }
1414
rustc_error_messages = { path = "../rustc_error_messages" }
1515
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
1616
rustc_hashes = { path = "../rustc_hashes" }
17-
rustc_hir_id = { path = "../rustc_hir_id" }
1817
rustc_index = { path = "../rustc_index" }
1918
rustc_lexer = { path = "../rustc_lexer" }
2019
rustc_lint_defs = { path = "../rustc_lint_defs" }

compiler/rustc_errors/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ pub use rustc_error_messages::{
6161
fallback_fluent_bundle, fluent_bundle, into_diag_arg_using_display,
6262
};
6363
use rustc_hashes::Hash128;
64-
use rustc_hir_id::HirId;
6564
pub use rustc_lint_defs::{Applicability, listify, pluralize};
6665
use rustc_lint_defs::{Lint, LintExpectationId};
6766
use rustc_macros::{Decodable, Encodable};
@@ -110,13 +109,14 @@ rustc_data_structures::static_assert_size!(PResult<'_, bool>, 24);
110109
/// Used to avoid depending on `rustc_middle` in `rustc_attr_parsing`.
111110
/// Always the `TyCtxt`.
112111
pub trait LintEmitter: Copy {
112+
type Id: Copy;
113113
#[track_caller]
114114
fn emit_node_span_lint(
115115
self,
116116
lint: &'static Lint,
117-
hir_id: HirId,
117+
hir_id: Self::Id,
118118
span: impl Into<MultiSpan>,
119-
decorator: impl for<'a> LintDiagnostic<'a, ()>,
119+
decorator: impl for<'a> LintDiagnostic<'a, ()> + DynSend + 'static,
120120
);
121121
}
122122

compiler/rustc_middle/src/ty/context.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,6 +1421,8 @@ pub struct TyCtxt<'tcx> {
14211421
}
14221422

14231423
impl<'tcx> LintEmitter for TyCtxt<'tcx> {
1424+
type Id = HirId;
1425+
14241426
fn emit_node_span_lint(
14251427
self,
14261428
lint: &'static Lint,

compiler/rustc_session/src/session.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::sync::atomic::AtomicBool;
77
use std::{env, fmt, io};
88

99
use rand::{RngCore, rng};
10+
use rustc_ast::NodeId;
1011
use rustc_data_structures::base_n::{CASE_INSENSITIVE, ToBaseN};
1112
use rustc_data_structures::flock;
1213
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
@@ -22,7 +23,7 @@ use rustc_errors::timings::TimingSectionHandler;
2223
use rustc_errors::translation::Translator;
2324
use rustc_errors::{
2425
Diag, DiagCtxt, DiagCtxtHandle, DiagMessage, Diagnostic, ErrorGuaranteed, FatalAbort,
25-
TerminalUrl, fallback_fluent_bundle,
26+
LintEmitter, TerminalUrl, fallback_fluent_bundle,
2627
};
2728
use rustc_macros::HashStable_Generic;
2829
pub use rustc_span::def_id::StableCrateId;
@@ -223,6 +224,20 @@ pub struct Session {
223224
pub invocation_temp: Option<String>,
224225
}
225226

227+
impl LintEmitter for &'_ Session {
228+
type Id = NodeId;
229+
230+
fn emit_node_span_lint(
231+
self,
232+
lint: &'static rustc_lint_defs::Lint,
233+
node_id: Self::Id,
234+
span: impl Into<rustc_errors::MultiSpan>,
235+
decorator: impl for<'a> rustc_errors::LintDiagnostic<'a, ()> + DynSend + 'static,
236+
) {
237+
self.psess.buffer_lint(lint, span, node_id, decorator);
238+
}
239+
}
240+
226241
#[derive(Clone, Copy)]
227242
pub enum CodegenUnits {
228243
/// Specified by the user. In this case we try fairly hard to produce the

tests/ui/lint/unused/unused_attributes-must_use.fixed

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ extern "Rust" {
6666
}
6767

6868
//~ ERROR unused attribute
69+
//~^ ERROR `#[must_use]` attribute cannot be used on macro calls
70+
//~| WARN this was previously accepted by the compiler but is being phased out
6971
global_asm!("");
7072

7173
//~ ERROR attribute cannot be used on

tests/ui/lint/unused/unused_attributes-must_use.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ extern "Rust" {
6666
}
6767

6868
#[must_use] //~ ERROR unused attribute
69+
//~^ ERROR `#[must_use]` attribute cannot be used on macro calls
70+
//~| WARN this was previously accepted by the compiler but is being phased out
6971
global_asm!("");
7072

7173
#[must_use] //~ ERROR attribute cannot be used on

0 commit comments

Comments
 (0)