diff --git a/compiler/rustc_typeck/src/coherence/builtin.rs b/compiler/rustc_typeck/src/coherence/builtin.rs index d08c0d4dbb72a..d4eb826f0b4d3 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) => { diff --git a/src/test/ui/coherence/coherence-negative-impls-copy-bad.rs b/src/test/ui/coherence/coherence-negative-impls-copy-bad.rs new file mode 100644 index 0000000000000..563f28e2291d4 --- /dev/null +++ b/src/test/ui/coherence/coherence-negative-impls-copy-bad.rs @@ -0,0 +1,11 @@ +#![feature(negative_impls)] +#![crate_type = "lib"] + +impl !Copy for str {} +//~^ ERROR only traits defined in the current crate can be implemented + +impl !Copy for fn() {} +//~^ ERROR only traits defined in the current crate can be implemented + +impl !Copy for () {} +//~^ ERROR only traits defined in the current crate can be implemented diff --git a/src/test/ui/coherence/coherence-negative-impls-copy-bad.stderr b/src/test/ui/coherence/coherence-negative-impls-copy-bad.stderr new file mode 100644 index 0000000000000..2295d6315d1c2 --- /dev/null +++ b/src/test/ui/coherence/coherence-negative-impls-copy-bad.stderr @@ -0,0 +1,36 @@ +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/coherence-negative-impls-copy-bad.rs:4:1 + | +LL | impl !Copy for str {} + | ^^^^^^^^^^^^^^^--- + | | | + | | `str` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/coherence-negative-impls-copy-bad.rs:7:1 + | +LL | impl !Copy for fn() {} + | ^^^^^^^^^^^^^^^---- + | | | + | | `fn()` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/coherence-negative-impls-copy-bad.rs:10:1 + | +LL | impl !Copy for () {} + | ^^^^^^^^^^^^^^^-- + | | | + | | this is not defined in the current crate because tuples are always foreign + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence-negative-impls-copy.rs b/src/test/ui/coherence/coherence-negative-impls-copy.rs new file mode 100644 index 0000000000000..7b29aade41335 --- /dev/null +++ b/src/test/ui/coherence/coherence-negative-impls-copy.rs @@ -0,0 +1,29 @@ +// check-pass +// regression test for issue #101836 + +#![feature(negative_impls, extern_types)] +#![crate_type = "lib"] + +struct NonCopy; +struct NeverCopy(NonCopy); + +impl !Copy for NeverCopy {} + + +struct WithDrop; +impl Drop for WithDrop { fn drop(&mut self) {} } + +impl !Copy for WithDrop {} + + +struct Type; +trait Trait {} +extern { + type ExternType; +} + +impl !Copy for &mut Type {} + +impl !Copy for dyn Trait {} + +impl !Copy for ExternType {} diff --git a/src/test/ui/coherence/deep-bad-copy-reason.stderr b/src/test/ui/coherence/deep-bad-copy-reason.stderr index 295538cee6096..168ee57263d2a 100644 --- a/src/test/ui/coherence/deep-bad-copy-reason.stderr +++ b/src/test/ui/coherence/deep-bad-copy-reason.stderr @@ -1,11 +1,11 @@ error[E0204]: the trait `Copy` may not be implemented for this type - --> $DIR/deep-bad-copy-reason.rs:33:15 + --> $DIR/deep-bad-copy-reason.rs:33:24 | LL | pub struct List<'tcx, T>(Interned<'tcx, ListS>); | ------------------------ this field does not implement `Copy` ... LL | impl<'tcx, T> Copy for List<'tcx, T> {} - | ^^^^ + | ^^^^^^^^^^^^^ | note: the `Copy` impl for `Interned<'tcx, ListS>` requires that `OpaqueListContents: Sized` --> $DIR/deep-bad-copy-reason.rs:23:26 diff --git a/src/test/ui/opt-in-copy.stderr b/src/test/ui/opt-in-copy.stderr index 0a275f1aa41d7..4461567df0a2a 100644 --- a/src/test/ui/opt-in-copy.stderr +++ b/src/test/ui/opt-in-copy.stderr @@ -1,20 +1,20 @@ error[E0204]: the trait `Copy` may not be implemented for this type - --> $DIR/opt-in-copy.rs:7:6 + --> $DIR/opt-in-copy.rs:7:15 | LL | but_i_cant: CantCopyThis, | ------------------------ this field does not implement `Copy` ... LL | impl Copy for IWantToCopyThis {} - | ^^^^ + | ^^^^^^^^^^^^^^^ error[E0204]: the trait `Copy` may not be implemented for this type - --> $DIR/opt-in-copy.rs:19:6 + --> $DIR/opt-in-copy.rs:19:15 | LL | ButICant(CantCopyThisEither), | ------------------ this field does not implement `Copy` ... LL | impl Copy for IWantToCopyThisToo {} - | ^^^^ + | ^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/span/E0204.stderr b/src/test/ui/span/E0204.stderr index 2575848435206..0b2166eed7ead 100644 --- a/src/test/ui/span/E0204.stderr +++ b/src/test/ui/span/E0204.stderr @@ -1,11 +1,11 @@ error[E0204]: the trait `Copy` may not be implemented for this type - --> $DIR/E0204.rs:5:6 + --> $DIR/E0204.rs:5:15 | LL | foo: Vec, | ------------- this field does not implement `Copy` ... LL | impl Copy for Foo { } - | ^^^^ + | ^^^ error[E0204]: the trait `Copy` may not be implemented for this type --> $DIR/E0204.rs:7:10 @@ -19,13 +19,13 @@ LL | ty: &'a mut bool, = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0204]: the trait `Copy` may not be implemented for this type - --> $DIR/E0204.rs:17:6 + --> $DIR/E0204.rs:17:15 | LL | Bar { x: Vec }, | ----------- this field does not implement `Copy` ... LL | impl Copy for EFoo { } - | ^^^^ + | ^^^^ error[E0204]: the trait `Copy` may not be implemented for this type --> $DIR/E0204.rs:19:10 diff --git a/src/test/ui/suggestions/missing-bound-in-manual-copy-impl-2.stderr b/src/test/ui/suggestions/missing-bound-in-manual-copy-impl-2.stderr index e0f405eedfa69..9e6f0d9ebbd27 100644 --- a/src/test/ui/suggestions/missing-bound-in-manual-copy-impl-2.stderr +++ b/src/test/ui/suggestions/missing-bound-in-manual-copy-impl-2.stderr @@ -1,11 +1,11 @@ error[E0204]: the trait `Copy` may not be implemented for this type - --> $DIR/missing-bound-in-manual-copy-impl-2.rs:16:9 + --> $DIR/missing-bound-in-manual-copy-impl-2.rs:16:18 | LL | struct Wrapper(T); | - this field does not implement `Copy` ... LL | impl Copy for Wrapper> {} - | ^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: the `Copy` impl for `OnlyCopyIfDisplay` requires that `S: std::fmt::Display` --> $DIR/missing-bound-in-manual-copy-impl-2.rs:4:19 diff --git a/src/test/ui/suggestions/missing-bound-in-manual-copy-impl.stderr b/src/test/ui/suggestions/missing-bound-in-manual-copy-impl.stderr index 218988511dbc3..fe2d133c8aa74 100644 --- a/src/test/ui/suggestions/missing-bound-in-manual-copy-impl.stderr +++ b/src/test/ui/suggestions/missing-bound-in-manual-copy-impl.stderr @@ -1,11 +1,11 @@ error[E0204]: the trait `Copy` may not be implemented for this type - --> $DIR/missing-bound-in-manual-copy-impl.rs:6:9 + --> $DIR/missing-bound-in-manual-copy-impl.rs:6:18 | LL | struct Wrapper(T); | - this field does not implement `Copy` LL | LL | impl Copy for Wrapper {} - | ^^^^ + | ^^^^^^^^^^ | help: consider restricting type parameter `S` | diff --git a/src/test/ui/traits/copy-impl-cannot-normalize.stderr b/src/test/ui/traits/copy-impl-cannot-normalize.stderr index afdad160919f9..68b95b42b3463 100644 --- a/src/test/ui/traits/copy-impl-cannot-normalize.stderr +++ b/src/test/ui/traits/copy-impl-cannot-normalize.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `T: TraitFoo` is not satisfied - --> $DIR/copy-impl-cannot-normalize.rs:22:1 + --> $DIR/copy-impl-cannot-normalize.rs:22:18 | LL | impl Copy for Foo {} - | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `TraitFoo` is not implemented for `T` + | ^^^^^^ the trait `TraitFoo` is not implemented for `T` | help: consider restricting type parameter `T` | diff --git a/src/test/ui/union/union-copy.stderr b/src/test/ui/union/union-copy.stderr index 8ecdafdde2045..53ee4dd2e5bdb 100644 --- a/src/test/ui/union/union-copy.stderr +++ b/src/test/ui/union/union-copy.stderr @@ -1,11 +1,11 @@ error[E0204]: the trait `Copy` may not be implemented for this type - --> $DIR/union-copy.rs:12:6 + --> $DIR/union-copy.rs:12:15 | LL | a: std::mem::ManuallyDrop | --------------------------------- this field does not implement `Copy` ... LL | impl Copy for W {} - | ^^^^ + | ^ | note: the `Copy` impl for `ManuallyDrop` requires that `String: Copy` --> $DIR/union-copy.rs:8:8