Allow more !Copy impls

This commit is contained in:
León Orell Valerian Liehr 2022-09-16 00:06:25 +02:00
parent 35a0407814
commit 28e0c5aec8
No known key found for this signature in database
GPG Key ID: CD75E31CE2CFD7D9
11 changed files with 100 additions and 30 deletions

View File

@ -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) => {

View File

@ -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

View File

@ -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`.

View File

@ -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 {}

View File

@ -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<T>>);
| ------------------------ this field does not implement `Copy`
...
LL | impl<'tcx, T> Copy for List<'tcx, T> {}
| ^^^^
| ^^^^^^^^^^^^^
|
note: the `Copy` impl for `Interned<'tcx, ListS<T>>` requires that `OpaqueListContents: Sized`
--> $DIR/deep-bad-copy-reason.rs:23:26

View File

@ -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

View File

@ -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<u32>,
| ------------- 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<u32> },
| ----------- 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

View File

@ -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>(T);
| - this field does not implement `Copy`
...
LL | impl<S> Copy for Wrapper<OnlyCopyIfDisplay<S>> {}
| ^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the `Copy` impl for `OnlyCopyIfDisplay<S>` requires that `S: std::fmt::Display`
--> $DIR/missing-bound-in-manual-copy-impl-2.rs:4:19

View File

@ -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>(T);
| - this field does not implement `Copy`
LL |
LL | impl<S> Copy for Wrapper<S> {}
| ^^^^
| ^^^^^^^^^^
|
help: consider restricting type parameter `S`
|

View File

@ -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<T> Copy for Foo<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `TraitFoo` is not implemented for `T`
| ^^^^^^ the trait `TraitFoo` is not implemented for `T`
|
help: consider restricting type parameter `T`
|

View File

@ -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<String>
| --------------------------------- this field does not implement `Copy`
...
LL | impl Copy for W {}
| ^^^^
| ^
|
note: the `Copy` impl for `ManuallyDrop<String>` requires that `String: Copy`
--> $DIR/union-copy.rs:8:8