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
@mu001999 mu001999 force-pushed the fix/path-kw-as-cfg-pred branch from f618938 to fc822f8 Compare November 21, 2025 10:48
@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 Nov 21, 2025
@petrochenkov
Copy link
Contributor

@bors r+

@bors
Copy link
Collaborator

bors commented Nov 21, 2025

📌 Commit fc822f8 has been approved by petrochenkov

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 21, 2025
bors added a commit that referenced this pull request Nov 21, 2025
Rollup of 7 pull requests

Successful merges:

 - #146978 (Emit error when using path-segment keyword as cfg pred)
 - #148719 (Allow unnormalized types in drop elaboration)
 - #148795 (add `rust.rustflags` and per target `rustflags` options to `bootstrap.toml`)
 - #149028 ([rustdoc] Remove `UrlFragment::render` method to unify `clean::types::links` and `anchor`)
 - #149043 ( rustdoc-json: add rlib path to ExternalCrate to enable robust crate resolution)
 - #149098 (Fix error message for calling a non-tuple struct)
 - #149151 (Add test for importing path-segment keyword)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 33d11ef into rust-lang:main Nov 21, 2025
11 checks passed
@rustbot rustbot added this to the 1.93.0 milestone Nov 21, 2025
rust-timer added a commit that referenced this pull request Nov 22, 2025
Rollup merge of #146978 - mu001999-contrib:fix/path-kw-as-cfg-pred, r=petrochenkov

Emit error when using path-segment keyword as cfg pred

Fixes #146968

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

Detailed change description - #146978 (comment).

r? petrochenkov
@mu001999 mu001999 deleted the fix/path-kw-as-cfg-pred branch November 22, 2025 03:30
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jan 14, 2026
Don't try to recover keyword as non-keyword identifier

Fixes rust-lang#149692.

On beta after rust-lang#146978, we ICE on

```rs
macro_rules! m {
    ($id:item()) => {}
}

m!(Self());
```

where `Self` in the macro invocation is a keyword not a "normal" identifier, while attempting to recover an missing keyword before an identifier. Except, `Self` *is* a keyword, so trying to parse that as a non-reserved identifier expectedly fails.

I suspect rust-lang#146978 merely unmasked a possible code path to hit this case; this logic has been so for a good while. Previously, on stable, the error message looks something like

```rs
error: expected identifier, found keyword `Self`
 --> src/lib.rs:5:4
  |
5 | m!(Self());
  |    ^^^^ expected identifier, found keyword

error: missing `fn` or `struct` for function or struct definition
 --> src/lib.rs:5:4
  |
2 |     ($id:item()) => {}
  |      -------- while parsing argument for this `item` macro fragment
...
5 | m!(Self());
  |    ^^^^
  |
help: if you meant to call a macro, try
  |
5 | m!(Self!());
  |        +
```

I considered restoring this diagnostic, but I'm not super convinced it's worth the complexity (and to me, it's not super clear what the user actually intended here).
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jan 14, 2026
Don't try to recover keyword as non-keyword identifier

Fixes rust-lang#149692.

On beta after rust-lang#146978, we ICE on

```rs
macro_rules! m {
    ($id:item()) => {}
}

m!(Self());
```

where `Self` in the macro invocation is a keyword not a "normal" identifier, while attempting to recover an missing keyword before an identifier. Except, `Self` *is* a keyword, so trying to parse that as a non-reserved identifier expectedly fails.

I suspect rust-lang#146978 merely unmasked a possible code path to hit this case; this logic has been so for a good while. Previously, on stable, the error message looks something like

```rs
error: expected identifier, found keyword `Self`
 --> src/lib.rs:5:4
  |
5 | m!(Self());
  |    ^^^^ expected identifier, found keyword

error: missing `fn` or `struct` for function or struct definition
 --> src/lib.rs:5:4
  |
2 |     ($id:item()) => {}
  |      -------- while parsing argument for this `item` macro fragment
...
5 | m!(Self());
  |    ^^^^
  |
help: if you meant to call a macro, try
  |
5 | m!(Self!());
  |        +
```

I considered restoring this diagnostic, but I'm not super convinced it's worth the complexity (and to me, it's not super clear what the user actually intended here).
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jan 14, 2026
Don't try to recover keyword as non-keyword identifier

Fixes rust-lang#149692.

On beta after rust-lang#146978, we ICE on

```rs
macro_rules! m {
    ($id:item()) => {}
}

m!(Self());
```

where `Self` in the macro invocation is a keyword not a "normal" identifier, while attempting to recover an missing keyword before an identifier. Except, `Self` *is* a keyword, so trying to parse that as a non-reserved identifier expectedly fails.

I suspect rust-lang#146978 merely unmasked a possible code path to hit this case; this logic has been so for a good while. Previously, on stable, the error message looks something like

```rs
error: expected identifier, found keyword `Self`
 --> src/lib.rs:5:4
  |
5 | m!(Self());
  |    ^^^^ expected identifier, found keyword

error: missing `fn` or `struct` for function or struct definition
 --> src/lib.rs:5:4
  |
2 |     ($id:item()) => {}
  |      -------- while parsing argument for this `item` macro fragment
...
5 | m!(Self());
  |    ^^^^
  |
help: if you meant to call a macro, try
  |
5 | m!(Self!());
  |        +
```

I considered restoring this diagnostic, but I'm not super convinced it's worth the complexity (and to me, it's not super clear what the user actually intended here).
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jan 14, 2026
Don't try to recover keyword as non-keyword identifier

Fixes rust-lang#149692.

On beta after rust-lang#146978, we ICE on

```rs
macro_rules! m {
    ($id:item()) => {}
}

m!(Self());
```

where `Self` in the macro invocation is a keyword not a "normal" identifier, while attempting to recover an missing keyword before an identifier. Except, `Self` *is* a keyword, so trying to parse that as a non-reserved identifier expectedly fails.

I suspect rust-lang#146978 merely unmasked a possible code path to hit this case; this logic has been so for a good while. Previously, on stable, the error message looks something like

```rs
error: expected identifier, found keyword `Self`
 --> src/lib.rs:5:4
  |
5 | m!(Self());
  |    ^^^^ expected identifier, found keyword

error: missing `fn` or `struct` for function or struct definition
 --> src/lib.rs:5:4
  |
2 |     ($id:item()) => {}
  |      -------- while parsing argument for this `item` macro fragment
...
5 | m!(Self());
  |    ^^^^
  |
help: if you meant to call a macro, try
  |
5 | m!(Self!());
  |        +
```

I considered restoring this diagnostic, but I'm not super convinced it's worth the complexity (and to me, it's not super clear what the user actually intended here).
rust-timer added a commit that referenced this pull request Jan 15, 2026
Rollup merge of #150590 - ident-kw-ice, r=petrochenkov

Don't try to recover keyword as non-keyword identifier

Fixes #149692.

On beta after #146978, we ICE on

```rs
macro_rules! m {
    ($id:item()) => {}
}

m!(Self());
```

where `Self` in the macro invocation is a keyword not a "normal" identifier, while attempting to recover an missing keyword before an identifier. Except, `Self` *is* a keyword, so trying to parse that as a non-reserved identifier expectedly fails.

I suspect #146978 merely unmasked a possible code path to hit this case; this logic has been so for a good while. Previously, on stable, the error message looks something like

```rs
error: expected identifier, found keyword `Self`
 --> src/lib.rs:5:4
  |
5 | m!(Self());
  |    ^^^^ expected identifier, found keyword

error: missing `fn` or `struct` for function or struct definition
 --> src/lib.rs:5:4
  |
2 |     ($id:item()) => {}
  |      -------- while parsing argument for this `item` macro fragment
...
5 | m!(Self());
  |    ^^^^
  |
help: if you meant to call a macro, try
  |
5 | m!(Self!());
  |        +
```

I considered restoring this diagnostic, but I'm not super convinced it's worth the complexity (and to me, it's not super clear what the user actually intended here).
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Jan 15, 2026
Don't try to recover keyword as non-keyword identifier

Fixes rust-lang/rust#149692.

On beta after rust-lang/rust#146978, we ICE on

```rs
macro_rules! m {
    ($id:item()) => {}
}

m!(Self());
```

where `Self` in the macro invocation is a keyword not a "normal" identifier, while attempting to recover an missing keyword before an identifier. Except, `Self` *is* a keyword, so trying to parse that as a non-reserved identifier expectedly fails.

I suspect rust-lang/rust#146978 merely unmasked a possible code path to hit this case; this logic has been so for a good while. Previously, on stable, the error message looks something like

```rs
error: expected identifier, found keyword `Self`
 --> src/lib.rs:5:4
  |
5 | m!(Self());
  |    ^^^^ expected identifier, found keyword

error: missing `fn` or `struct` for function or struct definition
 --> src/lib.rs:5:4
  |
2 |     ($id:item()) => {}
  |      -------- while parsing argument for this `item` macro fragment
...
5 | m!(Self());
  |    ^^^^
  |
help: if you meant to call a macro, try
  |
5 | m!(Self!());
  |        +
```

I considered restoring this diagnostic, but I'm not super convinced it's worth the complexity (and to me, it's not super clear what the user actually intended here).
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jan 19, 2026
Parse ident with allowing recovery when trying to diagnose

Fixes rust-lang#151238

rust-lang#146978 made parsing ident not always allowed-recovery ([change](https://github.com/rust-lang/rust/pull/146978/changes#diff-ef8d6186dc7fb1d03a71446d0c9e6cc9e72158ec6896703dcf05686ee7dc83fcL469-R469)), so when matching macro with `NoopTracker`, which has `Recovery::Forbidden`, ICE happens when trying to parse kw as ident and then unwraping it.

This PR introduces a new method for parsing ident with allowing recovery when trying to diagnose. Then errors will behave like previous.

r? @petrochenkov
rust-timer added a commit that referenced this pull request Jan 20, 2026
Rollup merge of #151249 - fix/151238, r=petrochenkov

Parse ident with allowing recovery when trying to diagnose

Fixes #151238

#146978 made parsing ident not always allowed-recovery ([change](https://github.com/rust-lang/rust/pull/146978/changes#diff-ef8d6186dc7fb1d03a71446d0c9e6cc9e72158ec6896703dcf05686ee7dc83fcL469-R469)), so when matching macro with `NoopTracker`, which has `Recovery::Forbidden`, ICE happens when trying to parse kw as ident and then unwraping it.

This PR introduces a new method for parsing ident with allowing recovery when trying to diagnose. Then errors will behave like previous.

r? @petrochenkov
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Jan 20, 2026
Parse ident with allowing recovery when trying to diagnose

Fixes rust-lang/rust#151238

rust-lang/rust#146978 made parsing ident not always allowed-recovery ([change](https://github.com/rust-lang/rust/pull/146978/changes#diff-ef8d6186dc7fb1d03a71446d0c9e6cc9e72158ec6896703dcf05686ee7dc83fcL469-R469)), so when matching macro with `NoopTracker`, which has `Recovery::Forbidden`, ICE happens when trying to parse kw as ident and then unwraping it.

This PR introduces a new method for parsing ident with allowing recovery when trying to diagnose. Then errors will behave like previous.

r? @petrochenkov
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributes Area: Attributes (`#[…]`, `#![…]`) disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. F-explicit_tail_calls `#![feature(explicit_tail_calls)]` finished-final-comment-period The final comment period is finished for this PR / Issue. relnotes Marks issues that should be documented in the release notes of the next release. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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 to-announce Announce this issue on triage meeting

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