Skip to content

Commit 04fd70a

Browse files
authored
Rollup merge of rust-lang#102406 - mejrs:missing_copy, r=wesleywiser
Make `missing_copy_implementations` more cautious - Fixes rust-lang#98348 - Also makes the lint not fire on large types and types containing raw pointers. Thoughts?
2 parents 968b9d8 + 1ccc2ab commit 04fd70a

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

compiler/rustc_lint/src/builtin.rs

+33-1
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,16 @@ use rustc_middle::lint::in_external_macro;
4646
use rustc_middle::ty::layout::{LayoutError, LayoutOf};
4747
use rustc_middle::ty::print::with_no_trimmed_paths;
4848
use rustc_middle::ty::subst::GenericArgKind;
49+
use rustc_middle::ty::List;
4950
use rustc_middle::ty::{self, Instance, Ty, TyCtxt, VariantDef};
5051
use rustc_session::lint::{BuiltinLintDiagnostics, FutureIncompatibilityReason};
5152
use rustc_span::edition::Edition;
5253
use rustc_span::source_map::Spanned;
5354
use rustc_span::symbol::{kw, sym, Ident, Symbol};
5455
use rustc_span::{BytePos, InnerSpan, Span};
5556
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};
5759

5860
use crate::nonstandard_style::{method_context, MethodLateContext};
5961

@@ -750,10 +752,40 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
750752
if def.has_dtor(cx.tcx) {
751753
return;
752754
}
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+
}
753764
let param_env = ty::ParamEnv::empty();
754765
if ty.is_copy_modulo_regions(cx.tcx, param_env) {
755766
return;
756767
}
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+
757789
if can_type_implement_copy(
758790
cx.tcx,
759791
param_env,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// check-pass
2+
#![deny(missing_copy_implementations)]
3+
4+
// Don't recommend implementing Copy on something stateful like an iterator.
5+
pub struct MyIterator {
6+
num: u8,
7+
}
8+
9+
impl Iterator for MyIterator {
10+
type Item = u8;
11+
12+
fn next(&mut self) -> Option<Self::Item> {
13+
todo!()
14+
}
15+
}
16+
17+
pub struct Handle {
18+
inner: *mut (),
19+
}
20+
21+
pub struct Handle2 {
22+
inner: *const (),
23+
}
24+
25+
pub enum MaybeHandle {
26+
Ptr(*mut ()),
27+
}
28+
29+
pub union UnionHandle {
30+
ptr: *mut (),
31+
}
32+
33+
pub struct Array([u8; 2048]);
34+
35+
fn main() {}

0 commit comments

Comments
 (0)