@@ -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
@@ -748,10 +750,40 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
748
750
if def. has_dtor ( cx. tcx ) {
749
751
return ;
750
752
}
753
+
754
+ // If the type contains a raw pointer, it may represent something like a handle,
755
+ // and recommending Copy might be a bad idea.
756
+ for field in def. all_fields ( ) {
757
+ let did = field. did ;
758
+ if cx. tcx . type_of ( did) . is_unsafe_ptr ( ) {
759
+ return ;
760
+ }
761
+ }
751
762
let param_env = ty:: ParamEnv :: empty ( ) ;
752
763
if ty. is_copy_modulo_regions ( cx. tcx . at ( item. span ) , param_env) {
753
764
return ;
754
765
}
766
+
767
+ // We shouldn't recommend implementing `Copy` on stateful things,
768
+ // such as iterators.
769
+ if let Some ( iter_trait) = cx. tcx . get_diagnostic_item ( sym:: Iterator ) {
770
+ if cx. tcx . infer_ctxt ( ) . enter ( |infer_ctxt| {
771
+ infer_ctxt. type_implements_trait ( iter_trait, ty, List :: empty ( ) , param_env)
772
+ == EvaluationResult :: EvaluatedToOk
773
+ } ) {
774
+ return ;
775
+ }
776
+ }
777
+
778
+ // Default value of clippy::trivially_copy_pass_by_ref
779
+ const MAX_SIZE : u64 = 256 ;
780
+
781
+ if let Some ( size) = cx. layout_of ( ty) . ok ( ) . map ( |l| l. size . bytes ( ) ) {
782
+ if size > MAX_SIZE {
783
+ return ;
784
+ }
785
+ }
786
+
755
787
if can_type_implement_copy (
756
788
cx. tcx ,
757
789
param_env,
0 commit comments