@@ -724,6 +724,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
724724 && let hir:: Node :: Expr ( expr) = self . tcx . hir ( ) . get ( * arg_hir_id)
725725 && let Some ( arg_ty) = typeck_results. expr_ty_adjusted_opt ( expr)
726726 {
727+ // Suggest dereferencing the argument to a function/method call if possible
728+
727729 let mut real_trait_pred = trait_pred;
728730 while let Some ( ( parent_code, parent_trait_pred) ) = code. parent ( ) {
729731 code = parent_code;
@@ -763,7 +765,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
763765 {
764766 if steps > 0 {
765767 // Don't care about `&mut` because `DerefMut` is used less
766- // often and user will not expect autoderef happens.
768+ // often and user will not expect that an autoderef happens.
767769 if let Some ( hir:: Node :: Expr ( hir:: Expr {
768770 kind :
769771 hir:: ExprKind :: AddrOf (
@@ -850,6 +852,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
850852 && let hir:: Node :: Expr ( rhs) = self . tcx . hir ( ) . get ( * rhs_hir_id)
851853 && let Some ( rhs_ty) = typeck_results. expr_ty_opt ( rhs)
852854 {
855+ // Suggest dereferencing the LHS, RHS, or both terms of a binop if possible
856+
853857 let trait_pred = predicate. unwrap_or ( trait_pred) ;
854858 let lhs_ty = self . tcx . instantiate_bound_regions_with_erased ( trait_pred. self_ty ( ) ) ;
855859 let lhs_autoderef = ( self . autoderef_steps ) ( lhs_ty) ;
@@ -869,6 +873,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
869873 . rev ( ) ;
870874 if let Some ( ( lsteps, rsteps) ) =
871875 autoderefs. find_map ( |( ( lsteps, ( l_ty, _) ) , ( rsteps, ( r_ty, _) ) ) | {
876+ // Create a new predicate with the dereferenced LHS and RHS
877+ // We simultaneously dereference both sides rather than doing them
878+ // one at a time to account for cases such as &Box<T> == &&T
872879 let trait_pred_and_ty = trait_pred. map_bound ( |inner| {
873880 (
874881 ty:: TraitPredicate {
@@ -909,6 +916,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
909916 expr = inner;
910917 steps -= 1 ;
911918 }
919+ // Empty suggestions with empty spans ICE with debug assertions
912920 if steps == 0 {
913921 return (
914922 msg. trim_end_matches ( " and dereferencing instead" ) ,
@@ -936,6 +944,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
936944 format!( "{derefs}" ) ,
937945 ) ]
938946 } ;
947+ // Empty suggestions with empty spans ICE with debug assertions
939948 if !prefix_span. is_empty ( ) {
940949 suggestion. push ( ( prefix_span, String :: new ( ) ) ) ;
941950 }
0 commit comments