Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3012,6 +3012,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
false,
));
}
(

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 think this isn't the right place to add this suggestion, as the suggestion is not about either referencing/dereferencing

hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, inner),
&ty::Ref(_, exp_inner, hir::Mutability::Mut),
&ty::Ref(_, check_inner, hir::Mutability::Not),
) if {
let new_mut_ref =
Ty::new_mut_ref(self.tcx, self.tcx.lifetimes.re_static, check_inner);

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.

Couldn't we use the original lifetime from the expression rather than 'static?

self.may_coerce(new_mut_ref, expected)
|| self.can_eq(self.param_env, check_inner, exp_inner)

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.

Why do we need can_eq? Isn't may_corece enough?

} =>
{
let inner_span = inner.span.find_ancestor_inside(sp).unwrap_or(inner.span);
if sp.contains(inner_span) && sm.is_span_accessible(inner_span) {
let borrow_span = sp.until(inner_span);
return Some((
vec![(borrow_span, "&mut ".to_string())],
"change the borrow to be mutable".to_string(),
Applicability::MachineApplicable,
false,
));
}
}
(_, &ty::Ref(_, exp, _), &ty::Ref(_, check, _)) => match (exp.kind(), check.kind()) {
(&ty::Str, &ty::Array(arr, _) | &ty::Slice(arr)) if arr == self.tcx.types.u8 => {
if let hir::ExprKind::Lit(_) = expr.kind
Expand Down
16 changes: 16 additions & 0 deletions tests/ui/suggestions/suggest-changing-argument-mutability.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
fn takes_mut(_: &mut String) {}

struct S;
impl S {
fn mutate(&mut self, _: &mut i32) {}
}

fn main() {
let mut s = String::new();
takes_mut(&s);
//~^ ERROR mismatched types

let mut val = 42;
S.mutate(&val);
//~^ ERROR mismatched types
}
43 changes: 43 additions & 0 deletions tests/ui/suggestions/suggest-changing-argument-mutability.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
error[E0308]: mismatched types
--> $DIR/suggest-changing-argument-mutability.rs:10:15
|
LL | takes_mut(&s);
| --------- ^^ types differ in mutability
| |
| arguments to this function are incorrect
|
= note: expected mutable reference `&mut String`
found reference `&String`
note: function defined here
--> $DIR/suggest-changing-argument-mutability.rs:1:4
|
LL | fn takes_mut(_: &mut String) {}
| ^^^^^^^^^ ------------------
help: change the borrow to be mutable
|
LL | takes_mut(&mut s);
| +++

error[E0308]: mismatched types
--> $DIR/suggest-changing-argument-mutability.rs:14:14
|
LL | S.mutate(&val);
| ------ ^^^^ types differ in mutability
| |
| arguments to this method are incorrect
|
= note: expected mutable reference `&mut i32`
found reference `&i32`
note: method defined here
--> $DIR/suggest-changing-argument-mutability.rs:5:8
|
LL | fn mutate(&mut self, _: &mut i32) {}
| ^^^^^^ -----------------------
help: change the borrow to be mutable
|
LL | S.mutate(&mut val);
| +++

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0308`.
Loading