@@ -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