Fix deref field pattern suggestions and improve error messages#154543
Fix deref field pattern suggestions and improve error messages#154543chenyukang wants to merge 1 commit intorust-lang:mainfrom
Conversation
|
r? @fmease rustbot has assigned @fmease. Use Why was this reviewer chosen?The reviewer was selected based on:
|
| | | ||
| LL | match &arg.field { | ||
| | + | ||
| LL | Some(ref s) => s.push('a'), |
There was a problem hiding this comment.
it's perfect if we suggest ref mut here, but current diagnostic is better than &arg.field, because it's at least a right direction, since user will get this if apply ref fix here:
help: consider changing this to be a mutable reference
|
7 | Some(ref mut s) => s.push('a'), //~ ERROR cannot borrow `s` as mutable
| +++
There was a problem hiding this comment.
I wonder how other parts of the crate handle this 🤔 Surely, there's some infrastructure for this already and it's not just people hoping that the user already wrote a mut ^^.
| | | ||
| LL | match &arg.field { | ||
| | + | ||
| LL | Some(ref s) => s.push('a'), |
There was a problem hiding this comment.
I wonder how other parts of the crate handle this 🤔 Surely, there's some infrastructure for this already and it's not just people hoping that the user already wrote a mut ^^.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
9278340 to
946ef2a
Compare
|
This PR was rebased onto a different main 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. |
|
@rustbot ready |
| hir::ExprKind::Index(base, ..) => self | ||
| .infcx | ||
| .tcx | ||
| .typeck(self.mir_def_id()) | ||
| .node_type_opt(base.hir_id) | ||
| .is_some_and(|base_ty| !matches!(base_ty.kind(), ty::Ref(..) | ty::RawPtr(..))), |
There was a problem hiding this comment.
Is this for disqualifying e.g., (&wrap)[0] / wrap[0] where wrap: &_? Do we still suggest &(&wrap)[0] / &wrap[0] as on main? If so, I don't understand the need for the extra check if the resulting suggestion is wrong either way. Did you add this check for a different reason I'm not thinking of?
In any case, this would also disqualify (&mut wrap)[0], wouldn't it, while the mut → ref mut would actually work out perfectly fine; if you keep this check you should probably check that ty::Ref(.., ty::Mutability::Not).
fn take(mut wrap: Wrap<[Option<NonCopy>; 1]>) {
if let Some(mut val) = (&mut wrap)[0] { //~ ERROR cannot move out of dereference of `Wrap<Struct>`
val.0 = ();
}
}| }; | ||
|
|
||
| let projection_qualifies = match expr.kind { | ||
| hir::ExprKind::Field(..) => true, |
There was a problem hiding this comment.
If you're verifying the base type of indexing exprs (about which I have questions), then there should be no reason not to also check the base type of field exprs.
In user code, that situation would arise given e.g., (&wrap).field (❌ disqualify | don't suggest adding &1, don't suggest adding ref); (&mut wrap).field (✅ qualify | don't suggest adding &, do suggest adding ref)
Footnotes
-
I think your PR still suggests that? not sure ↩
There was a problem hiding this comment.
Thanks, this should be addressed now. The check now distinguishes &T from &mut T, so (&mut wrap)[0] still qualifies for the ref mut suggestion.
I also applied the same base-type check to field expr, so shared-ref bases like (&wrap).field are disqualified while (&mut wrap).field still gets the pattern-binding suggestion.
Done some trivial code refactor and sqush into one commit by the way.
946ef2a to
766f6a4
Compare
Fixes #146995