Skip to content

Error on non-literal expressions in doc attributes on macro calls - #160904

Merged
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
mejrs:doc_feature_gating
Oct 10, 2026
Merged

rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
mejrs:doc_feature_gating

Conversation

@mejrs

@mejrs mejrs commented Aug 11, 2026 •

Copy link
Copy Markdown
Member

View all comments

Recently I discovered that, since Rust 1.94, doc attributes on macro invocations can have arbitrary expressions in them:

// accidentally stabilized in 1.94
#[doc = concat!("", "")]
#[doc = {
    let a = 1;
    let b = 1;
    let sum = a + b;
    assert_eq!(sum, 2);
}]
println!();

As part of the attribute parsing rework this was accidentally allowed. Note that doc attributes (or any doc comment) on macro invocations do nothing, because documentation for macro invocations is not rendered - this emits a lint saying macros must produce doc comments as part of their expansion.

With this PR, it now emits a FCW, like #57571. As this is so niche it's probable this could go straight to an error but there's quite a crater queue so I'd rather do this now and try turning it into an error later.

error: invalid expression in `doc` attribute on macro invocation
  --> $DIR/attr-on-mac-call.rs:115:13
   |
LL |     #[doc = concat!("", "")]
   |     --------^^^^^^^^^^^^^^^^^^^^^^^- help: remove the attribute
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
   = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default

error: invalid expression in `doc` attribute on macro invocation
  --> $DIR/attr-on-mac-call.rs:118:13
   |
LL |        #[doc = {
   |  ______-       ^
   | | _____________|
LL | ||         let a = 1;
LL | ||         let b = 1;
LL | ||         let sum = a + b;
LL | ||         assert_eq!(sum, 2);
LL | ||     }]
   | ||_____^- help: remove the attribute
   |  |_____|
   |
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>

error: aborting due to 7 previous errors; 30 warnings emitted

Note that #[doc = mac!()] is included in this. While this is allowed everywhere else as normally attribute parsing only sees it after its expansion, it is not expanded here, but we do need to check attributes here since we can't check them later as they're lost by then.

#[doc = mac!()] // this would be expanded second, but any remaining attributes
                // on macro invocations are dropped before they are expanded.
println!(); // this is expanded first

I don't think it is worth trying to make particular case work - this would involve checking that the expression would expand to a string literal:

  • These expansions have a defined order (see also @petrochenkov's comment at #t-compiler > attribute parsing rework @ 💬)
  • so it would be quite a hack to check whether the expression would expand to a string literal
  • changing macro expansion order might be possible but is a big can of worms and undesirable.
  • it would serve no use case, as the attribute is dropped regardless

This change would also make it consistent with all other key-value attributes. For an example, the following are allowed

#[deprecated = "foo"] // just `unused_attributes` warning
println!();
    
#[deprecated = concat!()]
struct Foo;

but this is not:

#[deprecated = concat!()]
println!();
error: attribute value must be a literal
 --> src/main.rs:2:20
  |
2 | #[deprecated = concat!()]

r? @JonathanBrouwer

@rustbot rustbot added A-attributes Area: Attributes (`#[…]`, `#![…]`) S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 11, 2026
@mejrs
mejrs force-pushed the doc_feature_gating branch from 63a2f0f to f705d49 Compare August 11, 2026 12:07
@rust-log-analyzer

This comment has been minimized.

@mejrs
mejrs force-pushed the doc_feature_gating branch from f705d49 to 11ac310 Compare August 12, 2026 09:40
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@mejrs
mejrs force-pushed the doc_feature_gating branch from 478a22c to 65407a3 Compare August 13, 2026 12:12
@rust-log-analyzer

This comment has been minimized.

@mejrs
mejrs force-pushed the doc_feature_gating branch from 65407a3 to 9b15145 Compare August 14, 2026 21:21
@rust-log-analyzer

This comment has been minimized.

@mejrs
mejrs force-pushed the doc_feature_gating branch from 9b15145 to dd5debd Compare August 15, 2026 17:07
@rust-log-analyzer

This comment has been minimized.

@mejrs
mejrs force-pushed the doc_feature_gating branch from dd5debd to 1953f77 Compare August 16, 2026 14:37
@rust-log-analyzer

This comment has been minimized.

@mejrs
mejrs force-pushed the doc_feature_gating branch from 1953f77 to 3888e00 Compare August 16, 2026 15:34
@mejrs
mejrs marked this pull request as ready for review August 16, 2026 15:42
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 16, 2026
@rustbot

rustbot commented Aug 16, 2026

Copy link
Copy Markdown
Collaborator

Some changes occurred in compiler/rustc_attr_parsing

cc @jdonszelmann, @JonathanBrouwer

These commits modify the Cargo.lock file. Unintentional changes to Cargo.lock can be introduced when switching branches and rebasing PRs.

If this was unintentional then you should revert the changes before this PR is merged.
Otherwise, you can ignore this comment.

@rustbot rustbot removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Aug 16, 2026
@mejrs
mejrs force-pushed the doc_feature_gating branch from 3888e00 to 8c0900d Compare August 19, 2026 22:26
@rustbot

This comment has been minimized.

@mejrs
mejrs force-pushed the doc_feature_gating branch from 8c0900d to 9fdd707 Compare August 19, 2026 23:11
@mejrs mejrs changed the title rework handling of doc attributes on macro calls FCW on expressions in doc attributes on macro calls Aug 19, 2026
@mejrs mejrs added the I-lang-nominated Nominated for discussion during a lang team meeting. label Aug 19, 2026
@mejrs

mejrs commented Aug 19, 2026

Copy link
Copy Markdown
Member Author

@JonathanBrouwer this is ready for review now

@JonathanBrouwer JonathanBrouwer left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r=me after lang FCP
Crater results look reasonable to me, only 1 crate broken, which is already fixed by @mejrs (thanks!) in Martan03/termint#13

View changes since this review

@JonathanBrouwer JonathanBrouwer added S-waiting-on-t-lang Status: Awaiting decision from T-lang and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 30, 2026
@scottmcm

scottmcm commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

Always happy to go straight to error for things that are clearly bugs that weren't supposed to work, so glad crater said we could :)

@rust-rfcbot rust-rfcbot added final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. and removed proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. labels Sep 30, 2026
@rust-rfcbot

Copy link
Copy Markdown
Collaborator

🔔 This is now entering its final comment period, as per the review above. 🔔

@traviscross traviscross removed I-lang-nominated Nominated for discussion during a lang team meeting. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang labels Sep 30, 2026
@mejrs
mejrs force-pushed the doc_feature_gating branch from 1c5fe3f to 6539813 Compare October 2, 2026 19:24
@rustbot

rustbot commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@rust-rfcbot rust-rfcbot added finished-final-comment-period The final comment period is finished for this PR / Issue. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. to-announce Announce this issue on triage meeting and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Oct 10, 2026
@rust-rfcbot

Copy link
Copy Markdown
Collaborator

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

@JonathanBrouwer

Copy link
Copy Markdown
Member

@bors r+ rollup

@rust-bors

rust-bors Bot commented Oct 10, 2026

Copy link
Copy Markdown
Contributor

📋 This PR cannot be approved because it currently has the following label: S-waiting-on-t-lang.

@JonathanBrouwer JonathanBrouwer removed the S-waiting-on-t-lang Status: Awaiting decision from T-lang label Oct 10, 2026
@JonathanBrouwer

Copy link
Copy Markdown
Member

@bors r+ rollup

@rust-bors

rust-bors Bot commented Oct 10, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 6539813 has been approved by JonathanBrouwer

It is now in the queue for this repository.

@rust-bors rust-bors Bot 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 Oct 10, 2026
rust-bors Bot pushed a commit that referenced this pull request Oct 10, 2026
…uwer

Rollup of 3 pull requests

Successful merges:

 - #160877 (rustc: Stabilize the WebAssembly `wide-arithmetic` feature)
 - #160904 (Error on non-literal expressions in doc attributes on macro calls)
 - #164091 (Triagebot: Subscribe myself to AST/HIR size changes)
@rust-bors
rust-bors Bot merged commit 1ed2494 into rust-lang:main Oct 10, 2026
14 checks passed
@rustbot rustbot added this to the 1.101.0 milestone Oct 10, 2026
rust-bors Bot pushed a commit that referenced this pull request Oct 10, 2026
Rollup merge of #160904 - mejrs:doc_feature_gating, r=JonathanBrouwer

Error on non-literal expressions in doc attributes on macro calls

Recently I discovered that, since Rust 1.94, doc attributes on macro invocations can have arbitrary expressions in them:

```rust
// accidentally stabilized in 1.94
#[doc = concat!("", "")]
#[doc = {
    let a = 1;
    let b = 1;
    let sum = a + b;
    assert_eq!(sum, 2);
}]
println!();
```

As part of the attribute parsing rework this was accidentally allowed. Note that doc attributes (or any doc comment) on macro invocations do nothing, because documentation for macro invocations is not rendered - this emits a lint saying macros must produce doc comments as part of their expansion.

With this PR, it now emits a FCW, like #57571. As this is so niche it's probable this could go straight to an error but there's quite a crater queue so I'd rather do this now and try turning it into an error later.
```
error: invalid expression in `doc` attribute on macro invocation
  --> $DIR/attr-on-mac-call.rs:115:13
   |
LL |     #[doc = concat!("", "")]
   |     --------^^^^^^^^^^^^^^^^^^^^^^^- help: remove the attribute
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #57571 <#57571>
   = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default

error: invalid expression in `doc` attribute on macro invocation
  --> $DIR/attr-on-mac-call.rs:118:13
   |
LL |        #[doc = {
   |  ______-       ^
   | | _____________|
LL | ||         let a = 1;
LL | ||         let b = 1;
LL | ||         let sum = a + b;
LL | ||         assert_eq!(sum, 2);
LL | ||     }]
   | ||_____^- help: remove the attribute
   |  |_____|
   |
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #57571 <#57571>

error: aborting due to 7 previous errors; 30 warnings emitted
```

Note that `#[doc = mac!()]` is included in this. While this is allowed everywhere else as normally attribute parsing only sees it after its expansion, it is not expanded here, but we do need to check attributes here since we can't check them later as they're lost by then.

```rust
#[doc = mac!()] // this would be expanded second, but any remaining attributes
                // on macro invocations are dropped before they are expanded.
println!(); // this is expanded first
```

I don't think it is worth trying to make particular case work - this would involve checking that the expression would expand to a string literal:
- These expansions have a defined order (see also @petrochenkov's comment at [#t-compiler > attribute parsing rework @ 💬](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/attribute.20parsing.20rework/near/615858530))
- so it would be quite a hack to check whether the expression would expand to a string literal
- changing macro expansion order might be possible but is a big can of worms and undesirable.
-  it would serve no use case, as the attribute is dropped regardless

This change would also make it consistent with all other key-value attributes. For an example, the following are allowed

```rust
#[deprecated = "foo"] // just `unused_attributes` warning
println!();

#[deprecated = concat!()]
struct Foo;
```
but this is not:
```rust
#[deprecated = concat!()]
println!();
```
```
error: attribute value must be a literal
 --> src/main.rs:2:20
  |
2 | #[deprecated = concat!()]
```

r? @JonathanBrouwer
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. finished-final-comment-period The final comment period is finished for this PR / Issue. I-lang-radar Items that are on lang's radar and will need eventual work or consideration. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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.

9 participants