@@ -211,10 +211,13 @@ pub trait TypeErrCtxtExt<'tcx> {
211211 obligation : & PredicateObligation < ' tcx > ,
212212 err : & mut Diagnostic ,
213213 trait_pred : ty:: PolyTraitPredicate < ' tcx > ,
214- ) ;
214+ ) -> bool ;
215215
216216 fn suggest_add_reference_to_arg (
217+ & self ,
218+ obligation : & PredicateObligation < ' tcx > ,
217219 err : & mut Diagnostic ,
220+ trait_pred : ty:: PolyTraitPredicate < ' tcx > ,
218221 has_custom_message : bool ,
219222 ) -> bool ;
220223
@@ -1112,60 +1115,58 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
11121115 err : & mut Diagnostic ,
11131116 trait_pred : ty:: PolyTraitPredicate < ' tcx > ,
11141117 ) -> bool {
1115- let span = obligation. cause . span ;
1116- let body_id = obligation. cause . body_id ;
11171118 let self_ty = self . resolve_vars_if_possible ( trait_pred. self_ty ( ) ) ;
11181119 let ty = self . tcx . erase_late_bound_regions ( self_ty) ;
1119- let owner = self . tcx . hir ( ) . get_parent_item ( body_id) ;
1120- if let ObligationCauseCode :: FunctionArgumentObligation { arg_hir_id, .. } = obligation. cause . code ( ) &&
1121- let arg_node = self . tcx . hir ( ) . get ( * arg_hir_id) &&
1122- let Node :: Expr ( Expr { kind : hir:: ExprKind :: Path ( _) , ..} ) = arg_node &&
1123- let Some ( generics) = self . tcx . hir ( ) . get_generics ( owner. def_id ) &&
1124- let ty:: Ref ( _, inner_ty, hir:: Mutability :: Not ) = ty. kind ( ) &&
1125- let ty:: Param ( param) = inner_ty. kind ( ) &&
1126- let Some ( generic_param) =
1127- generics. params . iter ( ) . find ( |p| p. name . ident ( ) . as_str ( ) == param. name . as_str ( ) )
1128- {
1129- let clone_trait = self . tcx . require_lang_item ( LangItem :: Clone , None ) ;
1130- let has_clone = self
1131- . type_implements_trait ( clone_trait, [ ty] , obligation. param_env )
1132- . must_apply_modulo_regions ( ) ;
1133-
1134- let trait_pred_and_suggested_ty =
1135- trait_pred. map_bound ( |trait_pred| ( trait_pred, * inner_ty) ) ;
1136- let new_obligation = self . mk_trait_obligation_with_new_self_ty (
1137- obligation. param_env ,
1138- trait_pred_and_suggested_ty,
1139- ) ;
1120+ let owner = self . tcx . hir ( ) . get_parent_item ( obligation. cause . body_id ) ;
1121+ let Some ( generics) = self . tcx . hir ( ) . get_generics ( owner. def_id ) else { return false } ;
1122+ let ty:: Ref ( _, inner_ty, hir:: Mutability :: Not ) = ty. kind ( ) else { return false } ;
1123+ let ty:: Param ( param) = inner_ty. kind ( ) else { return false } ;
1124+ let Some ( generic_param) = generics. get_named ( param. name ) else { return false } ;
1125+ let ObligationCauseCode :: FunctionArgumentObligation { arg_hir_id, .. } = obligation. cause . code ( ) else { return false } ;
1126+ let arg_node = self . tcx . hir ( ) . get ( * arg_hir_id) ;
1127+ let Node :: Expr ( Expr { kind : hir:: ExprKind :: Path ( _) , ..} ) = arg_node else { return false } ;
1128+
1129+ let clone_trait = self . tcx . require_lang_item ( LangItem :: Clone , None ) ;
1130+ let has_clone = self
1131+ . type_implements_trait ( clone_trait, [ ty] , obligation. param_env )
1132+ . must_apply_modulo_regions ( ) ;
1133+
1134+ let trait_pred_and_suggested_ty =
1135+ trait_pred. map_bound ( |trait_pred| ( trait_pred, * inner_ty) ) ;
1136+ let new_obligation = self . mk_trait_obligation_with_new_self_ty (
1137+ obligation. param_env ,
1138+ trait_pred_and_suggested_ty,
1139+ ) ;
11401140
1141- if has_clone && self . predicate_may_hold ( & new_obligation) {
1142- let clone_bound = generics. bounds_for_param ( generic_param. def_id )
1143- . flat_map ( |bp| bp. bounds )
1144- . any ( |bound| {
1145- if let hir:: GenericBound :: Trait ( hir:: PolyTraitRef { trait_ref, ..} , ..) = bound {
1146- Some ( clone_trait) == trait_ref. trait_def_id ( )
1147- } else {
1148- false
1149- }
1150- } ) ;
1151- if !clone_bound {
1152- suggest_constraining_type_param (
1153- self . tcx ,
1154- generics,
1155- err,
1156- param. name . as_str ( ) ,
1157- "Clone" ,
1158- Some ( clone_trait)
1159- ) ;
1160- }
1161- err. span_suggestion_verbose (
1162- span. shrink_to_hi ( ) ,
1163- "consider using clone here" ,
1164- ".clone()" . to_string ( ) ,
1165- Applicability :: MaybeIncorrect ,
1141+ if has_clone && self . predicate_may_hold ( & new_obligation) {
1142+ let clone_bound = generics
1143+ . bounds_for_param ( generic_param. def_id )
1144+ . flat_map ( |bp| bp. bounds )
1145+ . any ( |bound| {
1146+ if let hir:: GenericBound :: Trait ( hir:: PolyTraitRef { trait_ref, .. } , ..) = bound
1147+ {
1148+ Some ( clone_trait) == trait_ref. trait_def_id ( )
1149+ } else {
1150+ false
1151+ }
1152+ } ) ;
1153+ if !clone_bound {
1154+ suggest_constraining_type_param (
1155+ self . tcx ,
1156+ generics,
1157+ err,
1158+ param. name . as_str ( ) ,
1159+ "Clone" ,
1160+ Some ( clone_trait) ,
11661161 ) ;
1167- return true ;
11681162 }
1163+ err. span_suggestion_verbose (
1164+ obligation. cause . span . shrink_to_hi ( ) ,
1165+ "consider using clone here" ,
1166+ ".clone()" . to_string ( ) ,
1167+ Applicability :: MaybeIncorrect ,
1168+ ) ;
1169+ return true ;
11691170 }
11701171 false
11711172 }
0 commit comments