Skip to content

Split register_tool into register_attribute_tool and register_lint_tool#158038

Open
nbdd0121 wants to merge 4 commits into
rust-lang:mainfrom
nbdd0121:register_tool
Open

Split register_tool into register_attribute_tool and register_lint_tool#158038
nbdd0121 wants to merge 4 commits into
rust-lang:mainfrom
nbdd0121:register_tool

Conversation

@nbdd0121

@nbdd0121 nbdd0121 commented Jun 17, 2026

Copy link
Copy Markdown
Member

Tracking issue: #66079

This implements the attribute parsing part of RFC 3808. The resolution part is yet to be implemented.

cc @jyn514

nbdd0121 added 4 commits June 17, 2026 16:59
This splits the functionality to two parts per RFC. The `#![register_tool]`
attribute registers the tool in both ways.

Semantics remain unchanged and will be adjusted in later commit.
Under the RFC, it's not an error to register tool multiple times, but it is
an error to register a predefined tool, or register "rustc" tool.
@rustbot

rustbot commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

Some changes occurred in compiler/rustc_passes/src/check_attr.rs

cc @jdonszelmann, @JonathanBrouwer

Some changes occurred in compiler/rustc_attr_parsing

cc @jdonszelmann, @JonathanBrouwer

Some changes occurred in compiler/rustc_hir/src/attrs

cc @jdonszelmann, @JonathanBrouwer

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

rustbot commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

r? @wesleywiser

rustbot has assigned @wesleywiser.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 73 candidates
  • Random selection from 20 candidates

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job x86_64-gnu-tools failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
...............................F.................. (50/144)
.................................................. (100/144)
............................................       (144/144)

======== tests/rustdoc-gui/go-to-collapsed-elem.goml ========

[ERROR] line 40
    at `tests/rustdoc-gui/go-to-collapsed-elem.goml` line 21: Error: Node is detached from document: for command `click: "//*[@id='search']//a[@href='../test_docs/struct.Foo.html#method.must_use']"`
    at <file:///checkout/obj/build/x86_64-unknown-linux-gnu/test/rustdoc-gui/doc/test_docs/struct.Foo.html?search=t_use>


<= doc-ui tests done: 143 succeeded, 1 failed, 0 filtered out

Error: ()

@nbdd0121

Copy link
Copy Markdown
Member Author

Error seems to be flaky rustdoc test: #157747

@mejrs

mejrs commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

r? me

(Or Jonathan I suppose)

@rustbot rustbot assigned mejrs and unassigned wesleywiser Jun 17, 2026
@mejrs

mejrs commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Can you expand on the "resolution yet to be implemented" thing? I was under the impression there would be no resolution and it'd all be, essentially, stringly typed.

@petrochenkov petrochenkov self-assigned this Jun 17, 2026
@nbdd0121

Copy link
Copy Markdown
Member Author

Can you expand on the "resolution yet to be implemented" thing? I was under the impression there would be no resolution and it'd all be, essentially, stringly typed.

In https://github.com/rust-lang/rfcs/blob/master/text/3808-register-tool.md it mentioned that ambiguity between tool attribute and other resolution should be an error, and also that tool attribute is not affected by no_implicit_prelude. These are technically breaking changes so I'd want to split it to another PR so it gets a crater run.

@mejrs mejrs left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Typically when there are multiple attributes which are semantically related, we "merge" them into a single attribute. See https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html#how-this-crate-works

This implementation doesn't; you'd be dealing with RegisteredTool { kind: sym::register_lint_tool, ..}, RegisteredTool { kind: sym::register_tool, ..} and RegisteredTool { kind: sym::register_attribute_tool, ..}. That's three attributes, effectively. I've pointed at some places that need changes for that.

Also, my understanding from the rfc is that resolution and ambiguity errors are only for attribute_tool? i.e. #[my_tool::thing]? and not #[allow(my_tool::lint)]?

View changes since this review

Comment on lines +1269 to +1272
RegisterTool {
kind: Symbol,
tools: ThinVec<Ident>,
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

So I would expect this to look like...

Suggested change
RegisterTool {
kind: Symbol,
tools: ThinVec<Ident>,
},
RegisterTool {
lint_tools: ThinVec<Ident>,
attribute_tools: ThinVec<Ident>,
},

and if you use register_tool the name would be put into both of those.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

^ Agreed on this, it must never be possible to have two of the same variant in an attribute list in the HIR

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Attribute tools and lint tools are handled very differently in the compiler, and there're very few cases you'd want to know both, so I want to keep the queries distinct.

Perhaps I should split the HIR attr to two variants two? But I do want to avoid duplicated code because the parsing of the two attributes are very similar.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You could just make a function that parsers the attributes, and call that from the two distinct attribute parsers

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This doesn't work as this will run into Attribute ["register_tool"] has multiple accepters

Comment on lines +320 to +346
pub(crate) struct RegisterAttributeTool;
pub(crate) struct RegisterLintTool;
pub(crate) struct RegisterTool;

impl CombineAttributeParser for RegisterToolParser {
const PATH: &[Symbol] = &[sym::register_tool];
pub(crate) trait RegisterToolKind: 'static {
const SYMBOL: Symbol;
}

impl RegisterToolKind for RegisterAttributeTool {
const SYMBOL: Symbol = sym::register_attribute_tool;
}

impl RegisterToolKind for RegisterLintTool {
const SYMBOL: Symbol = sym::register_lint_tool;
}

impl RegisterToolKind for RegisterTool {
const SYMBOL: Symbol = sym::register_tool;
}

pub(crate) struct RegisterToolParser<Kind>(Kind);

impl<K: RegisterToolKind> CombineAttributeParser for RegisterToolParser<K> {
const PATH: &[Symbol] = &[K::SYMBOL];
type Item = Ident;
const CONVERT: ConvertFn<Self::Item> = |tools, _span| AttributeKind::RegisterTool(tools);
const CONVERT: ConvertFn<Self::Item> =
|tools, _span| AttributeKind::RegisterTool { kind: K::SYMBOL, tools };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

And this would need to implement AttributeParser directly. For example see the stability parser:

impl AttributeParser for StabilityParser {
which combines #[stable], #[unstable] and #[rustc_allowed_through_unstable_modules] into a single semantic attribute.


if let Some(Attribute::Parsed(AttributeKind::RegisterTool(tools))) =
if let Some(Attribute::Parsed(AttributeKind::RegisterTool { kind: _, tools })) =
AttributeParser::parse_limited(sess, pre_configured_attrs, &[sym])

@mejrs mejrs Jun 17, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Unfortunately you can only use parse_limited for one attribute at a time; you can't parse multiple attributes at a time. Feel free to make a function that allows multiple attributes though, if you need it.

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 17, 2026
/// Tool modules introduced with `#![register_tool]`.
ToolPrelude,
/// Tool modules introduced with `#![register_tool]` or `#![register_attribute_tool]`.
ToolAttributePrelude,

@petrochenkov petrochenkov Jun 18, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
ToolAttributePrelude,
AttributeToolPrelude,

It's a prelude for tools, not for attributes.

I'd probably just keep the ToolPrelude naming here, because lints do no go through name resolution, but may be better to be more explicit for readers less aware of the context.

View changes since the review

Comment on lines +10 to +11
#![register_attribute_tool(qux)]
#![register_attribute_tool(qux)]

@petrochenkov petrochenkov Jun 18, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@jyn514 is there a specific reason for

#![register_attribute_tool(qux)]
#![register_attribute_tool(qux)]

to be allowed?
I don't see the explanation in the RFC.
Duplicate definitions are typically prohibited in name resolution.

View changes since the review

@petrochenkov

Copy link
Copy Markdown
Contributor

Naming nit: "attribute" is long, so it's usually abbreviated to "attr" in the compiler, so all the AttributeToolPrelude/registered_attribute_tools internal stuff could be shortened to AttrToolPrelude/registered_attr_tools/etc.

@petrochenkov

Copy link
Copy Markdown
Contributor

The resolution part is yet to be implemented.

Please, assign me when the resolution part is submitted.

@petrochenkov petrochenkov removed their assignment Jun 18, 2026
@rust-bors

rust-bors Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

☔ The latest upstream changes (presumably #158124) made this pull request unmergeable. Please resolve the merge conflicts by rebasing.

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

Labels

A-attributes Area: Attributes (`#[…]`, `#![…]`) S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants