-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lint when shadowing a glob-reexported item with a local declaration #111336
Comments
I would like to take a stab at this |
(Great blog post!) I wonder if we could go even further here and start linting on any crate export that goes through a glob? (Maybe with some carveouts for, say, modules that reexport an entire other module via glob but include nothing else, or something?) We're definitely not going to prevent glob imports in general -- especially crate-local ones -- but maybe some sort of "look, this glob escapes the crate" checking could make sense. (Like how the pub-in-priv lints are starting to get smarter about whether things are exported, not just how they're tagged in the definition.) |
I'm not familiar with the lint system internals, but from a purely "protecting the author from unpleasantness" perspective I'd be in favor of such lints. I continued looking into glob-related risks after publishing the blog posts, and I've come up with things that are arguably even worse than what the blog post showed. All the examples require globs somewhere, so the globs are the thing to target with lints:
I'm adding examples like these to the test suite of |
Nicely done, @jieyouxu! Excited to try this lint out in nightly! Am I correct in understanding that this lint found some unintentional true-positive instances of glob re-export shadowing in rustc itself, as well as one intentional use as |
Yes,
This is not an intentional use, I was just describing that it was effectively doing |
Awesome, thanks for the clarification. It's not every day one finds things to lint in rustc :) Thanks again for putting this together! |
In this case it's more likely to find something in rustc than in published crates, because this lint is more relevant for crates with stable interfaces, but in rustc the interfaces between crates are almost entirely unstable. |
Code
Current output
Desired output
Rationale and extra context
Similar to #107563
Whereas that issue tackled the case of glob-glob name conflicts, this issue is about glob-vs-local name conflicts in which case the local name shadows the one imported from the glob. This is a footgun and can lead to semver-major breaking changes: uncommenting either line
(1)
or(2)
in the code example above is a major breaking change for the containing crate, since it causes the nameFoo
to stop being exported and makesFoo
become an unnamable (Voldemort) type.This is not a hypothetical issue. Around a year ago, the opencl3 crate seems to have suffered a regression when a large number of its items were accidentally shadowed. Neither code review nor tests seem to have been effective at preventing the regression. The fixing PR for that regression adds a test for the public re-export of one of the affected items.
This seems like a perfect situation for a lint. Shadowing a glob-reexported item with a local declaration is pretty much never what you want. If you wanted an unnamable type, there's a better way, and if you didn't want the item to be reexported then tweak the module structure so it doesn't get reexported.
I plan to publish a blog post with more details about this in a few hours, it will be available at the following link: https://predr.ag/blog/breaking-semver-in-rust-by-adding-private-type-or-import/
Other cases
No response
Anything else?
No response
The text was updated successfully, but these errors were encountered: