@@ -46,14 +46,16 @@ use rustc_middle::lint::in_external_macro;
46
46
use rustc_middle:: ty:: layout:: { LayoutError , LayoutOf } ;
47
47
use rustc_middle:: ty:: print:: with_no_trimmed_paths;
48
48
use rustc_middle:: ty:: subst:: GenericArgKind ;
49
+ use rustc_middle:: ty:: List ;
49
50
use rustc_middle:: ty:: { self , Instance , Ty , TyCtxt , VariantDef } ;
50
51
use rustc_session:: lint:: { BuiltinLintDiagnostics , FutureIncompatibilityReason } ;
51
52
use rustc_span:: edition:: Edition ;
52
53
use rustc_span:: source_map:: Spanned ;
53
54
use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
54
55
use rustc_span:: { BytePos , InnerSpan , Span } ;
55
56
use rustc_target:: abi:: VariantIdx ;
56
- use rustc_trait_selection:: traits:: { self , misc:: can_type_implement_copy} ;
57
+ use rustc_trait_selection:: infer:: { InferCtxtExt , TyCtxtInferExt } ;
58
+ use rustc_trait_selection:: traits:: { self , misc:: can_type_implement_copy, EvaluationResult } ;
57
59
58
60
use crate :: nonstandard_style:: { method_context, MethodLateContext } ;
59
61
@@ -750,10 +752,40 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
750
752
if def. has_dtor ( cx. tcx ) {
751
753
return ;
752
754
}
755
+
756
+ // If the type contains a raw pointer, it may represent something like a handle,
757
+ // and recommending Copy might be a bad idea.
758
+ for field in def. all_fields ( ) {
759
+ let did = field. did ;
760
+ if cx. tcx . type_of ( did) . is_unsafe_ptr ( ) {
761
+ return ;
762
+ }
763
+ }
753
764
let param_env = ty:: ParamEnv :: empty ( ) ;
754
765
if ty. is_copy_modulo_regions ( cx. tcx , param_env) {
755
766
return ;
756
767
}
768
+
769
+ // We shouldn't recommend implementing `Copy` on stateful things,
770
+ // such as iterators.
771
+ if let Some ( iter_trait) = cx. tcx . get_diagnostic_item ( sym:: Iterator ) {
772
+ if cx. tcx . infer_ctxt ( ) . enter ( |infer_ctxt| {
773
+ infer_ctxt. type_implements_trait ( iter_trait, ty, List :: empty ( ) , param_env)
774
+ == EvaluationResult :: EvaluatedToOk
775
+ } ) {
776
+ return ;
777
+ }
778
+ }
779
+
780
+ // Default value of clippy::trivially_copy_pass_by_ref
781
+ const MAX_SIZE : u64 = 256 ;
782
+
783
+ if let Some ( size) = cx. layout_of ( ty) . ok ( ) . map ( |l| l. size . bytes ( ) ) {
784
+ if size > MAX_SIZE {
785
+ return ;
786
+ }
787
+ }
788
+
757
789
if can_type_implement_copy (
758
790
cx. tcx ,
759
791
param_env,
0 commit comments