Skip to content

raise ambiguity error on attribute macro that could be tool attribute - #162597

Merged
rust-bors[bot] merged 2 commits into
rust-lang:mainfrom
mejrs:ambiguity
Oct 28, 2026
Merged

rust-bors[bot] merged 2 commits into
rust-lang:mainfrom
mejrs:ambiguity

Conversation

@mejrs

@mejrs mejrs commented Sep 10, 2026 •

Copy link
Copy Markdown
Member

View all comments

See #162597 (comment) for clean crater run; the errors are unrelated/spurious.

We need some sort of ambiguity error in other to implement the register tool rfc:

Fixing name resolution errors

Note that register_tool changes name resolution, and may give errors if you have a crate named some_tool.
The compiler will suggest ways to fix the new errors.

If a tool name conflicts with a crate name, you can disambiguate the crate with ::some_tool:

#![register_tool(some_tool)]
extern crate some_tool;

#[some_tool::attribute] //~ ERROR: is this the tool or a proc-macro?
fn bar() {
   // ...
}

#[::some_tool::attribute] // OK: This is the proc-macro defined in the crate.
fn foo() {
  // ...
}

However, if you want to go on to use a tool attribute,
you must rename the crate so it doesn't conflict:

#![register_tool(some_tool)]
extern crate some_tool as my_library;

#[some_tool::attribute] // OK: This is the attribute specified by the tool.
fn bar() {
   // ...
}

Alternatively, if you only want to use lints, you can use register_lint_tool instead of register_tool, which will avoid resolution errors.

Overlaps like this are expected to be rare in practice.

This PR implements the ambiguity error (not the "leading :: to disambiguate" part).

This is a breaking change if:

  • someone has a crate or module named diagnostic|miri|rust_analyzer|clippy|rustfmt and exports an attribute macro from it
  • it is then used it as #[(diagnostic|miri|rust_analyzer|clippy|rustfmt)::attr_macro] (rather than use module_or_crate::attr_macro; #[attr_macro])
  • the same applies for tools registered with register_tool, but that's unstable.

See #158146 for context. This is a simpler version of that PR.

This does not implement unconditionally resolving these as tool attributes but does reserve the ability to do so. This would allow things like this to compile:

mod rustfmt {}

#[rustfmt::skip]
fn main() {}

and see also #98291 for a case where it would be nice to assume e.g. #[rustfmt::skip] is actually a tool attribute and thus inert.

@mejrs mejrs added the needs-crater This change needs a crater run to check for possible breakage in the ecosystem. label Sep 10, 2026
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 10, 2026
@mejrs

mejrs commented Sep 10, 2026

Copy link
Copy Markdown
Member Author

@bors try

@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Sep 10, 2026
raise ambiguity error on attribute macro that could be tool attribute
@rust-log-analyzer

This comment has been minimized.

@rust-bors

rust-bors Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 8c2ec58 (8c2ec5867b7cd0db3869fc1c128b867c2e8c0129)
Base parent: c4c4a57 (c4c4a576936e9e67717d0deb8e74e02dd5dd10de)

@mejrs

mejrs commented Sep 10, 2026

Copy link
Copy Markdown
Member Author

@bors try

@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Sep 10, 2026
raise ambiguity error on attribute macro that could be tool attribute
@rust-bors

rust-bors Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: be3da1e (be3da1e8c043bb6f1f335463d3b1335cdf50b03c)
Base parent: 018018e (018018e881e2db0956f229dbb543e21f058d1ce7)

@mejrs

mejrs commented Sep 10, 2026

Copy link
Copy Markdown
Member Author

@craterbot check

@craterbot

Copy link
Copy Markdown
Collaborator

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

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

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Sep 10, 2026
@craterbot

Copy link
Copy Markdown
Collaborator

🚧 Experiment pr-162597 is now running

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

@craterbot

Copy link
Copy Markdown
Collaborator

🎉 Experiment pr-162597 is completed!
📊 3 regressed and 1 fixed (1108363 total)
📊 6349 spurious results on the retry-regressed-list.txt, consider a retry1 if this is a significant amount.
📰 Open the summary report.

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

Footnotes

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

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Sep 18, 2026
@mejrs

mejrs commented Sep 18, 2026

Copy link
Copy Markdown
Member Author

Looks like the crater run is clean, so I guess we can do this (If the lang team agrees, of course)

r? @petrochenkov

@mejrs
mejrs marked this pull request as ready for review September 18, 2026 22:31
Comment thread compiler/rustc_resolve/src/macros.rs Outdated
Comment thread compiler/rustc_resolve/src/macros.rs Outdated
Comment thread compiler/rustc_resolve/src/macros.rs Outdated
Comment thread compiler/rustc_resolve/src/macros.rs Outdated
@petrochenkov

Copy link
Copy Markdown
Contributor

So the main drawback here is the same as with built-in attributes - with these rules you cannot add a new built-in tool module without a breakage (maybe theoretical).

But if register_tool is stabilized, then new built-in tools are hopefully never added, and most of existing built-in tools are migrated to explicit registration in the next edition, so this is not going to be a big problem.

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

This comment has been minimized.

@theemathas

Copy link
Copy Markdown
Contributor

I am assuming that it's intended that the diagnostic namespace thingy is treated the same way as tool attributes.

@petrochenkov

Copy link
Copy Markdown
Contributor

@bors r+

@rust-bors

rust-bors Bot commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

📋 This PR cannot be approved because it currently has the following labels: S-waiting-on-t-lang, needs-reference-pr.

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

Copy link
Copy Markdown
Contributor

Ok, waiting on the reference PR.
@rustbot author

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

mejrs commented Oct 27, 2026

Copy link
Copy Markdown
Member Author

Reference PR is open at rust-lang/reference#2397

@petrochenkov petrochenkov removed the needs-reference-pr This language change needs an approved Reference PR to proceed. label Oct 27, 2026
@petrochenkov

Copy link
Copy Markdown
Contributor

@bors r+

@rust-bors

rust-bors Bot commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 168e53d has been approved by petrochenkov

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Oct 27, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Oct 27, 2026
raise ambiguity error on attribute macro that could be tool attribute

See rust-lang#162597 (comment) for clean crater run; the errors are unrelated/spurious.

We need some sort of ambiguity error in other to implement the [register tool rfc](https://rust-lang.github.io/rfcs/3808-register-tool.html#fixing-name-resolution-errors):

> #### Fixing name resolution errors
>
>Note that `register_tool` changes name resolution, and may give errors if you have a crate named `some_tool`.
The compiler will suggest ways to fix the new errors.
>
>If a tool name conflicts with a crate name, you can disambiguate the crate with `::some_tool`:
>```rust
>#![register_tool(some_tool)]
>extern crate some_tool;
>
>#[some_tool::attribute] //~ ERROR: is this the tool or a proc-macro?
>fn bar() {
>    // ...
>}
>
>#[::some_tool::attribute] // OK: This is the proc-macro defined in the crate.
>fn foo() {
>   // ...
>}
>```
>However, if you want to go on to use a tool attribute,
>you must rename the crate so it doesn't conflict:
>```rust
>#![register_tool(some_tool)]
>extern crate some_tool as my_library;
>
>#[some_tool::attribute] // OK: This is the attribute specified by the tool.
>fn bar() {
>    // ...
>}
>```
>Alternatively, if you only want to use lints, you can use `register_lint_tool` instead of `register_tool`, which will avoid resolution errors.
>
>Overlaps like this are expected to be rare in practice.

This PR implements the ambiguity error (**not** the "leading `::` to disambiguate" part).

This is a breaking change if:
- someone has a crate or module named diagnostic|miri|rust_analyzer|clippy|rustfmt and exports an attribute macro from it
- it is then used it as `#[(diagnostic|miri|rust_analyzer|clippy|rustfmt)::attr_macro]` (rather than `use module_or_crate::attr_macro; #[attr_macro]`)
- the same applies for tools registered with `register_tool`, but that's unstable.

See rust-lang#158146 for context. This is a simpler version of that PR.

This does not implement unconditionally resolving these as tool attributes but does reserve the ability to do so. This would allow things like this to compile:
```rust
mod rustfmt {}

#[rustfmt::skip]
fn main() {}
```

and see also rust-lang#98291 for a case where it would be nice to assume e.g. `#[rustfmt::skip]` is actually a tool attribute and thus inert.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Oct 27, 2026
raise ambiguity error on attribute macro that could be tool attribute

See rust-lang#162597 (comment) for clean crater run; the errors are unrelated/spurious.

We need some sort of ambiguity error in other to implement the [register tool rfc](https://rust-lang.github.io/rfcs/3808-register-tool.html#fixing-name-resolution-errors):

> #### Fixing name resolution errors
>
>Note that `register_tool` changes name resolution, and may give errors if you have a crate named `some_tool`.
The compiler will suggest ways to fix the new errors.
>
>If a tool name conflicts with a crate name, you can disambiguate the crate with `::some_tool`:
>```rust
>#![register_tool(some_tool)]
>extern crate some_tool;
>
>#[some_tool::attribute] //~ ERROR: is this the tool or a proc-macro?
>fn bar() {
>    // ...
>}
>
>#[::some_tool::attribute] // OK: This is the proc-macro defined in the crate.
>fn foo() {
>   // ...
>}
>```
>However, if you want to go on to use a tool attribute,
>you must rename the crate so it doesn't conflict:
>```rust
>#![register_tool(some_tool)]
>extern crate some_tool as my_library;
>
>#[some_tool::attribute] // OK: This is the attribute specified by the tool.
>fn bar() {
>    // ...
>}
>```
>Alternatively, if you only want to use lints, you can use `register_lint_tool` instead of `register_tool`, which will avoid resolution errors.
>
>Overlaps like this are expected to be rare in practice.

This PR implements the ambiguity error (**not** the "leading `::` to disambiguate" part).

This is a breaking change if:
- someone has a crate or module named diagnostic|miri|rust_analyzer|clippy|rustfmt and exports an attribute macro from it
- it is then used it as `#[(diagnostic|miri|rust_analyzer|clippy|rustfmt)::attr_macro]` (rather than `use module_or_crate::attr_macro; #[attr_macro]`)
- the same applies for tools registered with `register_tool`, but that's unstable.

See rust-lang#158146 for context. This is a simpler version of that PR.

This does not implement unconditionally resolving these as tool attributes but does reserve the ability to do so. This would allow things like this to compile:
```rust
mod rustfmt {}

#[rustfmt::skip]
fn main() {}
```

and see also rust-lang#98291 for a case where it would be nice to assume e.g. `#[rustfmt::skip]` is actually a tool attribute and thus inert.
rust-bors Bot pushed a commit that referenced this pull request Oct 27, 2026
…uwer

Rollup of 22 pull requests

Successful merges:

 - #159580 (Reject cfg on expressions that cannot be safely removed)
 - #162597 (raise ambiguity error on attribute macro that could be tool attribute)
 - #162808 (Enable `--generate-link-to-definition` rustdoc option on std docs)
 - #163059 (Recover invalid return type until `{`, `}` or `;`)
 - #163672 (Use runCodeGen Abstraction for new LLVM)
 - #164028 (Add a future incompat warning for #[no_link])
 - #164188 (Suggest adding lifetime for `dyn Trait` in return type)
 - #164345 (fix: handle `false` in root contexts)
 - #164494 (drop ands which are a superset of other ands)
 - #164766 (Unstably introduce MVP edition migration lint `unmarked_unchecked_type_aliases` together with bikeshed attribute `#[rustc_unchecked_type_alias]`)
 - #164785 (delegation: emit error when there is no field for `Self` mapping)
 - #164799 (Don't use `IntoIterator` in parallel API)
 - #164871 (Refactor call argument codegen)
 - #164648 (parse inline and rustc_force_inline with same parser)
 - #164811 (fix: Prevent ICE when comparing EII impl against generic declaration)
 - #164900 (make tool_attrs method to retrieve tool attributes.)
 - #164993 (copy_nonoverlapping: dont skip ovelrap check when src is fully uninit)
 - #164996 (miri: add missing alignment check in write_bytes)
 - #165012 (Remove Span::eq_ctxt())
 - #165013 ([tiny] Add missing backticks around lifetime name)
 - #165024 (rustdoc-search: rank re-export lower)
 - #165028 (Update enzyme to fix one bug related to higher-order derivatives)

> [!WARNING]
> This rollup conflicts with pending auto build #165042 and may need to be recreated if the pending build succeeds.
@mejrs mejrs added relnotes Marks issues that should be documented in the release notes of the next release. and removed relnotes Marks issues that should be documented in the release notes of the next release. labels Oct 27, 2026
rust-bors Bot pushed a commit that referenced this pull request Oct 27, 2026
…uwer

Rollup of 21 pull requests

Successful merges:

 - #159580 (Reject cfg on expressions that cannot be safely removed)
 - #162597 (raise ambiguity error on attribute macro that could be tool attribute)
 - #162808 (Enable `--generate-link-to-definition` rustdoc option on std docs)
 - #163059 (Recover invalid return type until `{`, `}` or `;`)
 - #163672 (Use runCodeGen Abstraction for new LLVM)
 - #164028 (Add a future incompat warning for #[no_link])
 - #164188 (Suggest adding lifetime for `dyn Trait` in return type)
 - #164345 (fix: handle `false` in root contexts)
 - #164494 (drop ands which are a superset of other ands)
 - #164785 (delegation: emit error when there is no field for `Self` mapping)
 - #164799 (Don't use `IntoIterator` in parallel API)
 - #164871 (Refactor call argument codegen)
 - #164648 (parse inline and rustc_force_inline with same parser)
 - #164811 (fix: Prevent ICE when comparing EII impl against generic declaration)
 - #164900 (make tool_attrs method to retrieve tool attributes.)
 - #164993 (copy_nonoverlapping: dont skip ovelrap check when src is fully uninit)
 - #164996 (miri: add missing alignment check in write_bytes)
 - #165012 (Remove Span::eq_ctxt())
 - #165013 ([tiny] Add missing backticks around lifetime name)
 - #165024 (rustdoc-search: rank re-export lower)
 - #165028 (Update enzyme to fix one bug related to higher-order derivatives)
rust-bors Bot pushed a commit that referenced this pull request Oct 28, 2026
…uwer

Rollup of 21 pull requests

Successful merges:

 - #159580 (Reject cfg on expressions that cannot be safely removed)
 - #162597 (raise ambiguity error on attribute macro that could be tool attribute)
 - #162808 (Enable `--generate-link-to-definition` rustdoc option on std docs)
 - #163059 (Recover invalid return type until `{`, `}` or `;`)
 - #163672 (Use runCodeGen Abstraction for new LLVM)
 - #164028 (Add a future incompat warning for #[no_link])
 - #164188 (Suggest adding lifetime for `dyn Trait` in return type)
 - #164345 (fix: handle `false` in root contexts)
 - #164494 (drop ands which are a superset of other ands)
 - #164785 (delegation: emit error when there is no field for `Self` mapping)
 - #164799 (Don't use `IntoIterator` in parallel API)
 - #164871 (Refactor call argument codegen)
 - #164648 (parse inline and rustc_force_inline with same parser)
 - #164811 (fix: Prevent ICE when comparing EII impl against generic declaration)
 - #164900 (make tool_attrs method to retrieve tool attributes.)
 - #164993 (copy_nonoverlapping: dont skip ovelrap check when src is fully uninit)
 - #164996 (miri: add missing alignment check in write_bytes)
 - #165012 (Remove Span::eq_ctxt())
 - #165013 ([tiny] Add missing backticks around lifetime name)
 - #165024 (rustdoc-search: rank re-export lower)
 - #165028 (Update enzyme to fix one bug related to higher-order derivatives)
@traviscross traviscross added the missed-reference-pr This language change needed an approved Reference PR and merged without it. label Oct 28, 2026
rust-bors Bot pushed a commit that referenced this pull request Oct 28, 2026
…uwer

Rollup of 21 pull requests

Successful merges:

 - #159580 (Reject cfg on expressions that cannot be safely removed)
 - #162597 (raise ambiguity error on attribute macro that could be tool attribute)
 - #162808 (Enable `--generate-link-to-definition` rustdoc option on std docs)
 - #163059 (Recover invalid return type until `{`, `}` or `;`)
 - #163672 (Use runCodeGen Abstraction for new LLVM)
 - #164028 (Add a future incompat warning for #[no_link])
 - #164188 (Suggest adding lifetime for `dyn Trait` in return type)
 - #164345 (fix: handle `false` in root contexts)
 - #164494 (drop ands which are a superset of other ands)
 - #164785 (delegation: emit error when there is no field for `Self` mapping)
 - #164799 (Don't use `IntoIterator` in parallel API)
 - #164871 (Refactor call argument codegen)
 - #164648 (parse inline and rustc_force_inline with same parser)
 - #164811 (fix: Prevent ICE when comparing EII impl against generic declaration)
 - #164900 (make tool_attrs method to retrieve tool attributes.)
 - #164993 (copy_nonoverlapping: dont skip ovelrap check when src is fully uninit)
 - #164996 (miri: add missing alignment check in write_bytes)
 - #165012 (Remove Span::eq_ctxt())
 - #165013 ([tiny] Add missing backticks around lifetime name)
 - #165024 (rustdoc-search: rank re-export lower)
 - #165028 (Update enzyme to fix one bug related to higher-order derivatives)
rust-bors Bot pushed a commit that referenced this pull request Oct 28, 2026
…uwer

Rollup of 21 pull requests



Successful merges:

 - #159580 (Reject cfg on expressions that cannot be safely removed)
 - #162597 (raise ambiguity error on attribute macro that could be tool attribute)
 - #162808 (Enable `--generate-link-to-definition` rustdoc option on std docs)
 - #163059 (Recover invalid return type until `{`, `}` or `;`)
 - #163672 (Use runCodeGen Abstraction for new LLVM)
 - #164028 (Add a future incompat warning for #[no_link])
 - #164188 (Suggest adding lifetime for `dyn Trait` in return type)
 - #164345 (fix: handle `false` in root contexts)
 - #164494 (drop ands which are a superset of other ands)
 - #164785 (delegation: emit error when there is no field for `Self` mapping)
 - #164799 (Don't use `IntoIterator` in parallel API)
 - #164871 (Refactor call argument codegen)
 - #164648 (parse inline and rustc_force_inline with same parser)
 - #164811 (fix: Prevent ICE when comparing EII impl against generic declaration)
 - #164900 (make tool_attrs method to retrieve tool attributes.)
 - #164993 (copy_nonoverlapping: dont skip ovelrap check when src is fully uninit)
 - #164996 (miri: add missing alignment check in write_bytes)
 - #165012 (Remove Span::eq_ctxt())
 - #165013 ([tiny] Add missing backticks around lifetime name)
 - #165024 (rustdoc-search: rank re-export lower)
 - #165028 (Update enzyme to fix one bug related to higher-order derivatives)
rust-bors Bot pushed a commit that referenced this pull request Oct 28, 2026
Rollup merge of #162597 - mejrs:ambiguity, r=petrochenkov

raise ambiguity error on attribute macro that could be tool attribute

See #162597 (comment) for clean crater run; the errors are unrelated/spurious.

We need some sort of ambiguity error in other to implement the [register tool rfc](https://rust-lang.github.io/rfcs/3808-register-tool.html#fixing-name-resolution-errors):

> #### Fixing name resolution errors
>
>Note that `register_tool` changes name resolution, and may give errors if you have a crate named `some_tool`.
The compiler will suggest ways to fix the new errors.
>
>If a tool name conflicts with a crate name, you can disambiguate the crate with `::some_tool`:
>```rust
>#![register_tool(some_tool)]
>extern crate some_tool;
>
>#[some_tool::attribute] //~ ERROR: is this the tool or a proc-macro?
>fn bar() {
>    // ...
>}
>
>#[::some_tool::attribute] // OK: This is the proc-macro defined in the crate.
>fn foo() {
>   // ...
>}
>```
>However, if you want to go on to use a tool attribute,
>you must rename the crate so it doesn't conflict:
>```rust
>#![register_tool(some_tool)]
>extern crate some_tool as my_library;
>
>#[some_tool::attribute] // OK: This is the attribute specified by the tool.
>fn bar() {
>    // ...
>}
>```
>Alternatively, if you only want to use lints, you can use `register_lint_tool` instead of `register_tool`, which will avoid resolution errors.
>
>Overlaps like this are expected to be rare in practice.

This PR implements the ambiguity error (**not** the "leading `::` to disambiguate" part).

This is a breaking change if:
- someone has a crate or module named diagnostic|miri|rust_analyzer|clippy|rustfmt and exports an attribute macro from it
- it is then used it as `#[(diagnostic|miri|rust_analyzer|clippy|rustfmt)::attr_macro]` (rather than `use module_or_crate::attr_macro; #[attr_macro]`)
- the same applies for tools registered with `register_tool`, but that's unstable.

See #158146 for context. This is a simpler version of that PR.

This does not implement unconditionally resolving these as tool attributes but does reserve the ability to do so. This would allow things like this to compile:
```rust
mod rustfmt {}

#[rustfmt::skip]
fn main() {}
```

and see also #98291 for a case where it would be nice to assume e.g. `#[rustfmt::skip]` is actually a tool attribute and thus inert.
@rust-bors
rust-bors Bot merged commit b4cf5bf into rust-lang:main Oct 28, 2026
14 checks passed
@rustbot rustbot added this to the 1.101.0 milestone Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. I-lang-radar Items that are on lang's radar and will need eventual work or consideration. missed-reference-pr This language change needed an approved Reference PR and merged without it. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team to-announce Announce this issue on triage meeting

Projects

None yet

Development

Successfully merging this pull request may close these issues.