Fix up autoderef when performing mutable auto borrow

This commit is contained in:
Gary Guo 2020-06-15 00:58:37 +01:00
parent fb0793c610
commit 8121d2e057
2 changed files with 15 additions and 5 deletions

View File

@ -119,11 +119,6 @@ fn confirm(
// Create the final `MethodCallee`.
let callee = MethodCallee { def_id: pick.item.def_id, substs: all_substs, sig: method_sig };
if let Some(hir::Mutability::Mut) = pick.autoref {
self.convert_place_derefs_to_mutable(self.self_expr);
}
ConfirmResult { callee, illegal_sized_bound }
}

View File

@ -3183,6 +3183,13 @@ pub fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment<'tcx>>
return;
}
let autoborrow_mut = adj.iter().any(|adj| {
matches!(adj, &Adjustment {
kind: Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Mut { .. })),
..
})
});
match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
Entry::Vacant(entry) => {
entry.insert(adj);
@ -3212,6 +3219,14 @@ pub fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment<'tcx>>
*entry.get_mut() = adj;
}
}
// When there is an auto mutable borrow, it is equivalent to `&mut expr`,
// thus `expr` is ought to be typechecked with needs = [`Needs::MutPlace`].
// However in many cases it might not be checked this way originally, e.g.
// the receiver of a method call. We need to fix them up.
if autoborrow_mut {
self.convert_place_derefs_to_mutable(expr);
}
}
/// Basically whenever we are converting from a type scheme into