@@ -62,6 +62,7 @@ use rustc_middle::lint::in_external_macro;
62
62
use rustc_middle:: ty:: layout:: { LayoutError , LayoutOf } ;
63
63
use rustc_middle:: ty:: print:: with_no_trimmed_paths;
64
64
use rustc_middle:: ty:: GenericArgKind ;
65
+ use rustc_middle:: ty:: ToPredicate ;
65
66
use rustc_middle:: ty:: TypeVisitableExt ;
66
67
use rustc_middle:: ty:: { self , Instance , Ty , TyCtxt , VariantDef } ;
67
68
use rustc_session:: config:: ExpectedValues ;
@@ -72,6 +73,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
72
73
use rustc_span:: { BytePos , InnerSpan , Span } ;
73
74
use rustc_target:: abi:: { Abi , FIRST_VARIANT } ;
74
75
use rustc_trait_selection:: infer:: { InferCtxtExt , TyCtxtInferExt } ;
76
+ use rustc_trait_selection:: traits:: query:: evaluate_obligation:: InferCtxtExt as _;
75
77
use rustc_trait_selection:: traits:: { self , misc:: type_allowed_to_implement_copy} ;
76
78
77
79
use crate :: nonstandard_style:: { method_context, MethodLateContext } ;
@@ -710,6 +712,9 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
710
712
if ty. is_copy_modulo_regions ( cx. tcx , param_env) {
711
713
return ;
712
714
}
715
+ if type_implements_negative_copy_modulo_regions ( cx. tcx , ty, param_env) {
716
+ return ;
717
+ }
713
718
714
719
// We shouldn't recommend implementing `Copy` on stateful things,
715
720
// such as iterators.
@@ -745,6 +750,24 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
745
750
}
746
751
}
747
752
753
+ /// Check whether a `ty` has a negative `Copy` implementation, ignoring outlives constraints.
754
+ fn type_implements_negative_copy_modulo_regions < ' tcx > (
755
+ tcx : TyCtxt < ' tcx > ,
756
+ ty : Ty < ' tcx > ,
757
+ param_env : ty:: ParamEnv < ' tcx > ,
758
+ ) -> bool {
759
+ let trait_ref = ty:: TraitRef :: new ( tcx, tcx. require_lang_item ( hir:: LangItem :: Copy , None ) , [ ty] ) ;
760
+ let pred = ty:: TraitPredicate { trait_ref, polarity : ty:: ImplPolarity :: Negative } ;
761
+ let obligation = traits:: Obligation {
762
+ cause : traits:: ObligationCause :: dummy ( ) ,
763
+ param_env,
764
+ recursion_depth : 0 ,
765
+ predicate : ty:: Binder :: dummy ( pred) . to_predicate ( tcx) ,
766
+ } ;
767
+
768
+ tcx. infer_ctxt ( ) . build ( ) . predicate_must_hold_modulo_regions ( & obligation)
769
+ }
770
+
748
771
declare_lint ! {
749
772
/// The `missing_debug_implementations` lint detects missing
750
773
/// implementations of [`fmt::Debug`] for public types.
0 commit comments