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?
This commit is contained in:
commit
4fae5891d0
2 changed files with 66 additions and 1 deletions
|
@ -53,7 +53,8 @@ use rustc_span::source_map::Spanned;
|
||||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||||
use rustc_span::{BytePos, InnerSpan, Span};
|
use rustc_span::{BytePos, InnerSpan, Span};
|
||||||
use rustc_target::abi::{Abi, VariantIdx};
|
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};
|
use crate::nonstandard_style::{method_context, MethodLateContext};
|
||||||
|
|
||||||
|
@ -750,10 +751,39 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
|
||||||
if def.has_dtor(cx.tcx) {
|
if def.has_dtor(cx.tcx) {
|
||||||
return;
|
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();
|
let param_env = ty::ParamEnv::empty();
|
||||||
if ty.is_copy_modulo_regions(cx.tcx, param_env) {
|
if ty.is_copy_modulo_regions(cx.tcx, param_env) {
|
||||||
return;
|
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(
|
if can_type_implement_copy(
|
||||||
cx.tcx,
|
cx.tcx,
|
||||||
param_env,
|
param_env,
|
||||||
|
|
35
src/test/ui/lint/lint-missing-copy-implementations-allow.rs
Normal file
35
src/test/ui/lint/lint-missing-copy-implementations-allow.rs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// check-pass
|
||||||
|
#![deny(missing_copy_implementations)]
|
||||||
|
|
||||||
|
// Don't recommend implementing Copy on something stateful like an iterator.
|
||||||
|
pub struct MyIterator {
|
||||||
|
num: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for MyIterator {
|
||||||
|
type Item = u8;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Handle {
|
||||||
|
inner: *mut (),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Handle2 {
|
||||||
|
inner: *const (),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum MaybeHandle {
|
||||||
|
Ptr(*mut ()),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub union UnionHandle {
|
||||||
|
ptr: *mut (),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Array([u8; 2048]);
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue