diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-12-09 22:31:54 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-12-09 22:31:54 +0100 |
| commit | 4fae5891d0857f9bfb0abbca9529e016c8a90ee6 (patch) | |
| tree | c63fffd8104a324d084ac7c8c6943faa55876257 /compiler/rustc_lint/src | |
| parent | dfe3fe710181738a2cb3060c23ec5efb3c68ca09 (diff) | |
| parent | 34277fcddc41e924ffed7ddacb573d240854cff0 (diff) | |
| download | rust-4fae5891d0857f9bfb0abbca9529e016c8a90ee6.tar.gz rust-4fae5891d0857f9bfb0abbca9529e016c8a90ee6.zip | |
Rollup merge of #102406 - mejrs:missing_copy, r=wesleywiser
Make `missing_copy_implementations` more cautious - Fixes https://github.com/rust-lang/rust/issues/98348 - Also makes the lint not fire on large types and types containing raw pointers. Thoughts?
Diffstat (limited to 'compiler/rustc_lint/src')
| -rw-r--r-- | compiler/rustc_lint/src/builtin.rs | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index d0d34d8d2b4..08fbd973b06 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -53,7 +53,8 @@ use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, InnerSpan, Span}; use rustc_target::abi::{Abi, VariantIdx}; -use rustc_trait_selection::traits::{self, misc::can_type_implement_copy}; +use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt}; +use rustc_trait_selection::traits::{self, misc::can_type_implement_copy, EvaluationResult}; use crate::nonstandard_style::{method_context, MethodLateContext}; @@ -750,10 +751,39 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { if def.has_dtor(cx.tcx) { return; } + + // If the type contains a raw pointer, it may represent something like a handle, + // and recommending Copy might be a bad idea. + for field in def.all_fields() { + let did = field.did; + if cx.tcx.type_of(did).is_unsafe_ptr() { + return; + } + } let param_env = ty::ParamEnv::empty(); if ty.is_copy_modulo_regions(cx.tcx, param_env) { return; } + + // We shouldn't recommend implementing `Copy` on stateful things, + // such as iterators. + if let Some(iter_trait) = cx.tcx.get_diagnostic_item(sym::Iterator) { + if cx.tcx.infer_ctxt().build().type_implements_trait(iter_trait, [ty], param_env) + == EvaluationResult::EvaluatedToOk + { + return; + } + } + + // Default value of clippy::trivially_copy_pass_by_ref + const MAX_SIZE: u64 = 256; + + if let Some(size) = cx.layout_of(ty).ok().map(|l| l.size.bytes()) { + if size > MAX_SIZE { + return; + } + } + if can_type_implement_copy( cx.tcx, param_env, |
