@@ -13,7 +13,9 @@ use rustc_hir_analysis::astconv::AstConv;
1313use rustc_infer:: infer;
1414use rustc_infer:: traits:: { self , StatementAsExpression } ;
1515use rustc_middle:: lint:: in_external_macro;
16- use rustc_middle:: ty:: { self , Binder , DefIdTree , IsSuggestable , Ty } ;
16+ use rustc_middle:: ty:: {
17+ self , suggest_constraining_type_params, Binder , DefIdTree , IsSuggestable , ToPredicate , Ty ,
18+ } ;
1719use rustc_session:: errors:: ExprParenthesesNeeded ;
1820use rustc_span:: symbol:: sym;
1921use rustc_span:: Span ;
@@ -1276,15 +1278,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12761278 && !results. expr_adjustments ( callee_expr) . iter ( ) . any ( |adj| matches ! ( adj. kind, ty:: adjustment:: Adjust :: Deref ( ..) ) )
12771279 // Check that we're in fact trying to clone into the expected type
12781280 && self . can_coerce ( * pointee_ty, expected_ty)
1281+ && let trait_ref = ty:: Binder :: dummy ( self . tcx . mk_trait_ref ( clone_trait_did, [ expected_ty] ) )
12791282 // And the expected type doesn't implement `Clone`
12801283 && !self . predicate_must_hold_considering_regions ( & traits:: Obligation :: new (
12811284 self . tcx ,
12821285 traits:: ObligationCause :: dummy ( ) ,
12831286 self . param_env ,
1284- ty:: Binder :: dummy ( self . tcx . mk_trait_ref (
1285- clone_trait_did,
1286- [ expected_ty] ,
1287- ) ) ,
1287+ trait_ref,
12881288 ) )
12891289 {
12901290 diag. span_note (
@@ -1293,6 +1293,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12931293 "`{expected_ty}` does not implement `Clone`, so `{found_ty}` was cloned instead"
12941294 ) ,
12951295 ) ;
1296+ let owner = self . tcx . hir ( ) . enclosing_body_owner ( expr. hir_id ) ;
1297+ if let ty:: Param ( param) = expected_ty. kind ( )
1298+ && let Some ( generics) = self . tcx . hir ( ) . get_generics ( owner)
1299+ {
1300+ suggest_constraining_type_params (
1301+ self . tcx ,
1302+ generics,
1303+ diag,
1304+ vec ! [ ( param. name. as_str( ) , "Clone" , Some ( clone_trait_did) ) ] . into_iter ( ) ,
1305+ ) ;
1306+ } else {
1307+ self . suggest_derive ( diag, & [ ( trait_ref. to_predicate ( self . tcx ) , None , None ) ] ) ;
1308+ }
12961309 }
12971310 }
12981311
0 commit comments