@@ -838,57 +838,78 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
838
838
}
839
839
}
840
840
}
841
- } else if let ( ObligationCauseCode :: BinOp { lhs_hir_id, .. } , predicate) =
841
+ } else if let ( ObligationCauseCode :: BinOp { lhs_hir_id, rhs_hir_id : Some ( _rhs_hir_id ) , .. } , predicate) =
842
842
code. peel_derives_with_predicate ( )
843
843
&& let hir:: Node :: Expr ( lhs) = self . tcx . hir ( ) . get ( * lhs_hir_id)
844
844
{
845
845
let trait_pred = predicate. unwrap_or ( trait_pred) ;
846
846
let lhs_ty = self . tcx . instantiate_bound_regions_with_erased ( trait_pred. self_ty ( ) ) ;
847
- if let ty:: Ref ( ..) = * lhs_ty. kind ( ) {
848
- let lhs_autoderef = ( self . autoderef_steps ) ( lhs_ty) ;
849
- if let Some ( steps) =
850
- lhs_autoderef. into_iter ( ) . enumerate ( ) . find_map ( |( steps, ( ty, obligations) ) | {
851
- // Remapping bound vars here
852
- let trait_pred_and_ty =
853
- trait_pred. map_bound ( |inner_trait_pred| ( inner_trait_pred, ty) ) ;
854
- let obligation = self . mk_trait_obligation_with_new_self_ty (
855
- obligation. param_env ,
856
- trait_pred_and_ty,
857
- ) ;
847
+ let lhs_autoderef = ( self . autoderef_steps ) ( lhs_ty) ;
848
+ if let Some ( mut steps) =
849
+ lhs_autoderef. into_iter ( ) . enumerate ( ) . find_map ( |( steps, ( ty, obligations) ) | {
850
+ // Remapping bound vars here
851
+ let trait_pred_and_ty =
852
+ trait_pred. map_bound ( |inner_trait_pred| ( inner_trait_pred, ty) ) ;
853
+ let obligation = self . mk_trait_obligation_with_new_self_ty (
854
+ obligation. param_env ,
855
+ trait_pred_and_ty,
856
+ ) ;
858
857
859
- let may_hold = obligations
860
- . iter ( )
861
- . chain ( [ & obligation] )
862
- . all ( |obligation| self . predicate_may_hold ( obligation) )
863
- . then_some ( steps) ;
858
+ let may_hold = obligations
859
+ . iter ( )
860
+ . chain ( [ & obligation] )
861
+ . all ( |obligation| self . predicate_may_hold ( obligation) )
862
+ . then_some ( steps) ;
864
863
865
- may_hold
866
- } )
867
- {
868
- if steps > 0 {
869
- // Suggest `&&**` rather than `**&&`
870
- let span = lhs. peel_borrows ( ) . span ;
871
- let derefs = "*" . repeat ( steps) ;
872
- let needs_parens = match lhs. kind {
864
+ may_hold
865
+ } )
866
+ {
867
+ if steps > 0 {
868
+ // Suggest `&*` rather than `*&`
869
+ let span = lhs. peel_borrows ( ) . span ;
870
+
871
+ let mut lhs = lhs;
872
+ let mut prefix_span = lhs. span . shrink_to_lo ( ) ;
873
+ let mut msg = "consider dereferencing here" ;
874
+ if let hir:: ExprKind :: AddrOf ( _, _, inner) = lhs. kind {
875
+ msg = "consider removing the borrow and dereferencing instead" ;
876
+ if let hir:: ExprKind :: AddrOf ( ..) = inner. kind {
877
+ msg = "consider removing the borrows and dereferencing instead" ;
878
+ }
879
+ }
880
+ while let hir:: ExprKind :: AddrOf ( _, _, inner) = lhs. kind
881
+ && steps > 0
882
+ {
883
+ prefix_span = prefix_span. with_hi ( inner. span . lo ( ) ) ;
884
+ lhs = inner;
885
+ steps -= 1 ;
886
+ }
887
+ if steps == 0 {
888
+ msg = msg. trim_end_matches ( " and dereferencing instead" ) ;
889
+ }
890
+
891
+ let derefs = "*" . repeat ( steps) ;
892
+ let needs_parens = steps > 0
893
+ && match lhs. kind {
873
894
hir:: ExprKind :: Cast ( _, _) | hir:: ExprKind :: Binary ( _, _, _) => true ,
874
895
_ if is_range_literal ( lhs) => true ,
875
896
_ => false ,
876
897
} ;
877
- let suggestion = if needs_parens {
878
- vec ! [
879
- ( span. shrink_to_lo( ) , format!( "{derefs}(" ) ) ,
880
- ( span. shrink_to_hi( ) , ")" . to_string( ) ) ,
881
- ]
882
- } else {
883
- vec ! [ ( span. shrink_to_lo( ) , format!( "{derefs}" ) ) ]
884
- } ;
885
- err . multipart_suggestion_verbose (
886
- "consider dereferencing here" ,
887
- suggestion ,
888
- Applicability :: MachineApplicable ,
889
- ) ;
890
- return true ;
891
- }
898
+ let mut suggestion = if needs_parens {
899
+ vec ! [
900
+ ( span. shrink_to_lo( ) , format!( "{derefs}(" ) ) ,
901
+ ( span. shrink_to_hi( ) , ")" . to_string( ) ) ,
902
+ ]
903
+ } else {
904
+ vec ! [ ( span. shrink_to_lo( ) , format!( "{derefs}" ) ) ]
905
+ } ;
906
+ suggestion . push ( ( prefix_span , "" . to_string ( ) ) ) ;
907
+ err . multipart_suggestion_verbose (
908
+ msg ,
909
+ suggestion ,
910
+ Applicability :: MachineApplicable ,
911
+ ) ;
912
+ return true ;
892
913
}
893
914
}
894
915
}
0 commit comments