Skip to content

Commit 9b0864d

Browse files
committed
restore missing case, method call on value of map
1 parent efb2ca0 commit 9b0864d

1 file changed

Lines changed: 67 additions & 21 deletions

File tree

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

Lines changed: 67 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -696,32 +696,35 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
696696
}
697697
count
698698
}
699+
700+
// we know ty is a map, with a key type at walk distance 2.
701+
let key_type = self.ty.walk().nth(1).unwrap().expect_ty();
702+
let key_ref_depth = count_ty_refs(key_type);
703+
699704
if let hir::ExprKind::Assign(place, rv, _sp) = expr.kind
700705
&& let hir::ExprKind::Index(val, index, _) = place.kind
701706
&& (expr.span == self.assign_span || place.span == self.assign_span)
702707
{
703-
let ref_depth_difference: usize;
704-
let _index_is_copy_clone: bool;
705-
706-
if let Some(index_ty) =
707-
self.infcx.tcx.typeck(val.hir_id.owner.def_id).expr_ty_opt(index)
708-
{
709-
// we know ty is a map, with a key type at walk distance 2.
710-
let key_type = self.ty.walk().nth(1).unwrap().expect_ty();
711-
let key_ref_depth = count_ty_refs(key_type);
712-
713-
let index_ref_depth = count_ty_refs(index_ty);
714-
ref_depth_difference = index_ref_depth - key_ref_depth; //index should
715-
//be deeper than key
716-
} else {
717-
// no type ?
718-
return;
719-
};
708+
let (prefix, gm_prefix) = {
709+
let ref_depth_difference: usize;
720710

721-
// remove the exessive referencing if necessary, but get_mut requires a ref
722-
let (prefix, gm_prefix) = match ref_depth_difference {
723-
0 => (String::new(), String::from("&")),
724-
n => ("*".repeat(n), "*".repeat(n - 1)),
711+
if let Some(index_ty) =
712+
self.infcx.tcx.typeck(val.hir_id.owner.def_id).expr_ty_opt(index)
713+
{
714+
let index_ref_depth = count_ty_refs(index_ty);
715+
ref_depth_difference = index_ref_depth - key_ref_depth; //index should
716+
//be deeper than key
717+
} else {
718+
// no type ?
719+
// FIXME: unsure how to handle this case
720+
return;
721+
};
722+
723+
// remove the excessive referencing if necessary, but get_mut requires a ref
724+
match ref_depth_difference {
725+
0 => (String::new(), String::from("&")),
726+
n => ("*".repeat(n), "*".repeat(n - 1)),
727+
}
725728
};
726729

727730
self.err.multipart_suggestion(
@@ -778,6 +781,49 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
778781
Applicability::MaybeIncorrect,
779782
);
780783
self.suggested = true;
784+
} else if let hir::ExprKind::MethodCall(_path, receiver, _, sp) = expr.kind
785+
&& let hir::ExprKind::Index(val, index, _) = receiver.kind
786+
&& receiver.span == self.assign_span
787+
{
788+
let gm_prefix = {
789+
let ref_depth_difference: usize;
790+
791+
if let Some(index_ty) =
792+
self.infcx.tcx.typeck(val.hir_id.owner.def_id).expr_ty_opt(index)
793+
{
794+
let index_ref_depth = count_ty_refs(index_ty);
795+
ref_depth_difference = index_ref_depth - key_ref_depth; //index should
796+
//be deeper than key
797+
} else {
798+
// no type ?
799+
// FIXME: unsure how to handle this case
800+
return;
801+
};
802+
803+
// remove the excessive referencing if necessary, but get_mut requires a ref
804+
match ref_depth_difference {
805+
0 => String::from("&"),
806+
n => "*".repeat(n - 1),
807+
}
808+
};
809+
// val[index].path(args..);
810+
self.err.multipart_suggestion(
811+
format!("to modify a `{}` use `.get_mut()`", self.ty),
812+
vec![
813+
(val.span.shrink_to_lo(), "if let Some(val) = ".to_string()),
814+
(
815+
val.span.shrink_to_hi().with_hi(index.span.lo()),
816+
format!(".get_mut({gm_prefix}"),
817+
),
818+
(
819+
index.span.shrink_to_hi().with_hi(receiver.span.hi()),
820+
") { val".to_string(),
821+
),
822+
(sp.shrink_to_hi(), "; }".to_string()),
823+
],
824+
Applicability::MachineApplicable,
825+
);
826+
self.suggested = true;
781827
}
782828
}
783829
}

0 commit comments

Comments
 (0)