@@ -211,10 +211,13 @@ pub trait TypeErrCtxtExt<'tcx> {
211
211
obligation : & PredicateObligation < ' tcx > ,
212
212
err : & mut Diagnostic ,
213
213
trait_pred : ty:: PolyTraitPredicate < ' tcx > ,
214
- ) ;
214
+ ) -> bool ;
215
215
216
216
fn suggest_add_reference_to_arg (
217
+ & self ,
218
+ obligation : & PredicateObligation < ' tcx > ,
217
219
err : & mut Diagnostic ,
220
+ trait_pred : ty:: PolyTraitPredicate < ' tcx > ,
218
221
has_custom_message : bool ,
219
222
) -> bool ;
220
223
@@ -1112,60 +1115,58 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1112
1115
err : & mut Diagnostic ,
1113
1116
trait_pred : ty:: PolyTraitPredicate < ' tcx > ,
1114
1117
) -> bool {
1115
- let span = obligation. cause . span ;
1116
- let body_id = obligation. cause . body_id ;
1117
1118
let self_ty = self . resolve_vars_if_possible ( trait_pred. self_ty ( ) ) ;
1118
1119
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
+ ) ;
1140
1140
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) ,
1166
1161
) ;
1167
- return true ;
1168
1162
}
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 ;
1169
1170
}
1170
1171
false
1171
1172
}
0 commit comments