-   Notifications  You must be signed in to change notification settings 
- Fork 13.9k
 Uplifts and extends clippy::needless-maybe-sized into rustc #145924 
 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
base: master
Are you sure you want to change the base?
  Uplifts and extends clippy::needless-maybe-sized into rustc  #145924 
 Conversation
| This PR modifies  Some changes occurred in src/tools/clippy cc @rust-lang/clippy | 
clippy::needless-maybe-sized into rustc    This comment has been minimized. 
   
 This comment has been minimized.
6f856bf to fe3f26f   Compare   There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed only the Clippy part.
fe3f26f to 7306887   Compare   | Thank you @samueltardieu for your feedback. Regarding the small changes to unrelated files, I believe that was my auto-formatter doing me a disservice, and I believe I have removed said changes from the commits. | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also believe I have addressed the other points you made, but do let me know if anything is amiss.
I think you still have to remove src/tools/clippy/tests/ui/needless_maybe_sized.rs and src/tools/clippy/tests/ui/needless_maybe_sized.stderr.
| As far as I can tell those files have already been removed, let me know if I'm missing anything. Thank you | 
| 
 These have been removed as far as I can tell, they're just showing as moves in Git as similar tests have been added to the rustc ui test suite w/ some changes. | 
| 
 Oh yes, the subpar GitHub diff UI shows this only at the point of destination, not at the point of origin. | 
7306887 to 8446c5a   Compare   | I have added a .fixed file to the tests | 
| @rfcbot fcp merge | 
| I don't want to bikeshed: I like this lint, and I'd rather have the better version of this lint by any name sooner, than a perfectly-named lint later. But I'm currently working on making  I think it's at least a nice-to-have if related SemVer ("across time") and rustc/clippy ("single point in time") lints have similar names. While "unused" seems plausibly reasonable in the "point in time" setting, it would imply a "becomes unused" lint in the SemVer setting. That doesn't seem like the right word at all to me. An example of the SemVer lint would catch e.g. a  I think I'd rather say that  
 I'm in the middle of prototyping something that does that kind of awful lot of querying, for rustdoc JSON and cargo-semver-checks: #143197 Maybe we should talk? :) | 
| 
 If you could elaborate this example, that'd be helpful. In particular, why are we worried about the bound here rather than the change to the trait? | 
| ☔ The latest upstream changes (presumably #147779) made this pull request unmergeable. Please resolve the merge conflicts. | 
| I think the concern is that you may unknowingly start disallowing unsized types in your API when you intended to prevent that with  | 
| 
 This is exactly it. I'm concerned the user will see a rustc/clippy lints for  I like all names @camsteffen and I proposed better than "unused" because they signal a higher severity. I'd still avoid "noop" if possible because I think it has the same risk, just not as much of it. | 
| It's still not coming into focus for me. Is this the concern? If the user has, in v1.1, pub fn f<T: ?Sized>(_: &dyn Deref<Target = T>) {}and then the user tries to ship, in v1.2, pub trait Tr: Sized {} impl<T> Tr for T {} pub fn f<T: ?Sized + Tr>(_: &dyn Deref<Target = T>) {}getting this warning, warning: `?Sized` has no effect due to another bound --> src/main.rs | | pub fn f<T: ?Sized + Tr>(_: &dyn Deref<Target = T>) {} | ^^^^^^ help: remove this unused bound relaxation | = note: generic parameters are assumed to be `Sized` unless the bound is relaxed by writing `?Sized`, but here this has no effect as another bound implies `Sized` = note: `#[warn(unused_relaxed_bounds)]` on by default note: the bound that implies `Sized` is here --> src/main.rs | | pub fn f<T: ?Sized + Tr>(_: &dyn Deref<Target = T>) {} | ^^ note: this bound implies `Sized` | note: `Sized` is implied by `Tr` as `Sized` is a supertrait --> src/main.rs | | pub trait Tr: Sized {} | ^^^^^ note: `Sized` is a supertrait |then the idea is that the user is going to reason, "I added a new  And then  Is that right, or no? | 
| As context, I take for granted that  E.g., if we have, pub trait Tr: Sized { fn f(self) -> u8 { 1 } } impl<T> Tr for T {}and then somewhere else we write, pub struct W<T>(T); impl<T> W<T> { fn f(&self) -> u8 { 2 } } fn main() { println!("{}", W(()).f()); }thinking that, "obviously this should print  warning: method `f` is never used --> src/main.rs:7:8 | 6 | impl<T> W<T> { | ------------ method in this implementation 7 | fn f(&self) -> u8 { 2 } | ^ | = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by defaultthat's a very serious warning. That causes me to sit up in my chair. I think, "if that code isn't being used, then what am I running? Not what I was expecting to run, obviously." Any  One ignores unexpected  | 
| I don't really object to unused personally. I agree whatever lint should make you stop and consider. However, there is an  Responding to your first example, FWIW, a more subtle story would be that you have  | 
| 
 You've then made a breaking change to the trait. At that point, it seems like the use-site bound is the least of one's SemVer problems. | 
| 
 Strongly agreed with this. "Users should take lints seriously" I agree with, but that is not the same statement as "users take lints seriously" which I don't think follows or is accurate in general. A great strength of Rust is setting up users to fall into the pit of success. Using  We should also remember there are other analogous flavors of "you wrote code X which looks like it does Y but it actually does not." What we name this lint will set a precedent for name those future lints. One example with  Here,  
 This does not currently trigger any lint, neither in rustc nor in clippy. I believe it should. By precedent from here, would such a lint then be named  If so, IMHO we'll end up dramatically redefining what the  Not a pit of success choice. 
 I agree, the breaking change is to the trait. But that can be viciously difficult to catch, and I believe we should offer as many opportunities as possible for users to spot and stop this problem. Consider this example: playground Let's assume there are suitable  Furthermore, assume  Say one then changes  
 It's thus all too easy for a trait bound change on a private trait, in an entirely non-pub corner of one's crate, to escalate and ripple across the ecosystem. SemVer breakage is a numbers game. IMHO we should play the numbers by doing our best to block that escalation path in as many places as possible. I believe this includes choosing a name for this lint that makes it harder to (mistakenly) ignore and just suppress away. To see how users might not understand the broader context of a lint and suppress it without due care, we only have to look as far as that  | 
| I'm happy to answer questions and generally engage with the discussion, but I don't want to do so at the cost of shipping this lint at all. As I mentioned, my goal is not to bikeshed this :) I feel I've made my case, and I hope you've found it persuasive. If not, that's fine! Consider my voice heard and, as far as I'm concerned, feel free to proceed! | 
| Thanks for those details and discussion. To answer your question, given this: pub trait Tr: 'static {} pub fn f<'a, T: Tr + 'a>() {} // ^^ help: remove this boundYes, I would suggest that bound is  In some cases where we use "unused" today, one could even argue for stronger terms like "contradictory" or "conflicting". E.g.: #[unsafe(export_name = "foo")] //~ WARNING: unused attribute #[unsafe(export_name = "bar")] //~^ This could be made more subtle with `cfg_attr`, macros, etc. pub fn f() {}Here,  Broadly, I think the purpose of our lint names is to be as precise, concise, and consistent as possible, not to try to hit a particular scariness level. If we want to scare users, the lint output seems a better place to do that than the name. All that said, if in discussion we turn out to not be happy with "unused", here are some other names that have occurred to me: 
 The "ask for what you need" hierarchy of  That's something to think about. Maybe, given our direction here, this new lint could itself be "subsumed". | 
| 
 Ordinarily I would agree with this. But naming a lint  We don't want  
 I'm happy with "subsumed" and it genuinely feels like the best name of the lot. It could also be the name of a new lint group for all these lints, which I think would be a good outcome. | 
| 
 That's a good example. I feel convinced now that  | 
| Given that it sounds like it was news to both of us that an ineffective  | 
| We discussed this in the lang-team meeting and concluded two things 
 In particular, other kinds of redundancy are not clearly worth linting over, for example, given  The "double role" of  We were tempted to say: let's just do it for  | 
| Can somebody update as to this question so we can review again in next triage? Thanks. | 
| Definitely a fan of marking bounds that "don't work", in some form. That said, I'd trying to think of whether there's potentially any reasons that you might want to write something for explicitness even if it's arguably useless. Like  So I'm a fan of linting on the "conflict"-y cases like  As a result I'd be fine focusing to the  | 
| For my part, I'm not sure I would be happy with linting on  At the same time, I'm sympathetic to @scottmcm's point that writing out the subtrait explicitly in the bound can sometimes be desired to improve local reasoning or (as I'd maybe see it) as a static assertion. | 
| 
 I don't think so? The PR description only contains the first case ( 
 I thought the former case is clearly more lintable since there is a possible conflict with the user's intention. | 
| 
 There's a potential conflict with the user's intention with all three cases. In every case, the user is getting at least as much as the user asked for, but not as little as the user asked for with one of the bounds in isolation. | 
| 
 But I think it's quite plausible that a user will think  | 
| Case in point: I've been working on SemVer for 3.5 years, and that was my expectation. I was shocked to find that ?Sized doesn't behave like that. I have to emphasize, I understand the logic and reasoning of why it works the way it does. But without reading about it in depth, I never would have assumed that's how it works. I think the lint should target users' possible misconceptions — we can't brush them away by saying "that's not a reasonable expectation" if that's genuinely how people think it works. | 
| 
 In certain places in the language we add an implicit  The  In place of these  Of course, this then means that, in writing  Since we're looking ahead to this likely model, this is part of the design challenge we're considering here. I mention this and elaborate it a bit as, unless one has been following our design discussions closely, the details of this consideration are likely not obvious. | 
| Upon reading the above discussion I am struggling to work out if a consensus has been reached. As @traviscross pointed out there is currently an inconsistency in the patch. The lint description claims it lints for cases such as  Just to recap, currently the lint will pick up: 
 Which I suppose can be generalised into two groups: 
 If there is rough consensus, I would appreciate if someone could detail the required changes to this PR. | 
| There was not a consensus. We're still working this one out. | 
| 
 Thanks for explaining. I think then that  For  | 
Fixes #140962
Uplift the
clippy::needless_maybe_sizedlint into rustc asredundant_sizedness_bounds. This is useful for #144404 as it deals with redundant bound that would need to be addressed during migration.redundant_sizedness_bounds(warn-by-default)
The
needless_maybe_sizedlint checks that?Sizedbounds aren't redundant. This lint is extended to do the equivalent checks for the sizedness traits introduced by #144404 and thus renamed fromneedless_maybe_sized.Example
Explanation
Relaxing a default
Sizedbound with?Sizeddoes nothing when there's another bound with aSizedsupertrait (Clonein the example above)@rustbot label: +I-lang-nominated
r? @lcnr
cc @flip1995
For Clippy:
changelog: Moves: Uplifted
clippy::needless_maybe_sizedinto rustc asredundant_sizedness_bounds