Skip to content

Commit ce57a19

Browse files
Wip
1 parent 30132fa commit ce57a19

File tree

8 files changed

+60
-99
lines changed

8 files changed

+60
-99
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use std::sync::Arc;
4040

4141
use rustc_ast::node_id::NodeMap;
4242
use rustc_ast::{self as ast, *};
43-
use rustc_attr_parsing::{AttributeParser, Late, OmitDoc};
43+
use rustc_attr_parsing::{AttributeParser, Late, OmitDoc, ShouldEmit};
4444
use rustc_data_structures::fingerprint::Fingerprint;
4545
use rustc_data_structures::sorted_map::SortedMap;
4646
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -208,6 +208,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
208208
tcx.features(),
209209
registered_tools,
210210
Late,
211+
ShouldEmit::ErrorsAndLints,
211212
),
212213
delayed_lints: Vec::new(),
213214
}

compiler/rustc_attr_parsing/src/attributes/cfg.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ fn parse_cfg_entry_version<S: Stage>(
103103
list: &MetaItemListParser,
104104
meta_span: Span,
105105
) -> Result<CfgEntry, ErrorGuaranteed> {
106-
try_gate_cfg(sym::version, meta_span, cx.sess(), cx.features_option());
106+
try_gate_cfg(sym::version, meta_span, cx);
107107
let Some(version) = list.single() else {
108108
return Err(
109109
cx.emit_err(session_diagnostics::ExpectedSingleVersionLiteral { span: list.span })
@@ -135,7 +135,8 @@ fn parse_cfg_entry_target<S: Stage>(
135135
list: &MetaItemListParser,
136136
meta_span: Span,
137137
) -> Result<CfgEntry, ErrorGuaranteed> {
138-
if let Some(features) = cx.features_option()
138+
if let ShouldEmit::ErrorsAndLints = cx.should_emit
139+
&& let Some(features) = cx.features_option()
139140
&& !features.cfg_target_compact()
140141
{
141142
feature_err(
@@ -180,7 +181,7 @@ pub(crate) fn parse_name_value<S: Stage>(
180181
span: Span,
181182
cx: &mut AcceptContext<'_, '_, S>,
182183
) -> Result<CfgEntry, ErrorGuaranteed> {
183-
try_gate_cfg(name, span, cx.sess(), cx.features_option());
184+
try_gate_cfg(name, span, cx);
184185

185186
let value = match value {
186187
None => None,
@@ -413,10 +414,13 @@ fn parse_cfg_attr_internal<'a>(
413414
Ok((cfg_predicate, expanded_attrs))
414415
}
415416

416-
fn try_gate_cfg(name: Symbol, span: Span, sess: &Session, features: Option<&Features>) {
417+
fn try_gate_cfg<S: Stage>(name: Symbol, span: Span, cx: &mut AcceptContext<'_, '_, S>) {
418+
if let ShouldEmit::Nothing = cx.should_emit {
419+
return;
420+
}
417421
let gate = find_gated_cfg(|sym| sym == name);
418-
if let (Some(feats), Some(gated_cfg)) = (features, gate) {
419-
gate_cfg(gated_cfg, span, sess, feats);
422+
if let (Some(feats), Some(gated_cfg)) = (cx.features, gate) {
423+
gate_cfg(gated_cfg, span, cx.sess, feats);
420424
}
421425
}
422426

compiler/rustc_attr_parsing/src/attributes/cfg_trace.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ use rustc_feature::AttributeTemplate;
22
use rustc_hir::attrs::{AttributeKind, CfgEntry};
33
use rustc_span::{Symbol, sym};
44

5-
use crate::{parse_cfg_entry, CFG_TEMPLATE};
65
use crate::attributes::{CombineAttributeParser, ConvertFn};
76
use crate::context::{AcceptContext, Stage};
87
use crate::parser::ArgParser;
98
use crate::target_checking::{ALL_TARGETS, AllowedTargets};
9+
use crate::{CFG_TEMPLATE, parse_cfg_entry};
1010

1111
pub(crate) struct CfgTraceParser;
1212

@@ -22,11 +22,9 @@ impl<S: Stage> CombineAttributeParser<S> for CfgTraceParser {
2222
args: &ArgParser,
2323
) -> impl IntoIterator<Item = Self::Item> {
2424
let Some(list) = args.list() else {
25-
cx.expected_list(cx.attr_span, args);
2625
return None;
2726
};
2827
let Some(entry) = list.single() else {
29-
cx.expected_single_argument(list.span);
3028
return None;
3129
};
3230

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 4 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,11 @@ use std::sync::LazyLock;
55

66
use private::Sealed;
77
use rustc_ast::{AttrStyle, CRATE_NODE_ID, MetaItemLit, NodeId};
8-
use rustc_errors::{Diag, Diagnostic, Level};
8+
use rustc_errors::{Diag, Level};
99
use rustc_feature::{AttrSuggestionStyle, AttributeTemplate};
1010
use rustc_hir::attrs::AttributeKind;
1111
use rustc_hir::lints::{AttributeLint, AttributeLintKind};
1212
use rustc_hir::{AttrPath, CRATE_HIR_ID, HirId};
13-
use rustc_session::Session;
1413
use rustc_session::lint::{Lint, LintId};
1514
use rustc_span::{ErrorGuaranteed, Span, Symbol};
1615

@@ -279,14 +278,6 @@ pub trait Stage: Sized + 'static + Sealed {
279278

280279
fn parsers() -> &'static GroupType<Self>;
281280

282-
fn emit_err<'sess>(
283-
&self,
284-
sess: &'sess Session,
285-
diag: impl for<'x> Diagnostic<'x>,
286-
) -> ErrorGuaranteed;
287-
288-
fn should_emit(&self) -> ShouldEmit;
289-
290281
fn id_is_crate_root(id: Self::Id) -> bool;
291282
}
292283

@@ -298,17 +289,6 @@ impl Stage for Early {
298289
fn parsers() -> &'static GroupType<Self> {
299290
&early::ATTRIBUTE_PARSERS
300291
}
301-
fn emit_err<'sess>(
302-
&self,
303-
sess: &'sess Session,
304-
diag: impl for<'x> Diagnostic<'x>,
305-
) -> ErrorGuaranteed {
306-
self.should_emit().emit_err(sess.dcx().create_err(diag))
307-
}
308-
309-
fn should_emit(&self) -> ShouldEmit {
310-
self.emit_errors
311-
}
312292

313293
fn id_is_crate_root(id: Self::Id) -> bool {
314294
id == CRATE_NODE_ID
@@ -323,30 +303,15 @@ impl Stage for Late {
323303
fn parsers() -> &'static GroupType<Self> {
324304
&late::ATTRIBUTE_PARSERS
325305
}
326-
fn emit_err<'sess>(
327-
&self,
328-
tcx: &'sess Session,
329-
diag: impl for<'x> Diagnostic<'x>,
330-
) -> ErrorGuaranteed {
331-
tcx.dcx().emit_err(diag)
332-
}
333-
334-
fn should_emit(&self) -> ShouldEmit {
335-
ShouldEmit::ErrorsAndLints
336-
}
337306

338307
fn id_is_crate_root(id: Self::Id) -> bool {
339308
id == CRATE_HIR_ID
340309
}
341310
}
342311

343312
/// used when parsing attributes for miscellaneous things *before* ast lowering
344-
pub struct Early {
345-
/// Whether to emit errors or delay them as a bug
346-
/// For most attributes, the attribute will be parsed again in the `Late` stage and in this case the errors should be delayed
347-
/// But for some, such as `cfg`, the attribute will be removed before the `Late` stage so errors must be emitted
348-
pub emit_errors: ShouldEmit,
349-
}
313+
pub struct Early;
314+
350315
/// used when parsing attributes during ast lowering
351316
pub struct Late;
352317

@@ -383,16 +348,12 @@ pub struct AcceptContext<'f, 'sess, S: Stage> {
383348
}
384349

385350
impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
386-
pub(crate) fn emit_err(&self, diag: impl for<'x> Diagnostic<'x>) -> ErrorGuaranteed {
387-
self.stage.emit_err(&self.sess, diag)
388-
}
389-
390351
/// Emit a lint. This method is somewhat special, since lints emitted during attribute parsing
391352
/// must be delayed until after HIR is built. This method will take care of the details of
392353
/// that.
393354
pub(crate) fn emit_lint(&mut self, lint: &'static Lint, kind: AttributeLintKind, span: Span) {
394355
if !matches!(
395-
self.stage.should_emit(),
356+
self.should_emit,
396357
ShouldEmit::ErrorsAndLints | ShouldEmit::EarlyFatal { also_emit_lints: true }
397358
) {
398359
return;

compiler/rustc_attr_parsing/src/interface.rs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ use std::convert::identity;
33
use rustc_ast as ast;
44
use rustc_ast::token::DocFragmentKind;
55
use rustc_ast::{AttrStyle, NodeId, Safety};
6-
use rustc_errors::DiagCtxtHandle;
6+
use rustc_errors::{DiagCtxtHandle, Diagnostic};
77
use rustc_feature::{AttributeTemplate, Features};
88
use rustc_hir::attrs::AttributeKind;
99
use rustc_hir::lints::AttributeLint;
1010
use rustc_hir::{AttrArgs, AttrItem, AttrPath, Attribute, HashIgnoredAttrId, Target};
1111
use rustc_session::Session;
1212
use rustc_session::lint::BuiltinLintDiag;
13-
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
13+
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
1414

1515
use crate::context::{AcceptContext, FinalizeContext, SharedContext, Stage};
1616
use crate::parser::{ArgParser, PathParser, RefPathParser};
@@ -23,7 +23,8 @@ pub struct AttributeParser<'sess, S: Stage = Late> {
2323
pub(crate) tools: Vec<Symbol>,
2424
pub(crate) features: Option<&'sess Features>,
2525
pub(crate) sess: &'sess Session,
26-
pub(crate) stage: S,
26+
pub(crate) _stage: S,
27+
pub(crate) should_emit: ShouldEmit,
2728

2829
/// *Only* parse attributes with this symbol.
2930
///
@@ -105,10 +106,10 @@ impl<'sess> AttributeParser<'sess, Early> {
105106
target_span: Span,
106107
target_node_id: NodeId,
107108
features: Option<&'sess Features>,
108-
emit_errors: ShouldEmit,
109+
should_emit: ShouldEmit,
109110
) -> Vec<Attribute> {
110111
let mut p =
111-
Self { features, tools: Vec::new(), parse_only, sess, stage: Early { emit_errors } };
112+
Self { features, tools: Vec::new(), parse_only, sess, _stage: Early, should_emit };
112113
p.parse_attribute_list(
113114
attrs,
114115
target_span,
@@ -179,7 +180,7 @@ impl<'sess> AttributeParser<'sess, Early> {
179180
target_span: Span,
180181
target_node_id: NodeId,
181182
features: Option<&'sess Features>,
182-
emit_errors: ShouldEmit,
183+
should_emit: ShouldEmit,
183184
args: &I,
184185
parse_fn: fn(cx: &mut AcceptContext<'_, '_, Early>, item: &I) -> T,
185186
template: &AttributeTemplate,
@@ -189,7 +190,8 @@ impl<'sess> AttributeParser<'sess, Early> {
189190
tools: Vec::new(),
190191
parse_only: None,
191192
sess,
192-
stage: Early { emit_errors },
193+
_stage: Early,
194+
should_emit,
193195
};
194196
let mut emit_lint = |lint: AttributeLint<NodeId>| {
195197
sess.psess.buffer_lint(
@@ -206,7 +208,6 @@ impl<'sess> AttributeParser<'sess, Early> {
206208
safety,
207209
&mut emit_lint,
208210
target_node_id,
209-
emit_errors,
210211
)
211212
}
212213
let mut cx: AcceptContext<'_, 'sess, Early> = AcceptContext {
@@ -233,8 +234,9 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
233234
features: &'sess Features,
234235
tools: Vec<Symbol>,
235236
stage: S,
237+
should_emit: ShouldEmit,
236238
) -> Self {
237-
Self { features: Some(features), tools, parse_only: None, sess, stage }
239+
Self { features: Some(features), tools, parse_only: None, sess, _stage: stage, should_emit }
238240
}
239241

240242
pub(crate) fn sess(&self) -> &'sess Session {
@@ -253,6 +255,10 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
253255
self.sess().dcx()
254256
}
255257

258+
pub(crate) fn emit_err(&self, diag: impl for<'x> Diagnostic<'x>) -> ErrorGuaranteed {
259+
self.should_emit.emit_err(self.dcx().create_err(diag))
260+
}
261+
256262
/// Parse a list of attributes.
257263
///
258264
/// `target_span` is the span of the thing this list of attributes is applied to,
@@ -264,14 +270,16 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
264270
target_id: S::Id,
265271
target: Target,
266272
omit_doc: OmitDoc,
267-
268273
lower_span: impl Copy + Fn(Span) -> Span,
269274
mut emit_lint: impl FnMut(AttributeLint<S::Id>),
270275
) -> Vec<Attribute> {
271276
let mut attributes = Vec::new();
272277
let mut attr_paths: Vec<RefPathParser<'_>> = Vec::new();
278+
let old_should_emit = self.should_emit;
273279

274280
for attr in attrs {
281+
self.should_emit = old_should_emit; //FIXME ugly solution
282+
275283
// If we're only looking for a single attribute, skip all the ones we don't care about.
276284
if let Some(expected) = self.parse_only {
277285
if !attr.has_name(expected) {
@@ -305,11 +313,10 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
305313
ast::AttrKind::Normal(n) => {
306314
attr_paths.push(PathParser(&n.item.path));
307315
let attr_path = AttrPath::from_ast(&n.item.path, lower_span);
308-
let mut should_emit = self.stage.should_emit();
309316

310317
// Don't emit anything for trace attributes
311318
if attr.has_any_name(&[sym::cfg_trace, sym::cfg_attr_trace]) {
312-
should_emit = ShouldEmit::Nothing;
319+
self.should_emit = ShouldEmit::Nothing;
313320
}
314321

315322
self.check_attribute_safety(
@@ -318,7 +325,6 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
318325
n.item.unsafety,
319326
&mut emit_lint,
320327
target_id,
321-
should_emit,
322328
);
323329

324330
let parts =
@@ -329,7 +335,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
329335
&n.item.args,
330336
&parts,
331337
&self.sess.psess,
332-
should_emit,
338+
self.should_emit,
333339
) else {
334340
continue;
335341
};
@@ -382,9 +388,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
382388
};
383389

384390
(accept.accept_fn)(&mut cx, &args);
385-
if !matches!(should_emit, ShouldEmit::Nothing) {
386-
Self::check_target(&accept.allowed_targets, target, &mut cx);
387-
}
391+
Self::check_target(&accept.allowed_targets, target, &mut cx);
388392
}
389393
} else {
390394
// If we're here, we must be compiling a tool attribute... Or someone

0 commit comments

Comments
 (0)