about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-09-26 19:19:19 +0200
committerGitHub <noreply@github.com>2022-09-26 19:19:19 +0200
commit4d4a3691e94588dc1539487cb62fe7a7cbe40bcb (patch)
tree009004758cb2bd007cff153dc0e174bffcb188f8 /compiler
parente1d7dec558d863fb76f98453088b36cb1a926d48 (diff)
parent28e0c5aec8335d34cd84f3970d633860d6bd08a9 (diff)
downloadrust-4d4a3691e94588dc1539487cb62fe7a7cbe40bcb.tar.gz
rust-4d4a3691e94588dc1539487cb62fe7a7cbe40bcb.zip
Rollup merge of #101875 - fmease:allow-more-negative-copy-impls, r=lcnr
Allow more `!Copy` impls

You can already implement `!Copy` for a lot of types (with `#![feature(negative_impls)]`). However, before this PR you could not implement `!Copy` for ADTs whose fields don't implement `Copy` which didn't make any sense. Further, you couldn't implement `!Copy` for types impl'ing `Drop` (equally nonsensical).

``@rustbot`` label T-types F-negative_impls
Fixes #101836.

r? types
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_typeck/src/coherence/builtin.rs18
1 files changed, 6 insertions, 12 deletions
diff --git a/compiler/rustc_typeck/src/coherence/builtin.rs b/compiler/rustc_typeck/src/coherence/builtin.rs
index d08c0d4dbb7..d4eb826f0b4 100644
--- a/compiler/rustc_typeck/src/coherence/builtin.rs
+++ b/compiler/rustc_typeck/src/coherence/builtin.rs
@@ -70,23 +70,21 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
     let self_type = tcx.type_of(impl_did);
     debug!("visit_implementation_of_copy: self_type={:?} (bound)", self_type);
 
-    let span = tcx.hir().span(impl_hir_id);
     let param_env = tcx.param_env(impl_did);
     assert!(!self_type.has_escaping_bound_vars());
 
     debug!("visit_implementation_of_copy: self_type={:?} (free)", self_type);
 
+    let span = match tcx.hir().expect_item(impl_did).kind {
+        ItemKind::Impl(hir::Impl { polarity: hir::ImplPolarity::Negative(_), .. }) => return,
+        ItemKind::Impl(impl_) => impl_.self_ty.span,
+        _ => bug!("expected Copy impl item"),
+    };
+
     let cause = traits::ObligationCause::misc(span, impl_hir_id);
     match can_type_implement_copy(tcx, param_env, self_type, cause) {
         Ok(()) => {}
         Err(CopyImplementationError::InfrigingFields(fields)) => {
-            let item = tcx.hir().expect_item(impl_did);
-            let span = if let ItemKind::Impl(hir::Impl { of_trait: Some(ref tr), .. }) = item.kind {
-                tr.path.span
-            } else {
-                span
-            };
-
             let mut err = struct_span_err!(
                 tcx.sess,
                 span,
@@ -166,10 +164,6 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
             err.emit();
         }
         Err(CopyImplementationError::NotAnAdt) => {
-            let item = tcx.hir().expect_item(impl_did);
-            let span =
-                if let ItemKind::Impl(ref impl_) = item.kind { impl_.self_ty.span } else { span };
-
             tcx.sess.emit_err(CopyImplOnNonAdt { span });
         }
         Err(CopyImplementationError::HasDestructor) => {