1- use hir:: ExprKind ;
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+ } ;
26use rustc_errors:: { Applicability , Diagnostic , DiagnosticBuilder , ErrorGuaranteed } ;
37use rustc_hir as hir;
48use rustc_hir:: intravisit:: Visitor ;
@@ -854,7 +858,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
854858 // In the future, attempt in all path but initially for RHS of for_loop
855859 fn suggest_similar_mut_method_for_for_loop ( & self , err : & mut Diagnostic , span : Span ) {
856860 use hir:: {
857- BorrowKind , Expr ,
861+ BorrowKind ,
858862 ExprKind :: { AddrOf , Block , Call , MethodCall } ,
859863 } ;
860864
@@ -1216,6 +1220,56 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
12161220 if let Some ( hir_id) = hir_id
12171221 && let Some ( hir:: Node :: Local ( local) ) = hir_map. find ( hir_id)
12181222 {
1223+
1224+ let initial_expression = match local. init . map ( |init| init. kind ) {
1225+ Some ( hir:: ExprKind :: Path ( hir:: QPath :: Resolved ( _, hir:: Path { res : Res :: Local ( id) , ..} ) ) ) => hir_map. find ( * id) ,
1226+ Some ( hir:: ExprKind :: Call ( Expr { kind : ExprKind :: Path ( QPath :: Resolved ( _, Path { res : Res :: Def ( DefKind :: Fn , defid ) , ..} ) , ..) , ..} , .. ) ) => {
1227+ let Some ( local_id) = defid. as_local ( ) else {
1228+ todo ! ( "What do we do here?" )
1229+ } ;
1230+
1231+ hir_map. find_by_def_id ( local_id)
1232+ }
1233+
1234+ _ => None
1235+ } ;
1236+
1237+ let initial_expression_mutability = match initial_expression {
1238+
1239+ Some ( Node :: Pat ( Pat {
1240+ kind : PatKind :: Binding ( BindingAnnotation ( _, mut_ty) , ..) ,
1241+ ..
1242+ } ) ) => * mut_ty,
1243+ Some ( Node :: Item ( Item {
1244+ kind :
1245+ ItemKind :: Fn (
1246+ FnSig {
1247+ decl :
1248+ FnDecl {
1249+ output :
1250+ FnRetTy :: Return ( hir:: Ty {
1251+ kind : TyKind :: Ref ( _, mut_ty) ,
1252+ ..
1253+ } ) ,
1254+ ..
1255+ } ,
1256+ ..
1257+ } ,
1258+ ..,
1259+ ) ,
1260+ ..
1261+ } ) ) => mut_ty. mutbl ,
1262+ _ => Mutability :: Mut , // TODO: this probably is not correct handling of this case.
1263+ } ;
1264+
1265+ // If the inital value of an expression is not mutable then suggesting that the user
1266+ // changes the type of the expression to be mutable is incorrect is it will not help.
1267+ // TODO: Could we provide an alternative suggestions around altering the mutability
1268+ // of the inital value.
1269+ if initial_expression_mutability. is_not ( ) {
1270+ return ;
1271+ }
1272+
12191273 let ( changing, span, sugg) = match local. ty {
12201274 Some ( ty) => ( "changing" , ty. span , message) ,
12211275 None => (
@@ -1224,6 +1278,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
12241278 format ! ( ": {message}" ) ,
12251279 ) ,
12261280 } ;
1281+ // FOUND IT
12271282 err. span_suggestion_verbose (
12281283 span,
12291284 format ! ( "consider {changing} this binding's type" ) ,
0 commit comments