diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index eb906d5fde7..e8ecb3cb6f3 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -5,16 +5,21 @@ use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorReported};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{AsyncGeneratorKind, GeneratorKind};
+use rustc_infer::infer::TyCtxtInferExt;
+use rustc_infer::traits::ObligationCause;
 use rustc_middle::mir::{
     self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory,
     FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef,
     ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm,
 };
-use rustc_middle::ty::{self, suggest_constraining_type_param, Ty};
+use rustc_middle::ty::{
+    self, suggest_constraining_type_param, suggest_constraining_type_params, PredicateKind, Ty,
+};
 use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
 use rustc_span::symbol::sym;
 use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
 use rustc_trait_selection::infer::InferCtxtExt;
+use rustc_trait_selection::traits::TraitEngineExt as _;
 
 use crate::borrow_set::TwoPhaseActivation;
 use crate::borrowck_errors;
@@ -423,7 +428,63 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                             None,
                         );
                     }
+                } else {
+                    // Try to find predicates on *generic params* that would allow copying `ty`
+
+                    let tcx = self.infcx.tcx;
+                    let generics = tcx.generics_of(self.mir_def_id());
+                    if let Some(hir_generics) = tcx
+                        .typeck_root_def_id(self.mir_def_id().to_def_id())
+                        .as_local()
+                        .and_then(|def_id| tcx.hir().get_generics(def_id))
+                    {
+                        let predicates: Result<Vec<_>, _> = tcx.infer_ctxt().enter(|infcx| {
+                            let mut fulfill_cx =
+                                <dyn rustc_infer::traits::TraitEngine<'_>>::new(infcx.tcx);
+
+                            let copy_did = infcx.tcx.lang_items().copy_trait().unwrap();
+                            let cause = ObligationCause::new(
+                                span,
+                                self.mir_hir_id(),
+                                rustc_infer::traits::ObligationCauseCode::MiscObligation,
+                            );
+                            fulfill_cx.register_bound(&infcx, self.param_env, ty, copy_did, cause);
+                            let errors = fulfill_cx.select_where_possible(&infcx);
+
+                            // Only emit suggestion if all required predicates are on generic
+                            errors
+                                .into_iter()
+                                .map(|err| match err.obligation.predicate.kind().skip_binder() {
+                                    PredicateKind::Trait(predicate) => {
+                                        match predicate.self_ty().kind() {
+                                            ty::Param(param_ty) => Ok((
+                                                generics.type_param(param_ty, tcx),
+                                                predicate
+                                                    .trait_ref
+                                                    .print_only_trait_path()
+                                                    .to_string(),
+                                            )),
+                                            _ => Err(()),
+                                        }
+                                    }
+                                    _ => Err(()),
+                                })
+                                .collect()
+                        });
+
+                        if let Ok(predicates) = predicates {
+                            suggest_constraining_type_params(
+                                tcx,
+                                hir_generics,
+                                &mut err,
+                                predicates.iter().map(|(param, constraint)| {
+                                    (param.name.as_str(), &**constraint, None)
+                                }),
+                            );
+                        }
+                    }
                 }
+
                 let span = if let Some(local) = place.as_local() {
                     let decl = &self.body.local_decls[local];
                     Some(decl.source_info.span)