@@ -13,7 +13,9 @@ use rustc_hir_analysis::astconv::AstConv;
13
13
use rustc_infer:: infer;
14
14
use rustc_infer:: traits:: { self , StatementAsExpression } ;
15
15
use rustc_middle:: lint:: in_external_macro;
16
- use rustc_middle:: ty:: { self , Binder , DefIdTree , IsSuggestable , ToPredicate , Ty } ;
16
+ use rustc_middle:: ty:: {
17
+ self , suggest_constraining_type_params, Binder , DefIdTree , IsSuggestable , ToPredicate , Ty ,
18
+ } ;
17
19
use rustc_session:: errors:: ExprParenthesesNeeded ;
18
20
use rustc_span:: symbol:: sym;
19
21
use rustc_span:: Span ;
@@ -1276,17 +1278,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1276
1278
&& !results. expr_adjustments ( callee_expr) . iter ( ) . any ( |adj| matches ! ( adj. kind, ty:: adjustment:: Adjust :: Deref ( ..) ) )
1277
1279
// Check that we're in fact trying to clone into the expected type
1278
1280
&& self . can_coerce ( * pointee_ty, expected_ty)
1281
+ && let predicate = ty:: Binder :: dummy ( ty:: TraitRef {
1282
+ def_id : clone_trait_did,
1283
+ substs : self . tcx . mk_substs ( [ expected_ty. into ( ) ] . iter ( ) ) ,
1284
+ } )
1285
+ . without_const ( )
1286
+ . to_predicate ( self . tcx )
1279
1287
// And the expected type doesn't implement `Clone`
1280
1288
&& !self . predicate_must_hold_considering_regions ( & traits:: Obligation {
1281
1289
cause : traits:: ObligationCause :: dummy ( ) ,
1282
1290
param_env : self . param_env ,
1283
1291
recursion_depth : 0 ,
1284
- predicate : ty:: Binder :: dummy ( ty:: TraitRef {
1285
- def_id : clone_trait_did,
1286
- substs : self . tcx . mk_substs ( [ expected_ty. into ( ) ] . iter ( ) ) ,
1287
- } )
1288
- . without_const ( )
1289
- . to_predicate ( self . tcx ) ,
1292
+ predicate,
1290
1293
} )
1291
1294
{
1292
1295
diag. span_note (
@@ -1295,6 +1298,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1295
1298
"`{expected_ty}` does not implement `Clone`, so `{found_ty}` was cloned instead"
1296
1299
) ,
1297
1300
) ;
1301
+ let owner = self . tcx . hir ( ) . enclosing_body_owner ( expr. hir_id ) ;
1302
+ if let ty:: Param ( param) = expected_ty. kind ( )
1303
+ && let Some ( generics) = self . tcx . hir ( ) . get_generics ( owner)
1304
+ {
1305
+ suggest_constraining_type_params (
1306
+ self . tcx ,
1307
+ generics,
1308
+ diag,
1309
+ vec ! [ ( param. name. as_str( ) , "Clone" , Some ( clone_trait_did) ) ] . into_iter ( ) ,
1310
+ ) ;
1311
+ } else {
1312
+ self . suggest_derive ( diag, & [ ( predicate, None , None ) ] ) ;
1313
+ }
1298
1314
}
1299
1315
}
1300
1316
0 commit comments