diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-08-05 14:00:17 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-08-05 14:00:17 +0200 |
| commit | e722f6f3ac46393ec9829a86aaef982b5fa0eb8b (patch) | |
| tree | 89c0f8d0bb08172480a4e53d37c8543d32975cf4 | |
| parent | bedadffe608cc05b674ec70b5c6996b9b75c4a68 (diff) | |
| parent | 2b8a3b44bfa63c729841c29d70cc2d3e66ca3842 (diff) | |
| download | rust-e722f6f3ac46393ec9829a86aaef982b5fa0eb8b.tar.gz rust-e722f6f3ac46393ec9829a86aaef982b5fa0eb8b.zip | |
Rollup merge of #114248 - fmease:neg-copy-rules-out-missing-copy-impl, r=b-naber
Make lint missing-copy-implementations honor negative `Copy` impls Fixes #101980. ``@rustbot`` label A-lint F-negative_impls
| -rw-r--r-- | compiler/rustc_lint/src/builtin.rs | 23 | ||||
| -rw-r--r-- | tests/ui/lint/missing-copy-implementations-negative-copy.rs | 15 |
2 files changed, 38 insertions, 0 deletions
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index c290462fc20..2c9d212a6a6 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -58,6 +58,7 @@ use rustc_middle::lint::in_external_macro; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::GenericArgKind; +use rustc_middle::ty::ToPredicate; use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{self, Ty, TyCtxt, VariantDef}; use rustc_session::config::ExpectedValues; @@ -68,6 +69,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, InnerSpan, Span}; use rustc_target::abi::Abi; use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt}; +use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_trait_selection::traits::{self, misc::type_allowed_to_implement_copy}; use crate::nonstandard_style::{method_context, MethodLateContext}; @@ -673,6 +675,9 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { if ty.is_copy_modulo_regions(cx.tcx, param_env) { return; } + if type_implements_negative_copy_modulo_regions(cx.tcx, ty, param_env) { + return; + } // We shouldn't recommend implementing `Copy` on stateful things, // such as iterators. @@ -708,6 +713,24 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { } } +/// Check whether a `ty` has a negative `Copy` implementation, ignoring outlives constraints. +fn type_implements_negative_copy_modulo_regions<'tcx>( + tcx: TyCtxt<'tcx>, + ty: Ty<'tcx>, + param_env: ty::ParamEnv<'tcx>, +) -> bool { + let trait_ref = ty::TraitRef::new(tcx, tcx.require_lang_item(hir::LangItem::Copy, None), [ty]); + let pred = ty::TraitPredicate { trait_ref, polarity: ty::ImplPolarity::Negative }; + let obligation = traits::Obligation { + cause: traits::ObligationCause::dummy(), + param_env, + recursion_depth: 0, + predicate: ty::Binder::dummy(pred).to_predicate(tcx), + }; + + tcx.infer_ctxt().build().predicate_must_hold_modulo_regions(&obligation) +} + declare_lint! { /// The `missing_debug_implementations` lint detects missing /// implementations of [`fmt::Debug`] for public types. diff --git a/tests/ui/lint/missing-copy-implementations-negative-copy.rs b/tests/ui/lint/missing-copy-implementations-negative-copy.rs new file mode 100644 index 00000000000..b29d2209fa9 --- /dev/null +++ b/tests/ui/lint/missing-copy-implementations-negative-copy.rs @@ -0,0 +1,15 @@ +// Regression test for issue #101980. +// Ensure that we don't suggest impl'ing `Copy` for a type if it already impl's `!Copy`. + +// check-pass + +#![feature(negative_impls)] +#![deny(missing_copy_implementations)] + +pub struct Struct { + pub field: i32, +} + +impl !Copy for Struct {} + +fn main() {} |
