-
Couldn't load subscription status.
- Fork 1.8k
clippy_utils: make peel_*_ty_refs class of functions a bit more consistent
#15515
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
Conversation
|
r? @Alexendoo rustbot has assigned @Alexendoo. Use |
This comment has been minimized.
This comment has been minimized.
|
Right. I don't really understand why rustfmt is complaining about the line -- it's even marked with EDIT: ah, it's not quite that: what rustfmt actually tries to format is the import line (because of the moved |
|
Also it's a shame that |
5e9ebc1 to
be3f4a8
Compare
Why? If I remember correctly, the results from |
|
Oh is it? That's nice. I guess the other direction ( |
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 like clean ups in general, as they reduce the technical debt.
However, when you use longer commit messages, could you use proper sentences and casing in them? It's ok for the short message to be concise, even though most of us still use proper casing, but longer messages should be both useful and easy to read.
clippy_utils/src/ty/mod.rs
Outdated
| } | ||
| /// Peels off all references on the type. Returns the underlying type and the number of references | ||
| /// removed. | ||
| pub fn peel_middle_ty_refs(mut ty: Ty<'_>) -> (Ty<'_>, usize) { |
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 think peel_and_count_refs would be a better name, we are in the ty module so I don't think it is useful to repeat "middle" here.
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 would agree if this were a method on middle::Ty, but it's a freestanding function which is often imported unqualified, so having some redundancy in the name could be helpful imo, WDYT?
The and_count part I do agree with though.
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.
This is the only part in Clippy where we use "middle_ty" as part of a function name, this is why it looks odd to me. And this is never used in the whole compiler as part of a function name either. In case of an ambiguity, it looks like "hir_ty" is used for rustc_hir::Ty, while "ty" is used for rustc_middle::ty::Ty.
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.
Fair enough. There's also peel_mid_ty_refs_is_mutable right beside it, and I'd like to give it a similarly structured name, but that's a bit hard given that that function does many things at once.
Maybe something like peel_ty_refs_with_count and peel_ty_refs_with_count_is_mutable?
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.
@samueltardieu friendly ping
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.
Or maybe just one function peel_and_count_ty_refs() which is the current peel_mid_ty_refs_is_mutable: it doesn't do much more work, and it is easy to just ignore the mutability result if we don't need it. WDYT?
I still think the "mid" or "middle" part is not useful, including for a standalone function, as there is no risk to use the wrong type thanks to static typing.
Note that you might want to rewrite the function to be non-recursive for the peace of mind, even though for such a simple tail-recursion textbook case I hope that the compiler will always de-recursify it by itself.
Also, a note indicating that if no refs were removed (the count is zero) then Mutability::Mut will always be returned might be useful in the function documentation.
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.
Or maybe just one function
peel_and_count_ty_refs()which is the currentpeel_mid_ty_refs_is_mutable: it doesn't do much more work, and it is easy to just ignore the mutability result if we don't need it. WDYT?
That feels just a bit clunky, but it's probably fine, yeah.
I still think the "mid" or "middle" part is not useful, including for a standalone function, as there is no risk to use the wrong type thanks to static typing.
Yes, I've removed it from the name^^
Note that you might want to rewrite the function to be non-recursive for the peace of mind
Sure
Also, a note indicating that if no refs were removed (the count is zero) then
Mutability::Mutwill always be returned might be useful in the function documentation.
Maybe return an Option<Mutability> instead? I see that most of the callers explicitly check ref_depth after calling this function, but some don't, and I'm actually unsure whether that's a conscious decision or an oversight. Unwrapping an Option would be a more explicit display of intent.
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.
Okay so I did go with the Option approach, and there were only two real unclear cases, unused_peekable, and a helper function in manual_utils, used by both manual_filter and manual_map. Fortunately, all of those had some tests fail when I tried rejecting None (no refs peeled), so I knew that all those lint depended on None being accepted.
Overall, I'm quite happy with this approach, but do let me know what you think
|
r? samueltardieu @rustbot author |
|
Reminder, once the PR becomes ready for a review, use |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
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.
LGTM, just a possibility of shortening the code (and keeping it as clear IMO), tell me what you want to do.
clippy_utils/src/ty/mod.rs
Outdated
| match (mutbl, m) { | ||
| (None, m) => mutbl = Some(*m), | ||
| (_, Mutability::Not) => mutbl = Some(Mutability::Not), | ||
| (_, Mutability::Mut) => {}, | ||
| } |
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.
You can make this more concise with:
| match (mutbl, m) { | |
| (None, m) => mutbl = Some(*m), | |
| (_, Mutability::Not) => mutbl = Some(Mutability::Not), | |
| (_, Mutability::Mut) => {}, | |
| } | |
| mutbl.replace(mutbl.map_or(*m, |x: Mutability| x.min(*m))); |
(and probably get rid of the type by initializing mutbl with None::<Mutability>)
But if you prefer to keep the current form that's fine too, just tell me.
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.
Wow that's terse... But after dabbling with it a bit, I guess that is what my implementation basically boils down to. It kind of looks like Option needs an Entry API, but that would be extremely silly of course.
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.
Oh and I think having the type ascription in the closure helps a bit to not get lost in all the mutbls, so I left it inside.
| /// Peels off all references on the type. Returns the underlying type, the number of references | ||
| /// removed, and, if there were any such references, whether the pointer is ultimately mutable or | ||
| /// not. | ||
| pub fn peel_and_count_ty_refs(mut ty: Ty<'_>) -> (Ty<'_>, usize, Option<Mutability>) { |
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 wonder if a return type of Option<(Ty<'_>, NonZeroUsize, Mutability)> would not be more "logical" here, but that may be an overkill and less readable.
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 was thinking of (Ty<'_>, Option<(NonZeroUsize, Mutability)>) myself, but yeah I think it'd only be more annoying to deal with for most of the callers -- which I guess would speak for having two functions after all, each with the return type more fitting to the use case
|
@rustbot ready |
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.
Looks good to me except for the commits split.
clippy_utils/src/ty/mod.rs
Outdated
| } | ||
|
|
||
| /// Returns the base type for HIR references and pointers. | ||
| pub fn walk_ptrs_hir_ty<'tcx>(ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::Ty<'tcx> { |
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.
Since you end up renaming then removing this function, could you please cleanup the commit stack so that those operations are replaced by just removing the function? No need to complicate things when looking at the history.
I don't know what tool you're using to manage your repository (I use jj, I was also using git branchless at some point), but you should take all your changes and organize them afterwards into several commits, rather than keep details of the development process in the final submission.
Here, in this case, I think the history would better as just one single squashed commit because everything makes sense at once or, at most, two commits with the cleanup of let prefix = match mutability { … }; as a separate commit but I'm not sure that deserves it as the code around has been modified as well.
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 don't know what tool you're using to manage your repository (I use jj, I was also using git branchless at some point), but you should take all your changes and organize them afterwards into several commits, rather than keep details of the development process in the final submission.
Here, in this case, I think the history would better as just one single squashed commit because everything makes sense at once or, at most, two commits
I generally agree, but honestly it's quite keep track of all the confusingly similarly called functions either way... I did squash the commits together, but added a description of all the moves into the commit body.
- give `ty::walk_ptrs_hir_ty` a more standard name `peel_hir_ty_refs_and_ptrs` - move it out of `ty`, since that's for `middle::ty::Ty` - remove `ty::walk_ptrs_ty_depth` for equivalent `peel_middle_ty_refs` - rename the latter into `ty::peel_and_count_ty_refs` - incorporate mutability tracking (from `ty::peel_mid_ty_refs_is_mutable`) into that
|
This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
|
Also it looks like in 473fffb, I wanted to move |
I was looking for the function that peels refs from a type while also returning the number of refs peeled, and it turns out there were actually two of them?? I removed the by far less popular one, and made some other clean-up along the way
changelog: none