Note when a a move/borrow error is caused by a deref coercion

Fixes #73268

When a deref coercion occurs, we may end up with a move error if the
base value has been partially moved out of. However, we do not indicate
anywhere that a deref coercion is occuring, resulting in an error
message with a confusing span.

This PR adds an explicit note to move errors when a deref coercion is
involved. We mention the name of the type that the deref-coercion
resolved to, as well as the `Deref::Target` associated type being used.
This commit is contained in:
Aaron Hill 2020-07-25 07:04:13 -04:00
parent a1947b3f9e
commit d18b4bb7a7
No known key found for this signature in database
GPG key ID: B4087E510E98B164
23 changed files with 250 additions and 54 deletions

View file

@ -27,6 +27,7 @@ pub struct Autoderef<'a, 'tcx> {
// Meta infos:
infcx: &'a InferCtxt<'a, 'tcx>,
span: Span,
overloaded_span: Span,
body_id: hir::HirId,
param_env: ty::ParamEnv<'tcx>,
@ -98,10 +99,12 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
body_id: hir::HirId,
span: Span,
base_ty: Ty<'tcx>,
overloaded_span: Span,
) -> Autoderef<'a, 'tcx> {
Autoderef {
infcx,
span,
overloaded_span,
body_id,
param_env,
state: AutoderefSnapshot {
@ -190,6 +193,10 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
self.span
}
pub fn overloaded_span(&self) -> Span {
self.overloaded_span
}
pub fn reached_recursion_limit(&self) -> bool {
self.state.reached_recursion_limit
}

View file

@ -483,7 +483,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
};
if let ty::Ref(region, base_ty, mutbl) = *real_ty.kind() {
let mut autoderef = Autoderef::new(self, param_env, body_id, span, base_ty);
let mut autoderef = Autoderef::new(self, param_env, body_id, span, base_ty, span);
if let Some(steps) = autoderef.find_map(|(ty, steps)| {
// Re-add the `&`
let ty = self.tcx.mk_ref(region, TypeAndMut { ty, mutbl });