Skip to content
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

NLL fails to suggest "try removing &mut here" #54720

Merged
merged 2 commits into from
Oct 3, 2018

Conversation

davidtwco
Copy link
Member

Fixes #51191.

This PR adds try removing `&mut` here suggestions to functions where a mutable borrow is being taken of a &mut self or a self: &mut Self. This PR also enables the suggestion for adding a mut pattern to by-value implicit self arguments without mut patterns already.

r? @nikomatsakis

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Oct 1, 2018
@rust-highfive

This comment has been minimized.

@nikomatsakis
Copy link
Contributor

r=me but the incremental tests are unhappy. Looks like the test just needs to be updated though. You probably just need to change

#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
trait TraitChangeModeSelfOwnToMut: Sized {
    #[rustc_clean(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    #[rustc_dirty(label="HirBody", cfg="cfail2")]
    #[rustc_clean(label="HirBody", cfg="cfail3")]
    fn method(mut self) {}
}

to

#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
trait TraitChangeModeSelfOwnToMut: Sized {
    #[rustc_dirty(label="Hir", cfg="cfail2")] // changed!
    #[rustc_clean(label="Hir", cfg="cfail3")]
    #[rustc_dirty(label="HirBody", cfg="cfail2")]
    #[rustc_clean(label="HirBody", cfg="cfail3")]
    fn method(mut self) {}
}

In particular, in the old system, the Hir didn't reflect the mut in the signature, but now it does.

This commit adds an `ImplicitSelfKind` to the HIR and the MIR that keeps
track of whether a implicit self argument is immutable by-value, mutable
by-value, immutable reference or mutable reference so that the addition
of the `mut` keyword can be suggested for the immutable by-value case.
This commit improves mutability error suggestions by suggesting the
removal of `&mut` where a mutable borrow is being taken of a `&mut self`
or a `self: &mut Self`.
} =>
{
err.span_label(span, format!("cannot {ACT}", ACT = act));
err.span_label(span, "try removing `&mut` here");
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe that if we use local_decl.source_info.span here it would point at &mut self instead of (&mut self), which would let you make it a machine applicable suggestion instead of a label. Changing this will likely require you to change the above condition, but marginally so.

Copy link
Member Author

Choose a reason for hiding this comment

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

I might be misunderstanding but, wouldn't local_decl.source_info.span point to the argument not the use of it as span does?

Copy link
Contributor

Choose a reason for hiding this comment

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

I believe you're right, I misread the code. It'd be nice to get the actual span to get the behavior I wanted, but it might be too hard to do in this case. Don't let it be a blocker.

@nikomatsakis
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Oct 2, 2018

📌 Commit 2be3069 has been approved by nikomatsakis

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 2, 2018
@bors
Copy link
Contributor

bors commented Oct 3, 2018

⌛ Testing commit 2be3069 with merge 6ddab3e...

bors added a commit that referenced this pull request Oct 3, 2018
NLL fails to suggest "try removing `&mut` here"

Fixes #51191.

This PR adds ``try removing `&mut` here`` suggestions to functions where a mutable borrow is being taken of a `&mut self` or a `self: &mut Self`. This PR also enables the suggestion for adding a `mut` pattern to by-value implicit self arguments without `mut` patterns already.

r? @nikomatsakis
@bors
Copy link
Contributor

bors commented Oct 3, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: nikomatsakis
Pushing 6ddab3e to master...

@bors bors merged commit 2be3069 into rust-lang:master Oct 3, 2018
@davidtwco davidtwco deleted the issue-51191 branch October 3, 2018 13:18
@pnkfelix pnkfelix added the A-NLL Area: Non-lexical lifetimes (NLL) label Oct 8, 2018
/// (but not a `self: Xxx` one).
pub has_implicit_self: bool,
/// Does the function have an implicit self?
pub implicit_self: ImplicitSelfKind,
Copy link
Member

Choose a reason for hiding this comment

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

This is a bit sad, I was hoping this could stay out of the HIR permanently.

@@ -583,11 +583,27 @@ pub enum BindingForm<'tcx> {
/// This is a binding for a non-`self` binding, or a `self` that has an explicit type.
Var(VarBindingForm<'tcx>),
/// Binding for a `self`/`&self`/`&mut self` binding where the type is implicit.
ImplicitSelf,
ImplicitSelf(ImplicitSelfKind),
/// Reference used in a guard expression to ensure immutability.
RefForGuard,
}
Copy link
Member

Choose a reason for hiding this comment

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

I guess the ideal of lowering away pattern-matching completely is too naive in the face of diagnostics 😭

/// Represents a `fn x(self);`.
Imm,
/// Represents a `fn x(mut self);`.
Mut,
Copy link
Member

Choose a reason for hiding this comment

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

Can't these two be distinguished by binding_mode?

/// Represents a `fn x(&self);`.
ImmRef,
/// Represents a `fn x(&mut self);`.
MutRef,
Copy link
Member

Choose a reason for hiding this comment

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

Can't these two be distinguished by type? (maybe even distinguish &self from self by type?)

bors added a commit to rust-lang-ci/rust that referenced this pull request Oct 8, 2020
Suggest removing `&mut` from a `&mut borrow`

Modify the code added in rust-lang#54720.

Closes  rust-lang#75871
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-NLL Area: Non-lexical lifetimes (NLL) S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants