Skip to content

Fix deref field pattern suggestions and improve error messages#154543

Open
chenyukang wants to merge 1 commit intorust-lang:mainfrom
chenyukang:yukang-fix-146995-deref-field-suggestion
Open

Fix deref field pattern suggestions and improve error messages#154543
chenyukang wants to merge 1 commit intorust-lang:mainfrom
chenyukang:yukang-fix-146995-deref-field-suggestion

Conversation

@chenyukang
Copy link
Copy Markdown
Member

@chenyukang chenyukang commented Mar 29, 2026

Fixes #146995

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 29, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Mar 29, 2026

r? @fmease

rustbot has assigned @fmease.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 69 candidates
  • Random selection from 11 candidates

|
LL | match &arg.field {
| +
LL | Some(ref s) => s.push('a'),
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
  |                  +++

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ^^.

Comment thread compiler/rustc_borrowck/src/diagnostics/move_errors.rs
Comment thread tests/ui/borrowck/deref-field-pattern-ref-suggestion-issue-146995.stderr Outdated
|
LL | match &arg.field {
| +
LL | Some(ref s) => s.push('a'),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ^^.

Comment thread compiler/rustc_borrowck/src/diagnostics/move_errors.rs Outdated
Comment thread compiler/rustc_borrowck/src/diagnostics/move_errors.rs
@fmease fmease added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 15, 2026
@rust-log-analyzer

This comment has been minimized.

@rust-bors

This comment has been minimized.

@chenyukang chenyukang force-pushed the yukang-fix-146995-deref-field-suggestion branch from 9278340 to 946ef2a Compare April 19, 2026 14:06
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 19, 2026

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.

@chenyukang
Copy link
Copy Markdown
Member Author

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 21, 2026
Copy link
Copy Markdown
Member

@fmease fmease left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two final questions; then we should be good to go

View changes since this review

Comment on lines +885 to +890
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(..))),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 mutref 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,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

  1. I think your PR still suggests that? not sure

Copy link
Copy Markdown
Member Author

@chenyukang chenyukang Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@fmease fmease added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 23, 2026
@chenyukang chenyukang force-pushed the yukang-fix-146995-deref-field-suggestion branch from 946ef2a to 766f6a4 Compare April 24, 2026 03:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Confusing suggestion when doing a conditional destructuring on a field of Deref struct

4 participants