Repository navigation
raise ambiguity error on attribute macro that could be tool attribute - #162597
Conversation
|
@bors try |
This comment has been minimized.
This comment has been minimized.
raise ambiguity error on attribute macro that could be tool attribute
This comment has been minimized.
This comment has been minimized.
|
@bors try |
This comment has been minimized.
This comment has been minimized.
raise ambiguity error on attribute macro that could be tool attribute
|
@craterbot check |
|
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
|
🚧 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
|
🎉 Experiment
Footnotes
|
|
Looks like the crater run is clean, so I guess we can do this (If the lang team agrees, of course) |
|
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 |
This comment has been minimized.
This comment has been minimized.
|
Reference PR is open at rust-lang/reference#2397 |
|
@bors r+ |
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.
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.
…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.
…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)
…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)
…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)
…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)
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.
raise ambiguity error on attribute macro that could be tool attribute See rust-lang/rust#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/rust#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/rust#98291 for a case where it would be nice to assume e.g. `#[rustfmt::skip]` is actually a tool attribute and thus inert.
…uwer Rollup of 21 pull requests Successful merges: - rust-lang/rust#159580 (Reject cfg on expressions that cannot be safely removed) - rust-lang/rust#162597 (raise ambiguity error on attribute macro that could be tool attribute) - rust-lang/rust#162808 (Enable `--generate-link-to-definition` rustdoc option on std docs) - rust-lang/rust#163059 (Recover invalid return type until `{`, `}` or `;`) - rust-lang/rust#163672 (Use runCodeGen Abstraction for new LLVM) - rust-lang/rust#164028 (Add a future incompat warning for #[no_link]) - rust-lang/rust#164188 (Suggest adding lifetime for `dyn Trait` in return type) - rust-lang/rust#164345 (fix: handle `false` in root contexts) - rust-lang/rust#164494 (drop ands which are a superset of other ands) - rust-lang/rust#164785 (delegation: emit error when there is no field for `Self` mapping) - rust-lang/rust#164799 (Don't use `IntoIterator` in parallel API) - rust-lang/rust#164871 (Refactor call argument codegen) - rust-lang/rust#164648 (parse inline and rustc_force_inline with same parser) - rust-lang/rust#164811 (fix: Prevent ICE when comparing EII impl against generic declaration) - rust-lang/rust#164900 (make tool_attrs method to retrieve tool attributes.) - rust-lang/rust#164993 (copy_nonoverlapping: dont skip ovelrap check when src is fully uninit) - rust-lang/rust#164996 (miri: add missing alignment check in write_bytes) - rust-lang/rust#165012 (Remove Span::eq_ctxt()) - rust-lang/rust#165013 ([tiny] Add missing backticks around lifetime name) - rust-lang/rust#165024 (rustdoc-search: rank re-export lower) - rust-lang/rust#165028 (Update enzyme to fix one bug related to higher-order derivatives)
…tebank Add a lint helper attribute namespace (and also port over three rustc lint attributes, as proof of concept) This PR implements parsing for the `lint` tool namespace (`#[lint::attribute]`) but doesn't add it as a builtin tool, so `#![register_tool(lint)]` is also required to use it. It raises an error on an unknown attribute within that namespace. The primary motivations for creating this namespace are: - creating a place for attributes like `trivial_field_reads` (rust-lang#160666) and `c_buffer_length` (rust-lang#162565) to live, as these IMO do not belong in the diagnostic namespace. - make it easier to unstably land lints and lint helper attributes, as these currently suffer from the "any new built-in attribute is a breaking change" problem. - implementing (part of) rust-lang#160808 ### What is a "lint helper" Attributes that change how or if a lint is emitted. Think of many of the internal attributes like `#[rustc_as_ptr]` , `#[rustc_pass_by_value]` etc. Other examples are `#[deprecated]` and `#[must_not_suspend]`. Even `clippy` has such a thing: `#[clippy::format_args]`. ### On breaking changes This doesn't add `lint` as a built-in tool (like `diagnostic`, `rustfmt`, `clippy` etc are) so this pr is not a breaking change. The breaking changes are opt-in by using `#![register_tool(lint)]` in the crate root which is unstable at this time. The way this PR is implemented means that, even if users could use `#![register_tool(lint)]` stably, they cannot stably use the namespace because an unknown attribute is an error and all valid attributes in it, at this time, are also feature gated. So there is no commitment to stability until we choose to stabilize an attribute in it. ### Going forward We can require using `#![register_tool(lint)]` indefinitely. It's possible to not require this this by adding `lint` as a builtin tool, but this (assuming rust-lang#162597) breaks ```rust #[lint::as_ptr] struct Foo; mod lint { pub use derive as as_ptr; } ``` However as [nobody on github does this](https://github.com/search?type=code&q=%22%23%5Blint%3A%3A%22+language%3ARust) it's probably only theoretically breaking. It's non-breaking to add it across an edition. r? @estebank cc @WaffleLapkin @petrochenkov
…r, r=petrochenkov Make `no_implicit_prelude` not suppress tool attributes Implements part of the `register_tool` rfc, [RFC 3808](https://rust-lang.github.io/rfcs/3808-register-tool.html): > Today, #![no_implicit_prelude] suppresses the tool attribute prelude but does not suppress the lint prelude (e.g., #[allow(clippy::foo)] continues to work). Under this RFC, neither prelude is suppressed by #![no_implicit_prelude]. This is technically a breaking change since it can produce new ambiguity errors in stable code. (The breaking change is already taken care of in rust-lang#162597, the ambiguity error is raised regardless of whether the `no_implicit_prelude` attribute is used) Currently, the following code errors. After this PR, it will start compiling. ```rust #![no_implicit_prelude] #![feature(register_tool)] #![register_tool(my_tool)] #[my_tool::attr] // ERROR cannot find module or crate `my_tool` in this scope #[rustfmt::skip] // ERROR cannot find module or crate `rustfmt` in this scope struct X; ``` Reference PR: rust-lang/reference#2404 r? petrochenkov
…tebank Add a lint helper attribute namespace (and also port over three rustc lint attributes, as proof of concept) This PR implements parsing for the `lint` tool namespace (`#[lint::attribute]`) but doesn't add it as a builtin tool, so `#![register_tool(lint)]` is also required to use it. It raises an error on an unknown attribute within that namespace. The primary motivations for creating this namespace are: - creating a place for attributes like `trivial_field_reads` (rust-lang#160666) and `c_buffer_length` (rust-lang#162565) to live, as these IMO do not belong in the diagnostic namespace. - make it easier to unstably land lints and lint helper attributes, as these currently suffer from the "any new built-in attribute is a breaking change" problem. - implementing (part of) rust-lang#160808 ### What is a "lint helper" Attributes that change how or if a lint is emitted. Think of many of the internal attributes like `#[rustc_as_ptr]` , `#[rustc_pass_by_value]` etc. Other examples are `#[deprecated]` and `#[must_not_suspend]`. Even `clippy` has such a thing: `#[clippy::format_args]`. ### On breaking changes This doesn't add `lint` as a built-in tool (like `diagnostic`, `rustfmt`, `clippy` etc are) so this pr is not a breaking change. The breaking changes are opt-in by using `#![register_tool(lint)]` in the crate root which is unstable at this time. The way this PR is implemented means that, even if users could use `#![register_tool(lint)]` stably, they cannot stably use the namespace because an unknown attribute is an error and all valid attributes in it, at this time, are also feature gated. So there is no commitment to stability until we choose to stabilize an attribute in it. ### Going forward We can require using `#![register_tool(lint)]` indefinitely. It's possible to not require this this by adding `lint` as a builtin tool, but this (assuming rust-lang#162597) breaks ```rust #[lint::as_ptr] struct Foo; mod lint { pub use derive as as_ptr; } ``` However as [nobody on github does this](https://github.com/search?type=code&q=%22%23%5Blint%3A%3A%22+language%3ARust) it's probably only theoretically breaking. It's non-breaking to add it across an edition. r? @estebank cc @WaffleLapkin @petrochenkov
…r, r=petrochenkov Make `no_implicit_prelude` not suppress tool attributes Implements part of the `register_tool` rfc, [RFC 3808](https://rust-lang.github.io/rfcs/3808-register-tool.html): > Today, #![no_implicit_prelude] suppresses the tool attribute prelude but does not suppress the lint prelude (e.g., #[allow(clippy::foo)] continues to work). Under this RFC, neither prelude is suppressed by #![no_implicit_prelude]. This is technically a breaking change since it can produce new ambiguity errors in stable code. (The breaking change is already taken care of in rust-lang#162597, the ambiguity error is raised regardless of whether the `no_implicit_prelude` attribute is used) Currently, the following code errors. After this PR, it will start compiling. ```rust #![no_implicit_prelude] #![feature(register_tool)] #![register_tool(my_tool)] #[my_tool::attr] // ERROR cannot find module or crate `my_tool` in this scope #[rustfmt::skip] // ERROR cannot find module or crate `rustfmt` in this scope struct X; ``` Reference PR: rust-lang/reference#2404 r? petrochenkov
…tebank Add a lint helper attribute namespace (and also port over three rustc lint attributes, as proof of concept) This PR implements parsing for the `lint` tool namespace (`#[lint::attribute]`) but doesn't add it as a builtin tool, so `#![register_tool(lint)]` is also required to use it. It raises an error on an unknown attribute within that namespace. The primary motivations for creating this namespace are: - creating a place for attributes like `trivial_field_reads` (rust-lang#160666) and `c_buffer_length` (rust-lang#162565) to live, as these IMO do not belong in the diagnostic namespace. - make it easier to unstably land lints and lint helper attributes, as these currently suffer from the "any new built-in attribute is a breaking change" problem. - implementing (part of) rust-lang#160808 ### What is a "lint helper" Attributes that change how or if a lint is emitted. Think of many of the internal attributes like `#[rustc_as_ptr]` , `#[rustc_pass_by_value]` etc. Other examples are `#[deprecated]` and `#[must_not_suspend]`. Even `clippy` has such a thing: `#[clippy::format_args]`. ### On breaking changes This doesn't add `lint` as a built-in tool (like `diagnostic`, `rustfmt`, `clippy` etc are) so this pr is not a breaking change. The breaking changes are opt-in by using `#![register_tool(lint)]` in the crate root which is unstable at this time. The way this PR is implemented means that, even if users could use `#![register_tool(lint)]` stably, they cannot stably use the namespace because an unknown attribute is an error and all valid attributes in it, at this time, are also feature gated. So there is no commitment to stability until we choose to stabilize an attribute in it. ### Going forward We can require using `#![register_tool(lint)]` indefinitely. It's possible to not require this this by adding `lint` as a builtin tool, but this (assuming rust-lang#162597) breaks ```rust #[lint::as_ptr] struct Foo; mod lint { pub use derive as as_ptr; } ``` However as [nobody on github does this](https://github.com/search?type=code&q=%22%23%5Blint%3A%3A%22+language%3ARust) it's probably only theoretically breaking. It's non-breaking to add it across an edition. r? @estebank cc @WaffleLapkin @petrochenkov
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:
This PR implements the ambiguity error (not the "leading
::to disambiguate" part).This is a breaking change if:
#[(diagnostic|miri|rust_analyzer|clippy|rustfmt)::attr_macro](rather thanuse module_or_crate::attr_macro; #[attr_macro])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:
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.