@@ -724,6 +724,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
724
724
&& let hir:: Node :: Expr ( expr) = self . tcx . hir ( ) . get ( * arg_hir_id)
725
725
&& let Some ( arg_ty) = typeck_results. expr_ty_adjusted_opt ( expr)
726
726
{
727
+ // Suggest dereferencing the argument to a function/method call if possible
728
+
727
729
let mut real_trait_pred = trait_pred;
728
730
while let Some ( ( parent_code, parent_trait_pred) ) = code. parent ( ) {
729
731
code = parent_code;
@@ -763,7 +765,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
763
765
{
764
766
if steps > 0 {
765
767
// 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.
767
769
if let Some ( hir:: Node :: Expr ( hir:: Expr {
768
770
kind :
769
771
hir:: ExprKind :: AddrOf (
@@ -850,6 +852,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
850
852
&& let hir:: Node :: Expr ( rhs) = self . tcx . hir ( ) . get ( * rhs_hir_id)
851
853
&& let Some ( rhs_ty) = typeck_results. expr_ty_opt ( rhs)
852
854
{
855
+ // Suggest dereferencing the LHS, RHS, or both terms of a binop if possible
856
+
853
857
let trait_pred = predicate. unwrap_or ( trait_pred) ;
854
858
let lhs_ty = self . tcx . instantiate_bound_regions_with_erased ( trait_pred. self_ty ( ) ) ;
855
859
let lhs_autoderef = ( self . autoderef_steps ) ( lhs_ty) ;
@@ -869,6 +873,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
869
873
. rev ( ) ;
870
874
if let Some ( ( lsteps, rsteps) ) =
871
875
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
872
879
let trait_pred_and_ty = trait_pred. map_bound ( |inner| {
873
880
(
874
881
ty:: TraitPredicate {
@@ -909,6 +916,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
909
916
expr = inner;
910
917
steps -= 1 ;
911
918
}
919
+ // Empty suggestions with empty spans ICE with debug assertions
912
920
if steps == 0 {
913
921
return (
914
922
msg. trim_end_matches ( " and dereferencing instead" ) ,
@@ -936,6 +944,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
936
944
format!( "{derefs}" ) ,
937
945
) ]
938
946
} ;
947
+ // Empty suggestions with empty spans ICE with debug assertions
939
948
if !prefix_span. is_empty ( ) {
940
949
suggestion. push ( ( prefix_span, String :: new ( ) ) ) ;
941
950
}
0 commit comments