1+ use hir:: def:: { DefKind , Res } ;
2+ use hir:: {
3+ BindingAnnotation , Expr , ExprKind , FnDecl , FnRetTy , FnSig , Item , ItemKind , Pat , PatKind , Path ,
4+ QPath , TyKind ,
5+ } ;
16use rustc_errors:: { Applicability , Diagnostic , DiagnosticBuilder , ErrorGuaranteed } ;
27use rustc_hir as hir;
38use rustc_hir:: intravisit:: Visitor ;
@@ -780,7 +785,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
780785 // In the future, attempt in all path but initially for RHS of for_loop
781786 fn suggest_similar_mut_method_for_for_loop ( & self , err : & mut Diagnostic , span : Span ) {
782787 use hir:: {
783- BorrowKind , Expr ,
788+ BorrowKind ,
784789 ExprKind :: { AddrOf , Block , Call , MethodCall } ,
785790 } ;
786791
@@ -1104,6 +1109,56 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
11041109 if let Some ( hir_id) = hir_id
11051110 && let Some ( hir:: Node :: Local ( local) ) = hir_map. find ( hir_id)
11061111 {
1112+
1113+ let initial_expression = match local. init . map ( |init| init. kind ) {
1114+ Some ( hir:: ExprKind :: Path ( hir:: QPath :: Resolved ( _, hir:: Path { res : Res :: Local ( id) , ..} ) ) ) => hir_map. find ( * id) ,
1115+ Some ( hir:: ExprKind :: Call ( Expr { kind : ExprKind :: Path ( QPath :: Resolved ( _, Path { res : Res :: Def ( DefKind :: Fn , defid ) , ..} ) , ..) , ..} , .. ) ) => {
1116+ let Some ( local_id) = defid. as_local ( ) else {
1117+ todo ! ( "What do we do here?" )
1118+ } ;
1119+
1120+ hir_map. find_by_def_id ( local_id)
1121+ }
1122+
1123+ _ => None
1124+ } ;
1125+
1126+ let initial_expression_mutability = match initial_expression {
1127+
1128+ Some ( Node :: Pat ( Pat {
1129+ kind : PatKind :: Binding ( BindingAnnotation ( _, mut_ty) , ..) ,
1130+ ..
1131+ } ) ) => * mut_ty,
1132+ Some ( Node :: Item ( Item {
1133+ kind :
1134+ ItemKind :: Fn (
1135+ FnSig {
1136+ decl :
1137+ FnDecl {
1138+ output :
1139+ FnRetTy :: Return ( hir:: Ty {
1140+ kind : TyKind :: Ref ( _, mut_ty) ,
1141+ ..
1142+ } ) ,
1143+ ..
1144+ } ,
1145+ ..
1146+ } ,
1147+ ..,
1148+ ) ,
1149+ ..
1150+ } ) ) => mut_ty. mutbl ,
1151+ _ => Mutability :: Mut , // TODO: this probably is not correct handling of this case.
1152+ } ;
1153+
1154+ // If the inital value of an expression is not mutable then suggesting that the user
1155+ // changes the type of the expression to be mutable is incorrect is it will not help.
1156+ // TODO: Could we provide an alternative suggestions around altering the mutability
1157+ // of the inital value.
1158+ if initial_expression_mutability. is_not ( ) {
1159+ return ;
1160+ }
1161+
11071162 let ( changing, span, sugg) = match local. ty {
11081163 Some ( ty) => ( "changing" , ty. span , message) ,
11091164 None => (
@@ -1112,6 +1167,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
11121167 format ! ( ": {message}" ) ,
11131168 ) ,
11141169 } ;
1170+ // FOUND IT
11151171 err. span_suggestion_verbose (
11161172 span,
11171173 format ! ( "consider {changing} this binding's type" ) ,
0 commit comments