@@ -58,6 +58,7 @@ use rustc_middle::lint::in_external_macro;
5858use rustc_middle:: ty:: layout:: LayoutOf ;
5959use rustc_middle:: ty:: print:: with_no_trimmed_paths;
6060use rustc_middle:: ty:: GenericArgKind ;
61+ use rustc_middle:: ty:: ToPredicate ;
6162use rustc_middle:: ty:: TypeVisitableExt ;
6263use rustc_middle:: ty:: { self , Ty , TyCtxt , VariantDef } ;
6364use rustc_session:: config:: ExpectedValues ;
@@ -68,6 +69,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
6869use rustc_span:: { BytePos , InnerSpan , Span } ;
6970use rustc_target:: abi:: Abi ;
7071use rustc_trait_selection:: infer:: { InferCtxtExt , TyCtxtInferExt } ;
72+ use rustc_trait_selection:: traits:: query:: evaluate_obligation:: InferCtxtExt as _;
7173use rustc_trait_selection:: traits:: { self , misc:: type_allowed_to_implement_copy} ;
7274
7375use crate :: nonstandard_style:: { method_context, MethodLateContext } ;
@@ -673,6 +675,9 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
673675 if ty. is_copy_modulo_regions ( cx. tcx , param_env) {
674676 return ;
675677 }
678+ if type_implements_negative_copy_modulo_regions ( cx. tcx , ty, param_env) {
679+ return ;
680+ }
676681
677682 // We shouldn't recommend implementing `Copy` on stateful things,
678683 // such as iterators.
@@ -708,6 +713,24 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
708713 }
709714}
710715
716+ /// Check whether a `ty` has a negative `Copy` implementation, ignoring outlives constraints.
717+ fn type_implements_negative_copy_modulo_regions < ' tcx > (
718+ tcx : TyCtxt < ' tcx > ,
719+ ty : Ty < ' tcx > ,
720+ param_env : ty:: ParamEnv < ' tcx > ,
721+ ) -> bool {
722+ let trait_ref = ty:: TraitRef :: new ( tcx, tcx. require_lang_item ( hir:: LangItem :: Copy , None ) , [ ty] ) ;
723+ let pred = ty:: TraitPredicate { trait_ref, polarity : ty:: ImplPolarity :: Negative } ;
724+ let obligation = traits:: Obligation {
725+ cause : traits:: ObligationCause :: dummy ( ) ,
726+ param_env,
727+ recursion_depth : 0 ,
728+ predicate : ty:: Binder :: dummy ( pred) . to_predicate ( tcx) ,
729+ } ;
730+
731+ tcx. infer_ctxt ( ) . build ( ) . predicate_must_hold_modulo_regions ( & obligation)
732+ }
733+
711734declare_lint ! {
712735 /// The `missing_debug_implementations` lint detects missing
713736 /// implementations of [`fmt::Debug`] for public types.
0 commit comments