Skip to content

Conversation

@mu001999
Copy link
Contributor

@mu001999 mu001999 commented Sep 24, 2025

Fixes #146968

Emit error CfgPredicateIdentifier if the word is path-segment keyword.

Detailed change description - #146978 (comment).

r? petrochenkov

@rustbot
Copy link
Collaborator

rustbot commented Sep 24, 2025

Some changes occurred in compiler/rustc_attr_parsing

cc @jdonszelmann

@rustbot rustbot added A-attributes Area: Attributes (`#[…]`, `#![…]`) S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 24, 2025
@petrochenkov
Copy link
Contributor

Could you

  • add similar test cases for some non path-segment keyword, like struct
  • add test cases for --cfg on command line and make sure that they behave identically to cfg! and #[cfg].

After that we should be able to run crater on this.
@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 26, 2025
@rustbot
Copy link
Collaborator

rustbot commented Sep 26, 2025

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@mu001999 mu001999 force-pushed the fix/path-kw-as-cfg-pred branch from 505d13f to b2be57d Compare September 27, 2025 03:24
@rustbot

This comment has been minimized.

@mu001999
Copy link
Contributor Author

add test cases for --cfg on command line and make sure that they behave identically to cfg! and #[cfg]

--cfg will emit same error but will be suppressed because parse_cfg is called with ParseSess::with_fatal_emitter

@mu001999
Copy link
Contributor Author

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Sep 27, 2025
@petrochenkov
Copy link
Contributor

add test cases for --cfg on command line and make sure that they behave identically to cfg! and #[cfg]

--cfg will emit same error but will be suppressed because parse_cfg is called with ParseSess::with_fatal_emitter

with_fatal_emitter doesn't suppress errors, it makes them fatal.
--cfg parsing has its own error reporting logic in fn parse_cfg in compiler\rustc_interface\src\interface.rs, and the new errors are not emitted there.
@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 30, 2025
@mu001999
Copy link
Contributor Author

with_fatal_emitter doesn't suppress errors, it makes them fatal.

@petrochenkov I found with_fatal_emitter create dcx with FatalOnlyEmitter, see

pub fn with_fatal_emitter(locale_resources: Vec<&'static str>, fatal_note: String) -> Self {
let translator = Translator::with_fallback_bundle(locale_resources, false);
let sm = Arc::new(SourceMap::new(FilePathMapping::empty()));
let fatal_emitter =
Box::new(HumanEmitter::new(stderr_destination(ColorConfig::Auto), translator));
let dcx = DiagCtxt::new(Box::new(FatalOnlyEmitter {
fatal_emitter,
fatal_note: Some(fatal_note),
}))
.disable_warnings();
ParseSess::with_dcx(dcx, sm)
}

and the comment of FatalOnlyEmitter and the impl of FatalOnlyEmitter::emit_diagnostic show only errors with diag.level == Level::Fatal can be emitted, see

/// An emitter that does nothing when emitting a non-fatal diagnostic.
/// Fatal diagnostics are forwarded to `fatal_emitter` to avoid silent
/// failures of rustc, as witnessed e.g. in issue #89358.
pub struct FatalOnlyEmitter {
pub fatal_emitter: Box<dyn Emitter + DynSend>,
pub fatal_note: Option<String>,
}
impl Emitter for FatalOnlyEmitter {
fn source_map(&self) -> Option<&SourceMap> {
None
}
fn emit_diagnostic(&mut self, mut diag: DiagInner, registry: &Registry) {
if diag.level == Level::Fatal {
if let Some(fatal_note) = &self.fatal_note {
diag.sub(Level::Note, fatal_note.clone(), MultiSpan::new());
}
self.fatal_emitter.emit_diagnostic(diag, registry);
}
}
fn translator(&self) -> &Translator {
self.fatal_emitter.translator()
}
}

@mu001999
Copy link
Contributor Author

mu001999 commented Sep 30, 2025

I have debug the logic in fn parse_cfg, and the err.emit is called in fact, but it is suppressed by the FatalOnlyEmitter.

@petrochenkov
Copy link
Contributor

petrochenkov commented Sep 30, 2025

Ah, ok, "fatal emitter" means "fatal-only emitter".

In any case, the behavior is not correct.
I guess the assumption when using the fatal emitter was that we always reach the "expected key or key="value"" error at the bottom anyway, but that's not actually the case.
If we get to return (ident.name, meta_item.value_str()), then all the non-fatal errors are lost, which is incorrect.

@mu001999 mu001999 marked this pull request as draft October 9, 2025 06:02
@rust-log-analyzer

This comment has been minimized.

@mu001999 mu001999 force-pushed the fix/path-kw-as-cfg-pred branch from 956aa91 to 97cd2c7 Compare October 9, 2025 11:16
@rust-log-analyzer

This comment has been minimized.

@mu001999 mu001999 force-pushed the fix/path-kw-as-cfg-pred branch from 97cd2c7 to a7d6090 Compare October 9, 2025 11:54
@rust-log-analyzer

This comment has been minimized.

@mu001999 mu001999 force-pushed the fix/path-kw-as-cfg-pred branch from a7d6090 to c8bc460 Compare October 9, 2025 15:31
@rust-log-analyzer

This comment has been minimized.

@mu001999 mu001999 force-pushed the fix/path-kw-as-cfg-pred branch from cc53ca4 to 9c2ed4c Compare October 9, 2025 18:10
@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 20, 2025
@mu001999 mu001999 force-pushed the fix/path-kw-as-cfg-pred branch from 15853b8 to 65b32a4 Compare October 20, 2025 16:13
@petrochenkov
Copy link
Contributor

Thanks, this should be ready for crater now, the remaining minor cleanups can be done later.
@bors try

rust-bors bot added a commit that referenced this pull request Oct 20, 2025
…try>

Emit error when using path-segment keyword as cfg pred
@rust-bors

This comment has been minimized.

@petrochenkov petrochenkov added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Oct 20, 2025
@rust-bors
Copy link

rust-bors bot commented Oct 20, 2025

☀️ Try build successful (CI)
Build commit: 4e55a50 (4e55a504843955c97eb06907c71f6f3e99208021, parent: 4068bafedd8ba724e332a5221c06a6fa531a30d2)

@petrochenkov
Copy link
Contributor

@craterbot check

@craterbot
Copy link
Collaborator

👌 Experiment pr-146978 created and queued.
🤖 Automatically detected try build 4e55a50
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot
Copy link
Collaborator

🚧 Experiment pr-146978 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot
Copy link
Collaborator

🎉 Experiment pr-146978 is completed!
📊 5 regressed and 3 fixed (720593 total)
📊 1730 spurious results on the retry-regessed-list.txt, consider a retry1 if this is a significant amount.
📰 Open the summary report.

⚠️ If you notice any spurious failure please add them to the denylist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

Footnotes

  1. re-run the experiment with crates=https://crater-reports.s3.amazonaws.com/pr-146978/retry-regressed-list.txt

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Oct 22, 2025
@petrochenkov
Copy link
Contributor

Nice, there are only spurious regressions.
I'll write the change description for the lang team later today and pass it to them.

@mu001999
Copy link
Contributor Author

@petrochenkov Cool! Thanks!

@petrochenkov
Copy link
Contributor

Change introducion

This PR makes syntax accepted by cfg predicates in #[cfg] attributes and cfg! macros stricter.
It also makes predicates in --cfg command line options accept the same syntax as in the attributes and macros (except true and false).

#[cfg] and cfg!

Predicates are generally supposed to use non-keyword identifiers (cfg!(ident), cfg!(ident="value")) + boolean literals, and attributes and macros generally followed this grammar, with one exception.
The exceptions is that path segment keywords (super, self, Self, crate, expanded $crate) were accepted.

This happened because internally cfg predicates were parsed as meta-items (besides boolean literals), and then inappropriate meta-items were rejected after obtaining the parsing result.
Path segment keywords are syntactically valid paths, and therefore valid meta-items, so they were successfully parsed but accidentally not rejected by a post-processing check.

This PR rejects them.

--cfg

Predicate syntax in --cfg was parsed largely incorrectly due to majority of parsing errors being suppressed.
Internally --cfg parsing used so called FatalOnlyEmitter overriding the regular error emitter, and that emitter just ignored all recoverable errors.
Initially a different emitter was introduced in "Hide diagnostics emitted during --cfg parsing" to improve diagnostics (reduce noisiness), but the actual effect was also occasionally accepting invalid syntax. "Report fatal lexer errors in --cfg command line arguments" fixed up the situation a bit, but not completely.
Eventually parser improved and improved its recovery, produced more and more recoverable errors, and FatalOnlyEmitter became more and more wrong, leading to the current situation.
In particular, the --cfg true/--cfg false case considered by lang team in #138632 (comment) was an instance of errors swallowed by FatalOnlyEmitter, it is not syntactically valid (true and false are not even meta-items).

This PR disables the error suppression in --cfg parsing and makes it accept the same syntax as its counterparts in #[cfg] and cfg! (except true and false because those are not predicate definitions).

Breakage

Crater run above (#146978 (comment)) didn't find any regressions from this.

@petrochenkov petrochenkov added S-waiting-on-t-lang Status: Awaiting decision from T-lang T-lang Relevant to the language team I-lang-nominated Nominated for discussion during a lang team meeting. and removed A-testsuite Area: The testsuite used to check the correctness of rustc T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. F-explicit_tail_calls `#![feature(explicit_tail_calls)]` A-compiletest Area: The compiletest test runner A-run-make Area: port run-make Makefiles to rmake.rs labels Oct 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributes Area: Attributes (`#[…]`, `#![…]`) I-lang-nominated Nominated for discussion during a lang team meeting. S-waiting-on-t-lang Status: Awaiting decision from T-lang T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cfg!($crate), cfg!(crate), cfg!(self), cfg!(Self), and cfg!(super) should not be accepted

8 participants