@@ -822,82 +822,72 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
822
822
expr : & hir:: Expr < ' _ > ,
823
823
error : Option < TypeError < ' tcx > > ,
824
824
) -> bool {
825
- let Some ( TypeError :: Sorts ( ExpectedFound { expected, found } ) ) = error else { return false } ;
826
- let ty:: Ref ( _, inner, hir:: Mutability :: Not ) = expected. kind ( ) else { return false } ;
827
- if !self . can_eq ( self . param_env , * inner, found) {
828
- // The difference between the expected and found values isn't one level of borrowing.
829
- return false ;
830
- }
831
- // We have an `ident = expr;` assignment.
832
- let hir:: Node :: Expr ( hir:: Expr { kind : hir:: ExprKind :: Assign ( lhs, rhs, _) , .. } ) =
833
- self . tcx . parent_hir_node ( expr. hir_id )
834
- else {
835
- return false ;
836
- } ;
837
- if rhs. hir_id != expr. hir_id || expected. is_closure ( ) {
838
- return false ;
839
- }
840
- // We are assigning to some binding.
841
- let hir:: ExprKind :: Path ( hir:: QPath :: Resolved (
842
- None ,
843
- hir:: Path { res : hir:: def:: Res :: Local ( hir_id) , .. } ,
844
- ) ) = lhs. kind
845
- else {
846
- return false ;
847
- } ;
848
- let hir:: Node :: Pat ( pat) = self . tcx . hir_node ( * hir_id) else { return false } ;
849
- // The pattern we have is an fn argument.
850
- let hir:: Node :: Param ( hir:: Param { ty_span, .. } ) = self . tcx . parent_hir_node ( pat. hir_id )
851
- else {
852
- return false ;
853
- } ;
854
- let item = self . tcx . hir ( ) . get_parent_item ( pat. hir_id ) ;
855
- let item = self . tcx . hir_owner_node ( item) ;
856
- let Some ( fn_decl) = item. fn_decl ( ) else { return false } ;
825
+ if let Some ( TypeError :: Sorts ( ExpectedFound { expected, found } ) ) = error
826
+ && let ty:: Ref ( _, inner, hir:: Mutability :: Not ) = expected. kind ( )
857
827
858
- // We have a mutable binding in the argument.
859
- let hir:: PatKind :: Binding ( hir:: BindingMode :: MUT , _hir_id, ident, _) = pat. kind else {
860
- return false ;
861
- } ;
828
+ // The difference between the expected and found values is one level of borrowing.
829
+ && self . can_eq ( self . param_env , * inner, found)
862
830
863
- // Look for the type corresponding to the argument pattern we have in the argument list.
864
- let Some ( ty_sugg) = fn_decl
865
- . inputs
866
- . iter ( )
867
- . filter_map ( |ty| {
868
- if ty. span == * ty_span
869
- && let hir:: TyKind :: Ref ( lt, mut_ty) = ty. kind
870
- {
871
- // `&'name Ty` -> `&'name mut Ty` or `&Ty` -> `&mut Ty`
872
- Some ( (
873
- mut_ty. ty . span . shrink_to_lo ( ) ,
874
- format ! (
875
- "{}mut " ,
876
- if lt. ident. span. lo( ) == lt. ident. span. hi( ) { "" } else { " " }
877
- ) ,
878
- ) )
879
- } else {
880
- None
881
- }
882
- } )
883
- . next ( )
884
- else {
885
- return false ;
886
- } ;
887
- let sugg = vec ! [
888
- ty_sugg,
889
- ( pat. span. until( ident. span) , String :: new( ) ) ,
890
- ( lhs. span. shrink_to_lo( ) , "*" . to_string( ) ) ,
891
- ] ;
892
- // We suggest changing the argument from `mut ident: &Ty` to `ident: &'_ mut Ty` and the
893
- // assignment from `ident = val;` to `*ident = val;`.
894
- err. multipart_suggestion_verbose (
895
- "you might have meant to mutate the pointed at value being passed in, instead of \
896
- changing the reference in the local binding",
897
- sugg,
898
- Applicability :: MaybeIncorrect ,
899
- ) ;
900
- return true ;
831
+ // We have an `ident = expr;` assignment.
832
+ && let hir:: Node :: Expr ( hir:: Expr { kind : hir:: ExprKind :: Assign ( lhs, rhs, _) , .. } ) =
833
+ self . tcx . parent_hir_node ( expr. hir_id )
834
+ && rhs. hir_id == expr. hir_id
835
+
836
+ // We are assigning to some binding.
837
+ && let hir:: ExprKind :: Path ( hir:: QPath :: Resolved (
838
+ None ,
839
+ hir:: Path { res : hir:: def:: Res :: Local ( hir_id) , .. } ,
840
+ ) ) = lhs. kind
841
+ && let hir:: Node :: Pat ( pat) = self . tcx . hir_node ( * hir_id)
842
+
843
+ // The pattern we have is an fn argument.
844
+ && let hir:: Node :: Param ( hir:: Param { ty_span, .. } ) =
845
+ self . tcx . parent_hir_node ( pat. hir_id )
846
+ && let item = self . tcx . hir ( ) . get_parent_item ( pat. hir_id )
847
+ && let item = self . tcx . hir_owner_node ( item)
848
+ && let Some ( fn_decl) = item. fn_decl ( )
849
+
850
+ // We have a mutable binding in the argument.
851
+ && let hir:: PatKind :: Binding ( hir:: BindingMode :: MUT , _hir_id, ident, _) = pat. kind
852
+
853
+ // Look for the type corresponding to the argument pattern we have in the argument list.
854
+ && let Some ( ty_sugg) = fn_decl
855
+ . inputs
856
+ . iter ( )
857
+ . filter_map ( |ty| {
858
+ if ty. span == * ty_span
859
+ && let hir:: TyKind :: Ref ( lt, x) = ty. kind
860
+ {
861
+ // `&'name Ty` -> `&'name mut Ty` or `&Ty` -> `&mut Ty`
862
+ Some ( (
863
+ x. ty . span . shrink_to_lo ( ) ,
864
+ format ! (
865
+ "{}mut " ,
866
+ if lt. ident. span. lo( ) == lt. ident. span. hi( ) { "" } else { " " }
867
+ ) ,
868
+ ) )
869
+ } else {
870
+ None
871
+ }
872
+ } )
873
+ . next ( )
874
+ {
875
+ let sugg = vec ! [
876
+ ty_sugg,
877
+ ( pat. span. until( ident. span) , String :: new( ) ) ,
878
+ ( lhs. span. shrink_to_lo( ) , "*" . to_string( ) ) ,
879
+ ] ;
880
+ // We suggest changing the argument from `mut ident: &Ty` to `ident: &'_ mut Ty` and the
881
+ // assignment from `ident = val;` to `*ident = val;`.
882
+ err. multipart_suggestion_verbose (
883
+ "you might have meant to mutate the pointed at value being passed in, instead of \
884
+ changing the reference in the local binding",
885
+ sugg,
886
+ Applicability :: MaybeIncorrect ,
887
+ ) ;
888
+ return true ;
889
+ }
890
+ false
901
891
}
902
892
903
893
fn annotate_alternative_method_deref (
0 commit comments