Replace check_attr_crate_level with check_target for #[doc] - #161521

Draft
evavh wants to merge 4 commits into
rust-lang:mainfrom
evavh:doc-crate-level-check
Draft

Replace check_attr_crate_level with check_target for #[doc]#161521
evavh wants to merge 4 commits into
rust-lang:mainfrom
evavh:doc-crate-level-check

Conversation

@evavh

Copy link
Copy Markdown
Contributor

A small change as part of the target checking refactor for #[doc] attribute parsing.

r? @JonathanBrouwer

@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred in compiler/rustc_attr_parsing

cc @jdonszelmann, @JonathanBrouwer

@rustbotrustbot 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 Aug 22, 2026
return;
}
cx.check_target(
&sym::no_crate_inject.to_string(),

@mejrsmejrsAug 22, 2026

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.

Suggested change
&sym::no_crate_inject.to_string(),
sym::no_crate_inject.as_str()

View changes since the review

return;
}
cx.check_target(
&s.to_string(),

@mejrsmejrsAug 22, 2026

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.

Suggested change
&s.to_string(),
s.as_str(),

View changes since the review

@rust-log-analyzer

This comment has been minimized.

return;
}
cx.check_target(
concat!("(", stringify!($ident), ")"),

@JonathanBrouwerJonathanBrouwerAug 22, 2026

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.

Could you make tests for these cases if they don't already exist? I'd expect some stderr changes in this PR

View changes since the review

@rustbotrustbot 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 Aug 22, 2026
@rustbot

Copy link
Copy Markdown
Collaborator

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

@evavh

Copy link
Copy Markdown
ContributorAuthor

I tried to add tests for the crate-level attribute checks, but I'm running into an interesting problem: there seems to be no way for the target check to fail. The possible ways for a crate-level attribute to be applied to a non-crate target (that I can think of) are:

  1. A #[doc(CRATE_LEVEL_ONLY)] attribute applied to an item: this outputs the error crate-level attribute should be an inner attribute: add an exclamation mark
  2. A #![doc(CRATE_LEVEL_ONLY)] attribute applied to an item (ie not at the top of the file): the error is an inner attribute is not permitted in this context

In both cases the compiler throws an error before we even reach the target checking code in doc.rs. The same applies to doc attribute arguments that shouldn't be used crate-level, like fake_variadic. It seems the distinction between inner (#!) and outer (#) attributes is enough to guard against wrong crate/non-crate targets.

The test I wrote covers all doc attribute arguments that check whether they are applied at crate level, and they all throw errors in earlier parsing steps. What do we do with the target checking code that does nothing?

@rust-log-analyzer

This comment has been minimized.

@rust-bors

This comment has been minimized.

@JonathanBrouwerJonathanBrouwer 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 Aug 30, 2026
@JonathanBrouwer

JonathanBrouwer commented Aug 30, 2026

Copy link
Copy Markdown
Member

@evavh I took a random crate-level doc attribute, and applied it to a function:

#[doc(html_no_source)]fntest1(){}fntest2(){#![doc(html_no_source)]}

In both cases this produces "this attribute can only be applied at the crate level"
This diagnostic is produced in target checking, so if you hit it you are doing target checking somewhere:

pub(crate)fncheck_crate_level(cx:&mutAcceptContext<'_,'sess>,warn:bool){

The diagnostic "an inner attribute is not permitted in this context" is produced when you apply inner attributes to an item that doesn't support inner attributes, such as a struct, and is indeed produced in the parser

structTest{#![doc(html_no_source)]}

@rustbot author

@rustbotrustbot 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 Aug 30, 2026
@evavh
evavhforce-pushed the doc-crate-level-check branch from 6c2968e to 7a056e3CompareAugust 31, 2026 14:31
@rustbot

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-log-analyzer

This comment has been minimized.

@mejrsmejrs added needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. needs-crater This change needs a crater run to check for possible breakage in the ecosystem. labels Aug 31, 2026
@mejrs

mejrs commented Aug 31, 2026

Copy link
Copy Markdown
Member

These are breaking changes, so they will need a crater run. Alternatively, you could refactor this in a way that doesn't change behavior.

@evavh
evavh marked this pull request as draft September 1, 2026 11:56
@evavh

evavh commented Sep 1, 2026

Copy link
Copy Markdown
ContributorAuthor

Turns out I was very confused by the "new" diagnostic emitted by check_crate_level called by AttributeParser::check_target. The target checking is still happening correctly with this refactor, though I do think the diagnostic has become worse.

I tried changing the diagnostic in check_crate_level, but that broke all kinds of unrelated tests.

As for breaking changes, using a crate-level doc attribute on the wrong target now emits an ERROR instead of a WARN.

@rustbot ready

@rustbotrustbot 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 1, 2026
}
cx.check_target(
sym::no_crate_inject.as_str(),
&AllowedTargets::AllowList(&[Allow(Target::Crate)]),

@JonathanBrouwerJonathanBrouwerSep 1, 2026

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.

If you use AllowListWarnRest instead of AllowList it will warn instead of erroring.
Then to generate the right lint INVALID_DOC_ATTRIBUTES instead of the default UNUSED_ATTRIBUTES we should add a special case here

View changes since the review

//! This is not an official rust crate

#[doc(rust_logo)]
//~^ WARN this attribute can only be applied at the crate level

@JonathanBrouwerJonathanBrouwerSep 1, 2026

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.

Is there a reason you removed this from the test?
This is here to show that this doc attribute, incorrectly, is not feature gated

View changes since the review

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-2 failed! Check out the build log: (web)(plain enhanced)(plain)

Click to see the possible cause of the failure (guessed by this bot)

This error was generated by the lint-docs tool.
This tool extracts documentation for lints from the source code and places
them in the rustc book. See the declare_lint! documentation
https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/macro.declare_lint.html
for an example of the format of documentation this tool expects.
To re-run these tests, run: ./x.py test --keep-stage=0 src/tools/lint-docs
The --keep-stage flag should be used if you have already built the compiler
and are only modifying the doc comments to avoid rebuilding the compiler.
Bootstrap failed while executing `--stage 2 test --skip tidy --skip intrinsic-test --skip src/tools/rust-analyzer --skip tests --skip library --skip tidyselftest`
Currently active steps:
test::LintDocs { build_compiler: Compiler { stage: 1, host: aarch64-unknown-linux-gnu, forced_compiler: false }, target: aarch64-unknown-linux-gnu } at src/bootstrap/src/core/build_steps/test.rs:4173
doc::RustcBook { build_compiler: Compiler { stage: 1, host: aarch64-unknown-linux-gnu, forced_compiler: false }, target: aarch64-unknown-linux-gnu, validate: true } at src/bootstrap/src/core/build_steps/test.rs:4186
Command `/checkout/obj/build/aarch64-unknown-linux-gnu/stage1-tools-bin/lint-docs --build-rustc-stage 1 --src /checkout/compiler --out /checkout/obj/build/aarch64-unknown-linux-gnu/md-doc/rustc/src/lints --rustc /checkout/obj/build/aarch64-unknown-linux-gnu/stage1/bin/rustc --rustc-target aarch64-unknown-linux-gnu --validate` failed with exit code 1
Created at: src/bootstrap/src/core/build_steps/tool.rs:1627:23
Executed at: src/bootstrap/src/core/build_steps/doc.rs:1465:13
Command has failed. Rerun with -v to see more details.
Build completed unsuccessfully in 0:39:24
local time: Tue Sep 1 12:58:18 UTC 2026
network time: Tue, 01 Sep 2026 12:58:18 GMT
##[error]Process completed with exit code 1.
##[group]Run echo "disk usage:"

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributesArea: Attributes (`#[…]`, `#![…]`)needs-craterThis change needs a crater run to check for possible breakage in the ecosystem.needs-fcpThis change is insta-stable, or significant enough to need a team FCP to proceed.S-waiting-on-reviewStatus: Awaiting review from the assignee but also interested parties.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@evavh@rustbot@rust-log-analyzer@JonathanBrouwer@mejrs
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Replace check_attr_crate_level with check_target for #[doc] - #161521

Draft
evavh wants to merge 4 commits into
rust-lang:mainfrom
evavh:doc-crate-level-check
Draft

Replace check_attr_crate_level with check_target for #[doc]#161521
evavh wants to merge 4 commits into
rust-lang:mainfrom
evavh:doc-crate-level-check

Conversation

@evavh

Copy link
Copy Markdown
Contributor

A small change as part of the target checking refactor for #[doc] attribute parsing.

r? @JonathanBrouwer

@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred in compiler/rustc_attr_parsing

cc @jdonszelmann, @JonathanBrouwer

@rustbotrustbot 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 Aug 22, 2026
return;
}
cx.check_target(
&sym::no_crate_inject.to_string(),

@mejrsmejrsAug 22, 2026

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.

Suggested change
&sym::no_crate_inject.to_string(),
sym::no_crate_inject.as_str()

View changes since the review

return;
}
cx.check_target(
&s.to_string(),

@mejrsmejrsAug 22, 2026

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.

Suggested change
&s.to_string(),
s.as_str(),

View changes since the review

@rust-log-analyzer

This comment has been minimized.

return;
}
cx.check_target(
concat!("(", stringify!($ident), ")"),

@JonathanBrouwerJonathanBrouwerAug 22, 2026

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.

Could you make tests for these cases if they don't already exist? I'd expect some stderr changes in this PR

View changes since the review

@rustbotrustbot 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 Aug 22, 2026
@rustbot

Copy link
Copy Markdown
Collaborator

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

@evavh

Copy link
Copy Markdown
ContributorAuthor

I tried to add tests for the crate-level attribute checks, but I'm running into an interesting problem: there seems to be no way for the target check to fail. The possible ways for a crate-level attribute to be applied to a non-crate target (that I can think of) are:

  1. A #[doc(CRATE_LEVEL_ONLY)] attribute applied to an item: this outputs the error crate-level attribute should be an inner attribute: add an exclamation mark
  2. A #![doc(CRATE_LEVEL_ONLY)] attribute applied to an item (ie not at the top of the file): the error is an inner attribute is not permitted in this context

In both cases the compiler throws an error before we even reach the target checking code in doc.rs. The same applies to doc attribute arguments that shouldn't be used crate-level, like fake_variadic. It seems the distinction between inner (#!) and outer (#) attributes is enough to guard against wrong crate/non-crate targets.

The test I wrote covers all doc attribute arguments that check whether they are applied at crate level, and they all throw errors in earlier parsing steps. What do we do with the target checking code that does nothing?

@rust-log-analyzer

This comment has been minimized.

@rust-bors

This comment has been minimized.

@JonathanBrouwerJonathanBrouwer 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 Aug 30, 2026
@JonathanBrouwer

JonathanBrouwer commented Aug 30, 2026

Copy link
Copy Markdown
Member

@evavh I took a random crate-level doc attribute, and applied it to a function:

#[doc(html_no_source)]fntest1(){}fntest2(){#![doc(html_no_source)]}

In both cases this produces "this attribute can only be applied at the crate level"
This diagnostic is produced in target checking, so if you hit it you are doing target checking somewhere:

pub(crate)fncheck_crate_level(cx:&mutAcceptContext<'_,'sess>,warn:bool){

The diagnostic "an inner attribute is not permitted in this context" is produced when you apply inner attributes to an item that doesn't support inner attributes, such as a struct, and is indeed produced in the parser

structTest{#![doc(html_no_source)]}

@rustbot author

@rustbotrustbot 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 Aug 30, 2026
@evavh
evavhforce-pushed the doc-crate-level-check branch from 6c2968e to 7a056e3CompareAugust 31, 2026 14:31
@rustbot

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-log-analyzer

This comment has been minimized.

@mejrsmejrs added needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. needs-crater This change needs a crater run to check for possible breakage in the ecosystem. labels Aug 31, 2026
@mejrs

mejrs commented Aug 31, 2026

Copy link
Copy Markdown
Member

These are breaking changes, so they will need a crater run. Alternatively, you could refactor this in a way that doesn't change behavior.

@evavh
evavh marked this pull request as draft September 1, 2026 11:56
@evavh

evavh commented Sep 1, 2026

Copy link
Copy Markdown
ContributorAuthor

Turns out I was very confused by the "new" diagnostic emitted by check_crate_level called by AttributeParser::check_target. The target checking is still happening correctly with this refactor, though I do think the diagnostic has become worse.

I tried changing the diagnostic in check_crate_level, but that broke all kinds of unrelated tests.

As for breaking changes, using a crate-level doc attribute on the wrong target now emits an ERROR instead of a WARN.

@rustbot ready

@rustbotrustbot 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 1, 2026
}
cx.check_target(
sym::no_crate_inject.as_str(),
&AllowedTargets::AllowList(&[Allow(Target::Crate)]),

@JonathanBrouwerJonathanBrouwerSep 1, 2026

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.

If you use AllowListWarnRest instead of AllowList it will warn instead of erroring.
Then to generate the right lint INVALID_DOC_ATTRIBUTES instead of the default UNUSED_ATTRIBUTES we should add a special case here

View changes since the review

//! This is not an official rust crate

#[doc(rust_logo)]
//~^ WARN this attribute can only be applied at the crate level

@JonathanBrouwerJonathanBrouwerSep 1, 2026

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.

Is there a reason you removed this from the test?
This is here to show that this doc attribute, incorrectly, is not feature gated

View changes since the review

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-2 failed! Check out the build log: (web)(plain enhanced)(plain)

Click to see the possible cause of the failure (guessed by this bot)

This error was generated by the lint-docs tool.
This tool extracts documentation for lints from the source code and places
them in the rustc book. See the declare_lint! documentation
https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/macro.declare_lint.html
for an example of the format of documentation this tool expects.
To re-run these tests, run: ./x.py test --keep-stage=0 src/tools/lint-docs
The --keep-stage flag should be used if you have already built the compiler
and are only modifying the doc comments to avoid rebuilding the compiler.
Bootstrap failed while executing `--stage 2 test --skip tidy --skip intrinsic-test --skip src/tools/rust-analyzer --skip tests --skip library --skip tidyselftest`
Currently active steps:
test::LintDocs { build_compiler: Compiler { stage: 1, host: aarch64-unknown-linux-gnu, forced_compiler: false }, target: aarch64-unknown-linux-gnu } at src/bootstrap/src/core/build_steps/test.rs:4173
doc::RustcBook { build_compiler: Compiler { stage: 1, host: aarch64-unknown-linux-gnu, forced_compiler: false }, target: aarch64-unknown-linux-gnu, validate: true } at src/bootstrap/src/core/build_steps/test.rs:4186
Command `/checkout/obj/build/aarch64-unknown-linux-gnu/stage1-tools-bin/lint-docs --build-rustc-stage 1 --src /checkout/compiler --out /checkout/obj/build/aarch64-unknown-linux-gnu/md-doc/rustc/src/lints --rustc /checkout/obj/build/aarch64-unknown-linux-gnu/stage1/bin/rustc --rustc-target aarch64-unknown-linux-gnu --validate` failed with exit code 1
Created at: src/bootstrap/src/core/build_steps/tool.rs:1627:23
Executed at: src/bootstrap/src/core/build_steps/doc.rs:1465:13
Command has failed. Rerun with -v to see more details.
Build completed unsuccessfully in 0:39:24
local time: Tue Sep 1 12:58:18 UTC 2026
network time: Tue, 01 Sep 2026 12:58:18 GMT
##[error]Process completed with exit code 1.
##[group]Run echo "disk usage:"

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributesArea: Attributes (`#[…]`, `#![…]`)needs-craterThis change needs a crater run to check for possible breakage in the ecosystem.needs-fcpThis change is insta-stable, or significant enough to need a team FCP to proceed.S-waiting-on-reviewStatus: Awaiting review from the assignee but also interested parties.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@evavh@rustbot@rust-log-analyzer@JonathanBrouwer@mejrs
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Replace check_attr_crate_level with check_target for #[doc] - #161521

Draft
evavh wants to merge 4 commits into
rust-lang:mainfrom
evavh:doc-crate-level-check
Draft

Replace check_attr_crate_level with check_target for #[doc]#161521
evavh wants to merge 4 commits into
rust-lang:mainfrom
evavh:doc-crate-level-check

Conversation

@evavh

Copy link
Copy Markdown
Contributor

A small change as part of the target checking refactor for #[doc] attribute parsing.

r? @JonathanBrouwer

@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred in compiler/rustc_attr_parsing

cc @jdonszelmann, @JonathanBrouwer

@rustbotrustbot 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 Aug 22, 2026
return;
}
cx.check_target(
&sym::no_crate_inject.to_string(),

@mejrsmejrsAug 22, 2026

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.

Suggested change
&sym::no_crate_inject.to_string(),
sym::no_crate_inject.as_str()

View changes since the review

return;
}
cx.check_target(
&s.to_string(),

@mejrsmejrsAug 22, 2026

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.

Suggested change
&s.to_string(),
s.as_str(),

View changes since the review

@rust-log-analyzer

This comment has been minimized.

return;
}
cx.check_target(
concat!("(", stringify!($ident), ")"),

@JonathanBrouwerJonathanBrouwerAug 22, 2026

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.

Could you make tests for these cases if they don't already exist? I'd expect some stderr changes in this PR

View changes since the review

@rustbotrustbot 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 Aug 22, 2026
@rustbot

Copy link
Copy Markdown
Collaborator

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

@evavh

Copy link
Copy Markdown
ContributorAuthor

I tried to add tests for the crate-level attribute checks, but I'm running into an interesting problem: there seems to be no way for the target check to fail. The possible ways for a crate-level attribute to be applied to a non-crate target (that I can think of) are:

  1. A #[doc(CRATE_LEVEL_ONLY)] attribute applied to an item: this outputs the error crate-level attribute should be an inner attribute: add an exclamation mark
  2. A #![doc(CRATE_LEVEL_ONLY)] attribute applied to an item (ie not at the top of the file): the error is an inner attribute is not permitted in this context

In both cases the compiler throws an error before we even reach the target checking code in doc.rs. The same applies to doc attribute arguments that shouldn't be used crate-level, like fake_variadic. It seems the distinction between inner (#!) and outer (#) attributes is enough to guard against wrong crate/non-crate targets.

The test I wrote covers all doc attribute arguments that check whether they are applied at crate level, and they all throw errors in earlier parsing steps. What do we do with the target checking code that does nothing?

@rust-log-analyzer

This comment has been minimized.

@rust-bors

This comment has been minimized.

@JonathanBrouwerJonathanBrouwer 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 Aug 30, 2026
@JonathanBrouwer

JonathanBrouwer commented Aug 30, 2026

Copy link
Copy Markdown
Member

@evavh I took a random crate-level doc attribute, and applied it to a function:

#[doc(html_no_source)]fntest1(){}fntest2(){#![doc(html_no_source)]}

In both cases this produces "this attribute can only be applied at the crate level"
This diagnostic is produced in target checking, so if you hit it you are doing target checking somewhere:

pub(crate)fncheck_crate_level(cx:&mutAcceptContext<'_,'sess>,warn:bool){

The diagnostic "an inner attribute is not permitted in this context" is produced when you apply inner attributes to an item that doesn't support inner attributes, such as a struct, and is indeed produced in the parser

structTest{#![doc(html_no_source)]}

@rustbot author

@rustbotrustbot 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 Aug 30, 2026
@evavh
evavhforce-pushed the doc-crate-level-check branch from 6c2968e to 7a056e3CompareAugust 31, 2026 14:31
@rustbot

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-log-analyzer

This comment has been minimized.

@mejrsmejrs added needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. needs-crater This change needs a crater run to check for possible breakage in the ecosystem. labels Aug 31, 2026
@mejrs

mejrs commented Aug 31, 2026

Copy link
Copy Markdown
Member

These are breaking changes, so they will need a crater run. Alternatively, you could refactor this in a way that doesn't change behavior.

@evavh
evavh marked this pull request as draft September 1, 2026 11:56
@evavh

evavh commented Sep 1, 2026

Copy link
Copy Markdown
ContributorAuthor

Turns out I was very confused by the "new" diagnostic emitted by check_crate_level called by AttributeParser::check_target. The target checking is still happening correctly with this refactor, though I do think the diagnostic has become worse.

I tried changing the diagnostic in check_crate_level, but that broke all kinds of unrelated tests.

As for breaking changes, using a crate-level doc attribute on the wrong target now emits an ERROR instead of a WARN.

@rustbot ready

@rustbotrustbot 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 1, 2026
}
cx.check_target(
sym::no_crate_inject.as_str(),
&AllowedTargets::AllowList(&[Allow(Target::Crate)]),

@JonathanBrouwerJonathanBrouwerSep 1, 2026

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.

If you use AllowListWarnRest instead of AllowList it will warn instead of erroring.
Then to generate the right lint INVALID_DOC_ATTRIBUTES instead of the default UNUSED_ATTRIBUTES we should add a special case here

View changes since the review

//! This is not an official rust crate

#[doc(rust_logo)]
//~^ WARN this attribute can only be applied at the crate level

@JonathanBrouwerJonathanBrouwerSep 1, 2026

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.

Is there a reason you removed this from the test?
This is here to show that this doc attribute, incorrectly, is not feature gated

View changes since the review

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-2 failed! Check out the build log: (web)(plain enhanced)(plain)

Click to see the possible cause of the failure (guessed by this bot)

This error was generated by the lint-docs tool.
This tool extracts documentation for lints from the source code and places
them in the rustc book. See the declare_lint! documentation
https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/macro.declare_lint.html
for an example of the format of documentation this tool expects.
To re-run these tests, run: ./x.py test --keep-stage=0 src/tools/lint-docs
The --keep-stage flag should be used if you have already built the compiler
and are only modifying the doc comments to avoid rebuilding the compiler.
Bootstrap failed while executing `--stage 2 test --skip tidy --skip intrinsic-test --skip src/tools/rust-analyzer --skip tests --skip library --skip tidyselftest`
Currently active steps:
test::LintDocs { build_compiler: Compiler { stage: 1, host: aarch64-unknown-linux-gnu, forced_compiler: false }, target: aarch64-unknown-linux-gnu } at src/bootstrap/src/core/build_steps/test.rs:4173
doc::RustcBook { build_compiler: Compiler { stage: 1, host: aarch64-unknown-linux-gnu, forced_compiler: false }, target: aarch64-unknown-linux-gnu, validate: true } at src/bootstrap/src/core/build_steps/test.rs:4186
Command `/checkout/obj/build/aarch64-unknown-linux-gnu/stage1-tools-bin/lint-docs --build-rustc-stage 1 --src /checkout/compiler --out /checkout/obj/build/aarch64-unknown-linux-gnu/md-doc/rustc/src/lints --rustc /checkout/obj/build/aarch64-unknown-linux-gnu/stage1/bin/rustc --rustc-target aarch64-unknown-linux-gnu --validate` failed with exit code 1
Created at: src/bootstrap/src/core/build_steps/tool.rs:1627:23
Executed at: src/bootstrap/src/core/build_steps/doc.rs:1465:13
Command has failed. Rerun with -v to see more details.
Build completed unsuccessfully in 0:39:24
local time: Tue Sep 1 12:58:18 UTC 2026
network time: Tue, 01 Sep 2026 12:58:18 GMT
##[error]Process completed with exit code 1.
##[group]Run echo "disk usage:"

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributesArea: Attributes (`#[…]`, `#![…]`)needs-craterThis change needs a crater run to check for possible breakage in the ecosystem.needs-fcpThis change is insta-stable, or significant enough to need a team FCP to proceed.S-waiting-on-reviewStatus: Awaiting review from the assignee but also interested parties.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@evavh@rustbot@rust-log-analyzer@JonathanBrouwer@mejrs
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Replace check_attr_crate_level with check_target for #[doc] - #161521

Draft
evavh wants to merge 4 commits into
rust-lang:mainfrom
evavh:doc-crate-level-check
Draft

Replace check_attr_crate_level with check_target for #[doc]#161521
evavh wants to merge 4 commits into
rust-lang:mainfrom
evavh:doc-crate-level-check

Conversation

@evavh

Copy link
Copy Markdown
Contributor

A small change as part of the target checking refactor for #[doc] attribute parsing.

r? @JonathanBrouwer

@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred in compiler/rustc_attr_parsing

cc @jdonszelmann, @JonathanBrouwer

@rustbotrustbot 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 Aug 22, 2026
return;
}
cx.check_target(
&sym::no_crate_inject.to_string(),

@mejrsmejrsAug 22, 2026

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.

Suggested change
&sym::no_crate_inject.to_string(),
sym::no_crate_inject.as_str()

View changes since the review

return;
}
cx.check_target(
&s.to_string(),

@mejrsmejrsAug 22, 2026

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.

Suggested change
&s.to_string(),
s.as_str(),

View changes since the review

@rust-log-analyzer

This comment has been minimized.

return;
}
cx.check_target(
concat!("(", stringify!($ident), ")"),

@JonathanBrouwerJonathanBrouwerAug 22, 2026

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.

Could you make tests for these cases if they don't already exist? I'd expect some stderr changes in this PR

View changes since the review

@rustbotrustbot 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 Aug 22, 2026
@rustbot

Copy link
Copy Markdown
Collaborator

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

@evavh

Copy link
Copy Markdown
ContributorAuthor

I tried to add tests for the crate-level attribute checks, but I'm running into an interesting problem: there seems to be no way for the target check to fail. The possible ways for a crate-level attribute to be applied to a non-crate target (that I can think of) are:

  1. A #[doc(CRATE_LEVEL_ONLY)] attribute applied to an item: this outputs the error crate-level attribute should be an inner attribute: add an exclamation mark
  2. A #![doc(CRATE_LEVEL_ONLY)] attribute applied to an item (ie not at the top of the file): the error is an inner attribute is not permitted in this context

In both cases the compiler throws an error before we even reach the target checking code in doc.rs. The same applies to doc attribute arguments that shouldn't be used crate-level, like fake_variadic. It seems the distinction between inner (#!) and outer (#) attributes is enough to guard against wrong crate/non-crate targets.

The test I wrote covers all doc attribute arguments that check whether they are applied at crate level, and they all throw errors in earlier parsing steps. What do we do with the target checking code that does nothing?

@rust-log-analyzer

This comment has been minimized.

@rust-bors

This comment has been minimized.

@JonathanBrouwerJonathanBrouwer 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 Aug 30, 2026
@JonathanBrouwer

JonathanBrouwer commented Aug 30, 2026

Copy link
Copy Markdown
Member

@evavh I took a random crate-level doc attribute, and applied it to a function:

#[doc(html_no_source)]fntest1(){}fntest2(){#![doc(html_no_source)]}

In both cases this produces "this attribute can only be applied at the crate level"
This diagnostic is produced in target checking, so if you hit it you are doing target checking somewhere:

pub(crate)fncheck_crate_level(cx:&mutAcceptContext<'_,'sess>,warn:bool){

The diagnostic "an inner attribute is not permitted in this context" is produced when you apply inner attributes to an item that doesn't support inner attributes, such as a struct, and is indeed produced in the parser

structTest{#![doc(html_no_source)]}

@rustbot author

@rustbotrustbot 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 Aug 30, 2026
@evavh
evavhforce-pushed the doc-crate-level-check branch from 6c2968e to 7a056e3CompareAugust 31, 2026 14:31
@rustbot

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-log-analyzer

This comment has been minimized.

@mejrsmejrs added needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. needs-crater This change needs a crater run to check for possible breakage in the ecosystem. labels Aug 31, 2026
@mejrs

mejrs commented Aug 31, 2026

Copy link
Copy Markdown
Member

These are breaking changes, so they will need a crater run. Alternatively, you could refactor this in a way that doesn't change behavior.

@evavh
evavh marked this pull request as draft September 1, 2026 11:56
@evavh

evavh commented Sep 1, 2026

Copy link
Copy Markdown
ContributorAuthor

Turns out I was very confused by the "new" diagnostic emitted by check_crate_level called by AttributeParser::check_target. The target checking is still happening correctly with this refactor, though I do think the diagnostic has become worse.

I tried changing the diagnostic in check_crate_level, but that broke all kinds of unrelated tests.

As for breaking changes, using a crate-level doc attribute on the wrong target now emits an ERROR instead of a WARN.

@rustbot ready

@rustbotrustbot 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 1, 2026
}
cx.check_target(
sym::no_crate_inject.as_str(),
&AllowedTargets::AllowList(&[Allow(Target::Crate)]),

@JonathanBrouwerJonathanBrouwerSep 1, 2026

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.

If you use AllowListWarnRest instead of AllowList it will warn instead of erroring.
Then to generate the right lint INVALID_DOC_ATTRIBUTES instead of the default UNUSED_ATTRIBUTES we should add a special case here

View changes since the review

//! This is not an official rust crate

#[doc(rust_logo)]
//~^ WARN this attribute can only be applied at the crate level

@JonathanBrouwerJonathanBrouwerSep 1, 2026

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.

Is there a reason you removed this from the test?
This is here to show that this doc attribute, incorrectly, is not feature gated

View changes since the review

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-2 failed! Check out the build log: (web)(plain enhanced)(plain)

Click to see the possible cause of the failure (guessed by this bot)

This error was generated by the lint-docs tool.
This tool extracts documentation for lints from the source code and places
them in the rustc book. See the declare_lint! documentation
https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/macro.declare_lint.html
for an example of the format of documentation this tool expects.
To re-run these tests, run: ./x.py test --keep-stage=0 src/tools/lint-docs
The --keep-stage flag should be used if you have already built the compiler
and are only modifying the doc comments to avoid rebuilding the compiler.
Bootstrap failed while executing `--stage 2 test --skip tidy --skip intrinsic-test --skip src/tools/rust-analyzer --skip tests --skip library --skip tidyselftest`
Currently active steps:
test::LintDocs { build_compiler: Compiler { stage: 1, host: aarch64-unknown-linux-gnu, forced_compiler: false }, target: aarch64-unknown-linux-gnu } at src/bootstrap/src/core/build_steps/test.rs:4173
doc::RustcBook { build_compiler: Compiler { stage: 1, host: aarch64-unknown-linux-gnu, forced_compiler: false }, target: aarch64-unknown-linux-gnu, validate: true } at src/bootstrap/src/core/build_steps/test.rs:4186
Command `/checkout/obj/build/aarch64-unknown-linux-gnu/stage1-tools-bin/lint-docs --build-rustc-stage 1 --src /checkout/compiler --out /checkout/obj/build/aarch64-unknown-linux-gnu/md-doc/rustc/src/lints --rustc /checkout/obj/build/aarch64-unknown-linux-gnu/stage1/bin/rustc --rustc-target aarch64-unknown-linux-gnu --validate` failed with exit code 1
Created at: src/bootstrap/src/core/build_steps/tool.rs:1627:23
Executed at: src/bootstrap/src/core/build_steps/doc.rs:1465:13
Command has failed. Rerun with -v to see more details.
Build completed unsuccessfully in 0:39:24
local time: Tue Sep 1 12:58:18 UTC 2026
network time: Tue, 01 Sep 2026 12:58:18 GMT
##[error]Process completed with exit code 1.
##[group]Run echo "disk usage:"

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributesArea: Attributes (`#[…]`, `#![…]`)needs-craterThis change needs a crater run to check for possible breakage in the ecosystem.needs-fcpThis change is insta-stable, or significant enough to need a team FCP to proceed.S-waiting-on-reviewStatus: Awaiting review from the assignee but also interested parties.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@evavh@rustbot@rust-log-analyzer@JonathanBrouwer@mejrs
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Replace check_attr_crate_level with check_target for #[doc] - #161521

Draft
evavh wants to merge 4 commits into
rust-lang:mainfrom
evavh:doc-crate-level-check
Draft

Replace check_attr_crate_level with check_target for #[doc]#161521
evavh wants to merge 4 commits into
rust-lang:mainfrom
evavh:doc-crate-level-check

Conversation

@evavh

Copy link
Copy Markdown
Contributor

A small change as part of the target checking refactor for #[doc] attribute parsing.

r? @JonathanBrouwer

@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred in compiler/rustc_attr_parsing

cc @jdonszelmann, @JonathanBrouwer

@rustbotrustbot 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 Aug 22, 2026
return;
}
cx.check_target(
&sym::no_crate_inject.to_string(),

@mejrsmejrsAug 22, 2026

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.

Suggested change
&sym::no_crate_inject.to_string(),
sym::no_crate_inject.as_str()

View changes since the review

return;
}
cx.check_target(
&s.to_string(),

@mejrsmejrsAug 22, 2026

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.

Suggested change
&s.to_string(),
s.as_str(),

View changes since the review

@rust-log-analyzer

This comment has been minimized.

return;
}
cx.check_target(
concat!("(", stringify!($ident), ")"),

@JonathanBrouwerJonathanBrouwerAug 22, 2026

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.

Could you make tests for these cases if they don't already exist? I'd expect some stderr changes in this PR

View changes since the review

@rustbotrustbot 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 Aug 22, 2026
@rustbot

Copy link
Copy Markdown
Collaborator

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

@evavh

Copy link
Copy Markdown
ContributorAuthor

I tried to add tests for the crate-level attribute checks, but I'm running into an interesting problem: there seems to be no way for the target check to fail. The possible ways for a crate-level attribute to be applied to a non-crate target (that I can think of) are:

  1. A #[doc(CRATE_LEVEL_ONLY)] attribute applied to an item: this outputs the error crate-level attribute should be an inner attribute: add an exclamation mark
  2. A #![doc(CRATE_LEVEL_ONLY)] attribute applied to an item (ie not at the top of the file): the error is an inner attribute is not permitted in this context

In both cases the compiler throws an error before we even reach the target checking code in doc.rs. The same applies to doc attribute arguments that shouldn't be used crate-level, like fake_variadic. It seems the distinction between inner (#!) and outer (#) attributes is enough to guard against wrong crate/non-crate targets.

The test I wrote covers all doc attribute arguments that check whether they are applied at crate level, and they all throw errors in earlier parsing steps. What do we do with the target checking code that does nothing?

@rust-log-analyzer

This comment has been minimized.

@rust-bors

This comment has been minimized.

@JonathanBrouwerJonathanBrouwer 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 Aug 30, 2026
@JonathanBrouwer

JonathanBrouwer commented Aug 30, 2026

Copy link
Copy Markdown
Member

@evavh I took a random crate-level doc attribute, and applied it to a function:

#[doc(html_no_source)]fntest1(){}fntest2(){#![doc(html_no_source)]}

In both cases this produces "this attribute can only be applied at the crate level"
This diagnostic is produced in target checking, so if you hit it you are doing target checking somewhere:

pub(crate)fncheck_crate_level(cx:&mutAcceptContext<'_,'sess>,warn:bool){

The diagnostic "an inner attribute is not permitted in this context" is produced when you apply inner attributes to an item that doesn't support inner attributes, such as a struct, and is indeed produced in the parser

structTest{#![doc(html_no_source)]}

@rustbot author

@rustbotrustbot 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 Aug 30, 2026
@evavh
evavhforce-pushed the doc-crate-level-check branch from 6c2968e to 7a056e3CompareAugust 31, 2026 14:31
@rustbot

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-log-analyzer

This comment has been minimized.

@mejrsmejrs added needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. needs-crater This change needs a crater run to check for possible breakage in the ecosystem. labels Aug 31, 2026
@mejrs

mejrs commented Aug 31, 2026

Copy link
Copy Markdown
Member

These are breaking changes, so they will need a crater run. Alternatively, you could refactor this in a way that doesn't change behavior.

@evavh
evavh marked this pull request as draft September 1, 2026 11:56
@evavh

evavh commented Sep 1, 2026

Copy link
Copy Markdown
ContributorAuthor

Turns out I was very confused by the "new" diagnostic emitted by check_crate_level called by AttributeParser::check_target. The target checking is still happening correctly with this refactor, though I do think the diagnostic has become worse.

I tried changing the diagnostic in check_crate_level, but that broke all kinds of unrelated tests.

As for breaking changes, using a crate-level doc attribute on the wrong target now emits an ERROR instead of a WARN.

@rustbot ready

@rustbotrustbot 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 1, 2026
}
cx.check_target(
sym::no_crate_inject.as_str(),
&AllowedTargets::AllowList(&[Allow(Target::Crate)]),

@JonathanBrouwerJonathanBrouwerSep 1, 2026

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.

If you use AllowListWarnRest instead of AllowList it will warn instead of erroring.
Then to generate the right lint INVALID_DOC_ATTRIBUTES instead of the default UNUSED_ATTRIBUTES we should add a special case here

View changes since the review

//! This is not an official rust crate

#[doc(rust_logo)]
//~^ WARN this attribute can only be applied at the crate level

@JonathanBrouwerJonathanBrouwerSep 1, 2026

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.

Is there a reason you removed this from the test?
This is here to show that this doc attribute, incorrectly, is not feature gated

View changes since the review

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-2 failed! Check out the build log: (web)(plain enhanced)(plain)

Click to see the possible cause of the failure (guessed by this bot)

This error was generated by the lint-docs tool.
This tool extracts documentation for lints from the source code and places
them in the rustc book. See the declare_lint! documentation
https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/macro.declare_lint.html
for an example of the format of documentation this tool expects.
To re-run these tests, run: ./x.py test --keep-stage=0 src/tools/lint-docs
The --keep-stage flag should be used if you have already built the compiler
and are only modifying the doc comments to avoid rebuilding the compiler.
Bootstrap failed while executing `--stage 2 test --skip tidy --skip intrinsic-test --skip src/tools/rust-analyzer --skip tests --skip library --skip tidyselftest`
Currently active steps:
test::LintDocs { build_compiler: Compiler { stage: 1, host: aarch64-unknown-linux-gnu, forced_compiler: false }, target: aarch64-unknown-linux-gnu } at src/bootstrap/src/core/build_steps/test.rs:4173
doc::RustcBook { build_compiler: Compiler { stage: 1, host: aarch64-unknown-linux-gnu, forced_compiler: false }, target: aarch64-unknown-linux-gnu, validate: true } at src/bootstrap/src/core/build_steps/test.rs:4186
Command `/checkout/obj/build/aarch64-unknown-linux-gnu/stage1-tools-bin/lint-docs --build-rustc-stage 1 --src /checkout/compiler --out /checkout/obj/build/aarch64-unknown-linux-gnu/md-doc/rustc/src/lints --rustc /checkout/obj/build/aarch64-unknown-linux-gnu/stage1/bin/rustc --rustc-target aarch64-unknown-linux-gnu --validate` failed with exit code 1
Created at: src/bootstrap/src/core/build_steps/tool.rs:1627:23
Executed at: src/bootstrap/src/core/build_steps/doc.rs:1465:13
Command has failed. Rerun with -v to see more details.
Build completed unsuccessfully in 0:39:24
local time: Tue Sep 1 12:58:18 UTC 2026
network time: Tue, 01 Sep 2026 12:58:18 GMT
##[error]Process completed with exit code 1.
##[group]Run echo "disk usage:"

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributesArea: Attributes (`#[…]`, `#![…]`)needs-craterThis change needs a crater run to check for possible breakage in the ecosystem.needs-fcpThis change is insta-stable, or significant enough to need a team FCP to proceed.S-waiting-on-reviewStatus: Awaiting review from the assignee but also interested parties.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@evavh@rustbot@rust-log-analyzer@JonathanBrouwer@mejrs
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Replace check_attr_crate_level with check_target for #[doc] - #161521

Draft
evavh wants to merge 4 commits into
rust-lang:mainfrom
evavh:doc-crate-level-check
Draft

Replace check_attr_crate_level with check_target for #[doc]#161521
evavh wants to merge 4 commits into
rust-lang:mainfrom
evavh:doc-crate-level-check

Conversation

@evavh

Copy link
Copy Markdown
Contributor

A small change as part of the target checking refactor for #[doc] attribute parsing.

r? @JonathanBrouwer

@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred in compiler/rustc_attr_parsing

cc @jdonszelmann, @JonathanBrouwer

@rustbotrustbot 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 Aug 22, 2026
return;
}
cx.check_target(
&sym::no_crate_inject.to_string(),

@mejrsmejrsAug 22, 2026

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.

Suggested change
&sym::no_crate_inject.to_string(),
sym::no_crate_inject.as_str()

View changes since the review

return;
}
cx.check_target(
&s.to_string(),

@mejrsmejrsAug 22, 2026

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.

Suggested change
&s.to_string(),
s.as_str(),

View changes since the review

@rust-log-analyzer

This comment has been minimized.

return;
}
cx.check_target(
concat!("(", stringify!($ident), ")"),

@JonathanBrouwerJonathanBrouwerAug 22, 2026

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.

Could you make tests for these cases if they don't already exist? I'd expect some stderr changes in this PR

View changes since the review

@rustbotrustbot 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 Aug 22, 2026
@rustbot

Copy link
Copy Markdown
Collaborator

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

@evavh

Copy link
Copy Markdown
ContributorAuthor

I tried to add tests for the crate-level attribute checks, but I'm running into an interesting problem: there seems to be no way for the target check to fail. The possible ways for a crate-level attribute to be applied to a non-crate target (that I can think of) are:

  1. A #[doc(CRATE_LEVEL_ONLY)] attribute applied to an item: this outputs the error crate-level attribute should be an inner attribute: add an exclamation mark
  2. A #![doc(CRATE_LEVEL_ONLY)] attribute applied to an item (ie not at the top of the file): the error is an inner attribute is not permitted in this context

In both cases the compiler throws an error before we even reach the target checking code in doc.rs. The same applies to doc attribute arguments that shouldn't be used crate-level, like fake_variadic. It seems the distinction between inner (#!) and outer (#) attributes is enough to guard against wrong crate/non-crate targets.

The test I wrote covers all doc attribute arguments that check whether they are applied at crate level, and they all throw errors in earlier parsing steps. What do we do with the target checking code that does nothing?

@rust-log-analyzer

This comment has been minimized.

@rust-bors

This comment has been minimized.

@JonathanBrouwerJonathanBrouwer 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 Aug 30, 2026
@JonathanBrouwer

JonathanBrouwer commented Aug 30, 2026

Copy link
Copy Markdown
Member

@evavh I took a random crate-level doc attribute, and applied it to a function:

#[doc(html_no_source)]fntest1(){}fntest2(){#![doc(html_no_source)]}

In both cases this produces "this attribute can only be applied at the crate level"
This diagnostic is produced in target checking, so if you hit it you are doing target checking somewhere:

pub(crate)fncheck_crate_level(cx:&mutAcceptContext<'_,'sess>,warn:bool){

The diagnostic "an inner attribute is not permitted in this context" is produced when you apply inner attributes to an item that doesn't support inner attributes, such as a struct, and is indeed produced in the parser

structTest{#![doc(html_no_source)]}

@rustbot author

@rustbotrustbot 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 Aug 30, 2026
@evavh
evavhforce-pushed the doc-crate-level-check branch from 6c2968e to 7a056e3CompareAugust 31, 2026 14:31
@rustbot

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-log-analyzer

This comment has been minimized.

@mejrsmejrs added needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. needs-crater This change needs a crater run to check for possible breakage in the ecosystem. labels Aug 31, 2026
@mejrs

mejrs commented Aug 31, 2026

Copy link
Copy Markdown
Member

These are breaking changes, so they will need a crater run. Alternatively, you could refactor this in a way that doesn't change behavior.

@evavh
evavh marked this pull request as draft September 1, 2026 11:56
@evavh

evavh commented Sep 1, 2026

Copy link
Copy Markdown
ContributorAuthor

Turns out I was very confused by the "new" diagnostic emitted by check_crate_level called by AttributeParser::check_target. The target checking is still happening correctly with this refactor, though I do think the diagnostic has become worse.

I tried changing the diagnostic in check_crate_level, but that broke all kinds of unrelated tests.

As for breaking changes, using a crate-level doc attribute on the wrong target now emits an ERROR instead of a WARN.

@rustbot ready

@rustbotrustbot 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 1, 2026
}
cx.check_target(
sym::no_crate_inject.as_str(),
&AllowedTargets::AllowList(&[Allow(Target::Crate)]),

@JonathanBrouwerJonathanBrouwerSep 1, 2026

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.

If you use AllowListWarnRest instead of AllowList it will warn instead of erroring.
Then to generate the right lint INVALID_DOC_ATTRIBUTES instead of the default UNUSED_ATTRIBUTES we should add a special case here

View changes since the review

//! This is not an official rust crate

#[doc(rust_logo)]
//~^ WARN this attribute can only be applied at the crate level

@JonathanBrouwerJonathanBrouwerSep 1, 2026

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.

Is there a reason you removed this from the test?
This is here to show that this doc attribute, incorrectly, is not feature gated

View changes since the review

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-2 failed! Check out the build log: (web)(plain enhanced)(plain)

Click to see the possible cause of the failure (guessed by this bot)

This error was generated by the lint-docs tool.
This tool extracts documentation for lints from the source code and places
them in the rustc book. See the declare_lint! documentation
https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/macro.declare_lint.html
for an example of the format of documentation this tool expects.
To re-run these tests, run: ./x.py test --keep-stage=0 src/tools/lint-docs
The --keep-stage flag should be used if you have already built the compiler
and are only modifying the doc comments to avoid rebuilding the compiler.
Bootstrap failed while executing `--stage 2 test --skip tidy --skip intrinsic-test --skip src/tools/rust-analyzer --skip tests --skip library --skip tidyselftest`
Currently active steps:
test::LintDocs { build_compiler: Compiler { stage: 1, host: aarch64-unknown-linux-gnu, forced_compiler: false }, target: aarch64-unknown-linux-gnu } at src/bootstrap/src/core/build_steps/test.rs:4173
doc::RustcBook { build_compiler: Compiler { stage: 1, host: aarch64-unknown-linux-gnu, forced_compiler: false }, target: aarch64-unknown-linux-gnu, validate: true } at src/bootstrap/src/core/build_steps/test.rs:4186
Command `/checkout/obj/build/aarch64-unknown-linux-gnu/stage1-tools-bin/lint-docs --build-rustc-stage 1 --src /checkout/compiler --out /checkout/obj/build/aarch64-unknown-linux-gnu/md-doc/rustc/src/lints --rustc /checkout/obj/build/aarch64-unknown-linux-gnu/stage1/bin/rustc --rustc-target aarch64-unknown-linux-gnu --validate` failed with exit code 1
Created at: src/bootstrap/src/core/build_steps/tool.rs:1627:23
Executed at: src/bootstrap/src/core/build_steps/doc.rs:1465:13
Command has failed. Rerun with -v to see more details.
Build completed unsuccessfully in 0:39:24
local time: Tue Sep 1 12:58:18 UTC 2026
network time: Tue, 01 Sep 2026 12:58:18 GMT
##[error]Process completed with exit code 1.
##[group]Run echo "disk usage:"

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributesArea: Attributes (`#[…]`, `#![…]`)needs-craterThis change needs a crater run to check for possible breakage in the ecosystem.needs-fcpThis change is insta-stable, or significant enough to need a team FCP to proceed.S-waiting-on-reviewStatus: Awaiting review from the assignee but also interested parties.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@evavh@rustbot@rust-log-analyzer@JonathanBrouwer@mejrs
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Replace check_attr_crate_level with check_target for #[doc] - #161521

Draft
evavh wants to merge 4 commits into
rust-lang:mainfrom
evavh:doc-crate-level-check
Draft

Replace check_attr_crate_level with check_target for #[doc]#161521
evavh wants to merge 4 commits into
rust-lang:mainfrom
evavh:doc-crate-level-check

Conversation

@evavh

Copy link
Copy Markdown
Contributor

A small change as part of the target checking refactor for #[doc] attribute parsing.

r? @JonathanBrouwer

@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred in compiler/rustc_attr_parsing

cc @jdonszelmann, @JonathanBrouwer

@rustbotrustbot 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 Aug 22, 2026
return;
}
cx.check_target(
&sym::no_crate_inject.to_string(),

@mejrsmejrsAug 22, 2026

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.

Suggested change
&sym::no_crate_inject.to_string(),
sym::no_crate_inject.as_str()

View changes since the review

return;
}
cx.check_target(
&s.to_string(),

@mejrsmejrsAug 22, 2026

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.

Suggested change
&s.to_string(),
s.as_str(),

View changes since the review

@rust-log-analyzer

This comment has been minimized.

return;
}
cx.check_target(
concat!("(", stringify!($ident), ")"),

@JonathanBrouwerJonathanBrouwerAug 22, 2026

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.

Could you make tests for these cases if they don't already exist? I'd expect some stderr changes in this PR

View changes since the review

@rustbotrustbot 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 Aug 22, 2026
@rustbot

Copy link
Copy Markdown
Collaborator

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

@evavh

Copy link
Copy Markdown
ContributorAuthor

I tried to add tests for the crate-level attribute checks, but I'm running into an interesting problem: there seems to be no way for the target check to fail. The possible ways for a crate-level attribute to be applied to a non-crate target (that I can think of) are:

  1. A #[doc(CRATE_LEVEL_ONLY)] attribute applied to an item: this outputs the error crate-level attribute should be an inner attribute: add an exclamation mark
  2. A #![doc(CRATE_LEVEL_ONLY)] attribute applied to an item (ie not at the top of the file): the error is an inner attribute is not permitted in this context

In both cases the compiler throws an error before we even reach the target checking code in doc.rs. The same applies to doc attribute arguments that shouldn't be used crate-level, like fake_variadic. It seems the distinction between inner (#!) and outer (#) attributes is enough to guard against wrong crate/non-crate targets.

The test I wrote covers all doc attribute arguments that check whether they are applied at crate level, and they all throw errors in earlier parsing steps. What do we do with the target checking code that does nothing?

@rust-log-analyzer

This comment has been minimized.

@rust-bors

This comment has been minimized.

@JonathanBrouwerJonathanBrouwer 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 Aug 30, 2026
@JonathanBrouwer

JonathanBrouwer commented Aug 30, 2026

Copy link
Copy Markdown
Member

@evavh I took a random crate-level doc attribute, and applied it to a function:

#[doc(html_no_source)]fntest1(){}fntest2(){#![doc(html_no_source)]}

In both cases this produces "this attribute can only be applied at the crate level"
This diagnostic is produced in target checking, so if you hit it you are doing target checking somewhere:

pub(crate)fncheck_crate_level(cx:&mutAcceptContext<'_,'sess>,warn:bool){

The diagnostic "an inner attribute is not permitted in this context" is produced when you apply inner attributes to an item that doesn't support inner attributes, such as a struct, and is indeed produced in the parser

structTest{#![doc(html_no_source)]}

@rustbot author

@rustbotrustbot 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 Aug 30, 2026
@evavh
evavhforce-pushed the doc-crate-level-check branch from 6c2968e to 7a056e3CompareAugust 31, 2026 14:31
@rustbot

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-log-analyzer

This comment has been minimized.

@mejrsmejrs added needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. needs-crater This change needs a crater run to check for possible breakage in the ecosystem. labels Aug 31, 2026
@mejrs

mejrs commented Aug 31, 2026

Copy link
Copy Markdown
Member

These are breaking changes, so they will need a crater run. Alternatively, you could refactor this in a way that doesn't change behavior.

@evavh
evavh marked this pull request as draft September 1, 2026 11:56
@evavh

evavh commented Sep 1, 2026

Copy link
Copy Markdown
ContributorAuthor

Turns out I was very confused by the "new" diagnostic emitted by check_crate_level called by AttributeParser::check_target. The target checking is still happening correctly with this refactor, though I do think the diagnostic has become worse.

I tried changing the diagnostic in check_crate_level, but that broke all kinds of unrelated tests.

As for breaking changes, using a crate-level doc attribute on the wrong target now emits an ERROR instead of a WARN.

@rustbot ready

@rustbotrustbot 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 1, 2026
}
cx.check_target(
sym::no_crate_inject.as_str(),
&AllowedTargets::AllowList(&[Allow(Target::Crate)]),

@JonathanBrouwerJonathanBrouwerSep 1, 2026

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.

If you use AllowListWarnRest instead of AllowList it will warn instead of erroring.
Then to generate the right lint INVALID_DOC_ATTRIBUTES instead of the default UNUSED_ATTRIBUTES we should add a special case here

View changes since the review

//! This is not an official rust crate

#[doc(rust_logo)]
//~^ WARN this attribute can only be applied at the crate level

@JonathanBrouwerJonathanBrouwerSep 1, 2026

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.

Is there a reason you removed this from the test?
This is here to show that this doc attribute, incorrectly, is not feature gated

View changes since the review

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-2 failed! Check out the build log: (web)(plain enhanced)(plain)

Click to see the possible cause of the failure (guessed by this bot)

This error was generated by the lint-docs tool.
This tool extracts documentation for lints from the source code and places
them in the rustc book. See the declare_lint! documentation
https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/macro.declare_lint.html
for an example of the format of documentation this tool expects.
To re-run these tests, run: ./x.py test --keep-stage=0 src/tools/lint-docs
The --keep-stage flag should be used if you have already built the compiler
and are only modifying the doc comments to avoid rebuilding the compiler.
Bootstrap failed while executing `--stage 2 test --skip tidy --skip intrinsic-test --skip src/tools/rust-analyzer --skip tests --skip library --skip tidyselftest`
Currently active steps:
test::LintDocs { build_compiler: Compiler { stage: 1, host: aarch64-unknown-linux-gnu, forced_compiler: false }, target: aarch64-unknown-linux-gnu } at src/bootstrap/src/core/build_steps/test.rs:4173
doc::RustcBook { build_compiler: Compiler { stage: 1, host: aarch64-unknown-linux-gnu, forced_compiler: false }, target: aarch64-unknown-linux-gnu, validate: true } at src/bootstrap/src/core/build_steps/test.rs:4186
Command `/checkout/obj/build/aarch64-unknown-linux-gnu/stage1-tools-bin/lint-docs --build-rustc-stage 1 --src /checkout/compiler --out /checkout/obj/build/aarch64-unknown-linux-gnu/md-doc/rustc/src/lints --rustc /checkout/obj/build/aarch64-unknown-linux-gnu/stage1/bin/rustc --rustc-target aarch64-unknown-linux-gnu --validate` failed with exit code 1
Created at: src/bootstrap/src/core/build_steps/tool.rs:1627:23
Executed at: src/bootstrap/src/core/build_steps/doc.rs:1465:13
Command has failed. Rerun with -v to see more details.
Build completed unsuccessfully in 0:39:24
local time: Tue Sep 1 12:58:18 UTC 2026
network time: Tue, 01 Sep 2026 12:58:18 GMT
##[error]Process completed with exit code 1.
##[group]Run echo "disk usage:"

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributesArea: Attributes (`#[…]`, `#![…]`)needs-craterThis change needs a crater run to check for possible breakage in the ecosystem.needs-fcpThis change is insta-stable, or significant enough to need a team FCP to proceed.S-waiting-on-reviewStatus: Awaiting review from the assignee but also interested parties.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@evavh@rustbot@rust-log-analyzer@JonathanBrouwer@mejrs
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Replace check_attr_crate_level with check_target for #[doc] - #161521

Draft
evavh wants to merge 4 commits into
rust-lang:mainfrom
evavh:doc-crate-level-check
Draft

Replace check_attr_crate_level with check_target for #[doc]#161521
evavh wants to merge 4 commits into
rust-lang:mainfrom
evavh:doc-crate-level-check

Conversation

@evavh

Copy link
Copy Markdown
Contributor

A small change as part of the target checking refactor for #[doc] attribute parsing.

r? @JonathanBrouwer

@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred in compiler/rustc_attr_parsing

cc @jdonszelmann, @JonathanBrouwer

@rustbotrustbot 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 Aug 22, 2026
return;
}
cx.check_target(
&sym::no_crate_inject.to_string(),

@mejrsmejrsAug 22, 2026

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.

Suggested change
&sym::no_crate_inject.to_string(),
sym::no_crate_inject.as_str()

View changes since the review

return;
}
cx.check_target(
&s.to_string(),

@mejrsmejrsAug 22, 2026

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.

Suggested change
&s.to_string(),
s.as_str(),

View changes since the review

@rust-log-analyzer

This comment has been minimized.

return;
}
cx.check_target(
concat!("(", stringify!($ident), ")"),

@JonathanBrouwerJonathanBrouwerAug 22, 2026

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.

Could you make tests for these cases if they don't already exist? I'd expect some stderr changes in this PR

View changes since the review

@rustbotrustbot 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 Aug 22, 2026
@rustbot

Copy link
Copy Markdown
Collaborator

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

@evavh

Copy link
Copy Markdown
ContributorAuthor

I tried to add tests for the crate-level attribute checks, but I'm running into an interesting problem: there seems to be no way for the target check to fail. The possible ways for a crate-level attribute to be applied to a non-crate target (that I can think of) are:

  1. A #[doc(CRATE_LEVEL_ONLY)] attribute applied to an item: this outputs the error crate-level attribute should be an inner attribute: add an exclamation mark
  2. A #![doc(CRATE_LEVEL_ONLY)] attribute applied to an item (ie not at the top of the file): the error is an inner attribute is not permitted in this context

In both cases the compiler throws an error before we even reach the target checking code in doc.rs. The same applies to doc attribute arguments that shouldn't be used crate-level, like fake_variadic. It seems the distinction between inner (#!) and outer (#) attributes is enough to guard against wrong crate/non-crate targets.

The test I wrote covers all doc attribute arguments that check whether they are applied at crate level, and they all throw errors in earlier parsing steps. What do we do with the target checking code that does nothing?

@rust-log-analyzer

This comment has been minimized.

@rust-bors

This comment has been minimized.

@JonathanBrouwerJonathanBrouwer 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 Aug 30, 2026
@JonathanBrouwer

JonathanBrouwer commented Aug 30, 2026

Copy link
Copy Markdown
Member

@evavh I took a random crate-level doc attribute, and applied it to a function:

#[doc(html_no_source)]fntest1(){}fntest2(){#![doc(html_no_source)]}

In both cases this produces "this attribute can only be applied at the crate level"
This diagnostic is produced in target checking, so if you hit it you are doing target checking somewhere:

pub(crate)fncheck_crate_level(cx:&mutAcceptContext<'_,'sess>,warn:bool){

The diagnostic "an inner attribute is not permitted in this context" is produced when you apply inner attributes to an item that doesn't support inner attributes, such as a struct, and is indeed produced in the parser

structTest{#![doc(html_no_source)]}

@rustbot author

@rustbotrustbot 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 Aug 30, 2026
@evavh
evavhforce-pushed the doc-crate-level-check branch from 6c2968e to 7a056e3CompareAugust 31, 2026 14:31
@rustbot

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-log-analyzer

This comment has been minimized.

@mejrsmejrs added needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. needs-crater This change needs a crater run to check for possible breakage in the ecosystem. labels Aug 31, 2026
@mejrs

mejrs commented Aug 31, 2026

Copy link
Copy Markdown
Member

These are breaking changes, so they will need a crater run. Alternatively, you could refactor this in a way that doesn't change behavior.

@evavh
evavh marked this pull request as draft September 1, 2026 11:56
@evavh

evavh commented Sep 1, 2026

Copy link
Copy Markdown
ContributorAuthor

Turns out I was very confused by the "new" diagnostic emitted by check_crate_level called by AttributeParser::check_target. The target checking is still happening correctly with this refactor, though I do think the diagnostic has become worse.

I tried changing the diagnostic in check_crate_level, but that broke all kinds of unrelated tests.

As for breaking changes, using a crate-level doc attribute on the wrong target now emits an ERROR instead of a WARN.

@rustbot ready

@rustbotrustbot 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 1, 2026
}
cx.check_target(
sym::no_crate_inject.as_str(),
&AllowedTargets::AllowList(&[Allow(Target::Crate)]),

@JonathanBrouwerJonathanBrouwerSep 1, 2026

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.

If you use AllowListWarnRest instead of AllowList it will warn instead of erroring.
Then to generate the right lint INVALID_DOC_ATTRIBUTES instead of the default UNUSED_ATTRIBUTES we should add a special case here

View changes since the review

//! This is not an official rust crate

#[doc(rust_logo)]
//~^ WARN this attribute can only be applied at the crate level

@JonathanBrouwerJonathanBrouwerSep 1, 2026

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.

Is there a reason you removed this from the test?
This is here to show that this doc attribute, incorrectly, is not feature gated

View changes since the review

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-2 failed! Check out the build log: (web)(plain enhanced)(plain)

Click to see the possible cause of the failure (guessed by this bot)

This error was generated by the lint-docs tool.
This tool extracts documentation for lints from the source code and places
them in the rustc book. See the declare_lint! documentation
https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/macro.declare_lint.html
for an example of the format of documentation this tool expects.
To re-run these tests, run: ./x.py test --keep-stage=0 src/tools/lint-docs
The --keep-stage flag should be used if you have already built the compiler
and are only modifying the doc comments to avoid rebuilding the compiler.
Bootstrap failed while executing `--stage 2 test --skip tidy --skip intrinsic-test --skip src/tools/rust-analyzer --skip tests --skip library --skip tidyselftest`
Currently active steps:
test::LintDocs { build_compiler: Compiler { stage: 1, host: aarch64-unknown-linux-gnu, forced_compiler: false }, target: aarch64-unknown-linux-gnu } at src/bootstrap/src/core/build_steps/test.rs:4173
doc::RustcBook { build_compiler: Compiler { stage: 1, host: aarch64-unknown-linux-gnu, forced_compiler: false }, target: aarch64-unknown-linux-gnu, validate: true } at src/bootstrap/src/core/build_steps/test.rs:4186
Command `/checkout/obj/build/aarch64-unknown-linux-gnu/stage1-tools-bin/lint-docs --build-rustc-stage 1 --src /checkout/compiler --out /checkout/obj/build/aarch64-unknown-linux-gnu/md-doc/rustc/src/lints --rustc /checkout/obj/build/aarch64-unknown-linux-gnu/stage1/bin/rustc --rustc-target aarch64-unknown-linux-gnu --validate` failed with exit code 1
Created at: src/bootstrap/src/core/build_steps/tool.rs:1627:23
Executed at: src/bootstrap/src/core/build_steps/doc.rs:1465:13
Command has failed. Rerun with -v to see more details.
Build completed unsuccessfully in 0:39:24
local time: Tue Sep 1 12:58:18 UTC 2026
network time: Tue, 01 Sep 2026 12:58:18 GMT
##[error]Process completed with exit code 1.
##[group]Run echo "disk usage:"

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributesArea: Attributes (`#[…]`, `#![…]`)needs-craterThis change needs a crater run to check for possible breakage in the ecosystem.needs-fcpThis change is insta-stable, or significant enough to need a team FCP to proceed.S-waiting-on-reviewStatus: Awaiting review from the assignee but also interested parties.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@evavh@rustbot@rust-log-analyzer@JonathanBrouwer@mejrs