@@ -4069,15 +4069,46 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
40694069 ) )
40704070 && expr. span . hi ( ) != rcvr. span . hi ( )
40714071 {
4072- err. span_suggestion_verbose (
4073- expr. span . with_lo ( rcvr. span . hi ( ) ) ,
4074- format ! (
4075- "consider removing this method call, as the receiver has type `{ty}` and \
4076- `{pred}` trivially holds",
4077- ) ,
4078- "" ,
4079- Applicability :: MaybeIncorrect ,
4080- ) ;
4072+ let should_sugg = match tcx. hir_node ( call_hir_id) {
4073+ Node :: Expr ( hir:: Expr {
4074+ kind : hir:: ExprKind :: MethodCall ( _, call_receiver, _, _) ,
4075+ ..
4076+ } ) if let Some ( ( DefKind :: AssocFn , did) ) =
4077+ typeck_results. type_dependent_def ( call_hir_id)
4078+ && call_receiver. hir_id == arg_hir_id =>
4079+ {
4080+ // Avoid suggesting removing a method call if the argument is the receiver of the parent call and
4081+ // removing the receiver would make the method inaccessible. i.e. `x.a().b()`, suggesting removing
4082+ // `.a()` could change the type and make `.b()` unavailable.
4083+ if tcx. inherent_impl_of_assoc ( did) . is_some ( ) {
4084+ // if we're calling an inherent impl method, just try to make sure that the receiver type stays the same.
4085+ Some ( ty) == typeck_results. node_type_opt ( arg_hir_id)
4086+ } else {
4087+ // we're calling a trait method, so we just check removing the method call still satisfies the trait.
4088+ let trait_id = tcx
4089+ . trait_of_assoc ( did)
4090+ . unwrap_or_else ( || tcx. impl_trait_id ( tcx. parent ( did) ) ) ;
4091+ let args = typeck_results. node_args ( call_hir_id) ;
4092+ let tr = ty:: TraitRef :: from_assoc ( tcx, trait_id, args)
4093+ . with_replaced_self_ty ( tcx, ty) ;
4094+ self . type_implements_trait ( tr. def_id , tr. args , param_env)
4095+ . must_apply_modulo_regions ( )
4096+ }
4097+ }
4098+ _ => true ,
4099+ } ;
4100+
4101+ if should_sugg {
4102+ err. span_suggestion_verbose (
4103+ expr. span . with_lo ( rcvr. span . hi ( ) ) ,
4104+ format ! (
4105+ "consider removing this method call, as the receiver has type `{ty}` and \
4106+ `{pred}` trivially holds",
4107+ ) ,
4108+ "" ,
4109+ Applicability :: MaybeIncorrect ,
4110+ ) ;
4111+ }
40814112 }
40824113 if let hir:: Expr { kind : hir:: ExprKind :: Block ( block, _) , .. } = expr {
40834114 let inner_expr = expr. peel_blocks ( ) ;
0 commit comments