Description
While we manually reject1 attribute paths that contain a path segment that starts with the string rustc
2 in order to protect internal attributes
/* assume the user defined `rustc`, `rustc_attr`, `rustcorrosion` or don't */
#[rustc::property] //~ ERROR attributes starting with `rustc` are reserved
#[rustc_attr] //~ ERROR attributes starting with `rustc` are reserved
#[rustcorrosion] //~ ERROR attributes starting with `rustc` are reserved
fn main() {}
we don't have a similar mechanism in place for "lint paths", i.e., paths given as arguments to lint attributes like allow
and deny
. The following code passes compilation without any warnings which I didn't expect:
#![allow(rustc::internals)]
#![deny(rustc::i_do_not_exist)]
Why could this be considered problematic? Rustc should be allowed to remove or rename the lint scope rustc
without impacting stable users. However, if rustc did do so, it would break the code of hypothetical stable users who started to "rely" on these lint paths existing. Why would it break their code? Well, undefined lint scopes currently result in a hard error (unlike unknown lints for which we emit the warn-by-default lint unknown-lints):
#![allow(undefined::lint)] //~ ERROR unknown tool name `undefined` found in scoped lint: `undefined::lint` [E0710]
Of course, that scenario is quite unlikely to happen in practice. This is slightly above P-low territory I'd say.
I think we should reject lint scope rustc
unless internal feature rustc_attrs
is enabled.
Alternatively, we could think about replacing the hard error E0710 with a deny-by-default lint unknown-lint-scopes (rendering "breakages" caused by renaming/removing the lint scope acceptable as per Rust's stability guarantees) but that might do a disservice to tools using register_tool
and wouldn't signal to users that crashes/ICEs caused by running these internal lint passes are not considered bugs.
Footnotes
-
Unless internal feature
rustc_attrs
is enabled. ↩ -
Indeed, this includes "benign" segment idents like
rustcorrosion
which I find questionable personally speaking (I would at least relax it to IS(rustc
) OR STARTSWITH(rustc_
)) since users could theoretically encounter this in the wild if they define or use attribute proc macros. I remember there having been heated discussions about replacing that with a proper "tool" module (ToolMod
) calledrustc
with the main(?) counter argument being "rustc is not a tool" which I do understand. ↩
Activity
[-]Arguably internal lint scope `rustc` isn't protected inside lint paths[/-][+]Arguably-internal lint scope `rustc` isn't protected inside lint paths[/+][-]Arguably-internal lint scope `rustc` isn't protected inside lint paths[/-][+]Arguably-internal lint scope `rustc` isn't protected by a feature gate[/+]jyn514 commentedon Mar 28, 2025
I plan to make an RFC for register_tool soon, I'd appreciate it if you could hold off on making changes for the next couple months.
My initial reaction is that this should behave the same as other lints for unknown tools. but I am considering changing that behavior in the RFC. it would be great to look at the holistic picture here instead of immediately making it a breaking change to match an unstable feature.