@@ -838,57 +838,78 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
838838 }
839839 }
840840 }
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) =
842842 code. peel_derives_with_predicate ( )
843843 && let hir:: Node :: Expr ( lhs) = self . tcx . hir ( ) . get ( * lhs_hir_id)
844844 {
845845 let trait_pred = predicate. unwrap_or ( trait_pred) ;
846846 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+ ) ;
858857
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) ;
864863
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 {
873894 hir:: ExprKind :: Cast ( _, _) | hir:: ExprKind :: Binary ( _, _, _) => true ,
874895 _ if is_range_literal ( lhs) => true ,
875896 _ => false ,
876897 } ;
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 ;
892913 }
893914 }
894915 }
0 commit comments