Skip to content

Commit 28e0c5a

Browse files
committed
Allow more !Copy impls
1 parent 35a0407 commit 28e0c5a

11 files changed

+100
-30
lines changed

compiler/rustc_typeck/src/coherence/builtin.rs

+6-12
Original file line numberDiff line numberDiff line change
@@ -70,23 +70,21 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
7070
let self_type = tcx.type_of(impl_did);
7171
debug!("visit_implementation_of_copy: self_type={:?} (bound)", self_type);
7272

73-
let span = tcx.hir().span(impl_hir_id);
7473
let param_env = tcx.param_env(impl_did);
7574
assert!(!self_type.has_escaping_bound_vars());
7675

7776
debug!("visit_implementation_of_copy: self_type={:?} (free)", self_type);
7877

78+
let span = match tcx.hir().expect_item(impl_did).kind {
79+
ItemKind::Impl(hir::Impl { polarity: hir::ImplPolarity::Negative(_), .. }) => return,
80+
ItemKind::Impl(impl_) => impl_.self_ty.span,
81+
_ => bug!("expected Copy impl item"),
82+
};
83+
7984
let cause = traits::ObligationCause::misc(span, impl_hir_id);
8085
match can_type_implement_copy(tcx, param_env, self_type, cause) {
8186
Ok(()) => {}
8287
Err(CopyImplementationError::InfrigingFields(fields)) => {
83-
let item = tcx.hir().expect_item(impl_did);
84-
let span = if let ItemKind::Impl(hir::Impl { of_trait: Some(ref tr), .. }) = item.kind {
85-
tr.path.span
86-
} else {
87-
span
88-
};
89-
9088
let mut err = struct_span_err!(
9189
tcx.sess,
9290
span,
@@ -166,10 +164,6 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
166164
err.emit();
167165
}
168166
Err(CopyImplementationError::NotAnAdt) => {
169-
let item = tcx.hir().expect_item(impl_did);
170-
let span =
171-
if let ItemKind::Impl(ref impl_) = item.kind { impl_.self_ty.span } else { span };
172-
173167
tcx.sess.emit_err(CopyImplOnNonAdt { span });
174168
}
175169
Err(CopyImplementationError::HasDestructor) => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![feature(negative_impls)]
2+
#![crate_type = "lib"]
3+
4+
impl !Copy for str {}
5+
//~^ ERROR only traits defined in the current crate can be implemented
6+
7+
impl !Copy for fn() {}
8+
//~^ ERROR only traits defined in the current crate can be implemented
9+
10+
impl !Copy for () {}
11+
//~^ ERROR only traits defined in the current crate can be implemented
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
2+
--> $DIR/coherence-negative-impls-copy-bad.rs:4:1
3+
|
4+
LL | impl !Copy for str {}
5+
| ^^^^^^^^^^^^^^^---
6+
| | |
7+
| | `str` is not defined in the current crate
8+
| impl doesn't use only types from inside the current crate
9+
|
10+
= note: define and implement a trait or new type instead
11+
12+
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
13+
--> $DIR/coherence-negative-impls-copy-bad.rs:7:1
14+
|
15+
LL | impl !Copy for fn() {}
16+
| ^^^^^^^^^^^^^^^----
17+
| | |
18+
| | `fn()` is not defined in the current crate
19+
| impl doesn't use only types from inside the current crate
20+
|
21+
= note: define and implement a trait or new type instead
22+
23+
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
24+
--> $DIR/coherence-negative-impls-copy-bad.rs:10:1
25+
|
26+
LL | impl !Copy for () {}
27+
| ^^^^^^^^^^^^^^^--
28+
| | |
29+
| | this is not defined in the current crate because tuples are always foreign
30+
| impl doesn't use only types from inside the current crate
31+
|
32+
= note: define and implement a trait or new type instead
33+
34+
error: aborting due to 3 previous errors
35+
36+
For more information about this error, try `rustc --explain E0117`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// check-pass
2+
// regression test for issue #101836
3+
4+
#![feature(negative_impls, extern_types)]
5+
#![crate_type = "lib"]
6+
7+
struct NonCopy;
8+
struct NeverCopy(NonCopy);
9+
10+
impl !Copy for NeverCopy {}
11+
12+
13+
struct WithDrop;
14+
impl Drop for WithDrop { fn drop(&mut self) {} }
15+
16+
impl !Copy for WithDrop {}
17+
18+
19+
struct Type;
20+
trait Trait {}
21+
extern {
22+
type ExternType;
23+
}
24+
25+
impl !Copy for &mut Type {}
26+
27+
impl !Copy for dyn Trait {}
28+
29+
impl !Copy for ExternType {}

src/test/ui/coherence/deep-bad-copy-reason.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0204]: the trait `Copy` may not be implemented for this type
2-
--> $DIR/deep-bad-copy-reason.rs:33:15
2+
--> $DIR/deep-bad-copy-reason.rs:33:24
33
|
44
LL | pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>);
55
| ------------------------ this field does not implement `Copy`
66
...
77
LL | impl<'tcx, T> Copy for List<'tcx, T> {}
8-
| ^^^^
8+
| ^^^^^^^^^^^^^
99
|
1010
note: the `Copy` impl for `Interned<'tcx, ListS<T>>` requires that `OpaqueListContents: Sized`
1111
--> $DIR/deep-bad-copy-reason.rs:23:26

src/test/ui/opt-in-copy.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
error[E0204]: the trait `Copy` may not be implemented for this type
2-
--> $DIR/opt-in-copy.rs:7:6
2+
--> $DIR/opt-in-copy.rs:7:15
33
|
44
LL | but_i_cant: CantCopyThis,
55
| ------------------------ this field does not implement `Copy`
66
...
77
LL | impl Copy for IWantToCopyThis {}
8-
| ^^^^
8+
| ^^^^^^^^^^^^^^^
99

1010
error[E0204]: the trait `Copy` may not be implemented for this type
11-
--> $DIR/opt-in-copy.rs:19:6
11+
--> $DIR/opt-in-copy.rs:19:15
1212
|
1313
LL | ButICant(CantCopyThisEither),
1414
| ------------------ this field does not implement `Copy`
1515
...
1616
LL | impl Copy for IWantToCopyThisToo {}
17-
| ^^^^
17+
| ^^^^^^^^^^^^^^^^^^
1818

1919
error: aborting due to 2 previous errors
2020

src/test/ui/span/E0204.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0204]: the trait `Copy` may not be implemented for this type
2-
--> $DIR/E0204.rs:5:6
2+
--> $DIR/E0204.rs:5:15
33
|
44
LL | foo: Vec<u32>,
55
| ------------- this field does not implement `Copy`
66
...
77
LL | impl Copy for Foo { }
8-
| ^^^^
8+
| ^^^
99

1010
error[E0204]: the trait `Copy` may not be implemented for this type
1111
--> $DIR/E0204.rs:7:10
@@ -19,13 +19,13 @@ LL | ty: &'a mut bool,
1919
= note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
2020

2121
error[E0204]: the trait `Copy` may not be implemented for this type
22-
--> $DIR/E0204.rs:17:6
22+
--> $DIR/E0204.rs:17:15
2323
|
2424
LL | Bar { x: Vec<u32> },
2525
| ----------- this field does not implement `Copy`
2626
...
2727
LL | impl Copy for EFoo { }
28-
| ^^^^
28+
| ^^^^
2929

3030
error[E0204]: the trait `Copy` may not be implemented for this type
3131
--> $DIR/E0204.rs:19:10

src/test/ui/suggestions/missing-bound-in-manual-copy-impl-2.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0204]: the trait `Copy` may not be implemented for this type
2-
--> $DIR/missing-bound-in-manual-copy-impl-2.rs:16:9
2+
--> $DIR/missing-bound-in-manual-copy-impl-2.rs:16:18
33
|
44
LL | struct Wrapper<T>(T);
55
| - this field does not implement `Copy`
66
...
77
LL | impl<S> Copy for Wrapper<OnlyCopyIfDisplay<S>> {}
8-
| ^^^^
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
99
|
1010
note: the `Copy` impl for `OnlyCopyIfDisplay<S>` requires that `S: std::fmt::Display`
1111
--> $DIR/missing-bound-in-manual-copy-impl-2.rs:4:19

src/test/ui/suggestions/missing-bound-in-manual-copy-impl.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0204]: the trait `Copy` may not be implemented for this type
2-
--> $DIR/missing-bound-in-manual-copy-impl.rs:6:9
2+
--> $DIR/missing-bound-in-manual-copy-impl.rs:6:18
33
|
44
LL | struct Wrapper<T>(T);
55
| - this field does not implement `Copy`
66
LL |
77
LL | impl<S> Copy for Wrapper<S> {}
8-
| ^^^^
8+
| ^^^^^^^^^^
99
|
1010
help: consider restricting type parameter `S`
1111
|

src/test/ui/traits/copy-impl-cannot-normalize.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `T: TraitFoo` is not satisfied
2-
--> $DIR/copy-impl-cannot-normalize.rs:22:1
2+
--> $DIR/copy-impl-cannot-normalize.rs:22:18
33
|
44
LL | impl<T> Copy for Foo<T> {}
5-
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `TraitFoo` is not implemented for `T`
5+
| ^^^^^^ the trait `TraitFoo` is not implemented for `T`
66
|
77
help: consider restricting type parameter `T`
88
|

src/test/ui/union/union-copy.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0204]: the trait `Copy` may not be implemented for this type
2-
--> $DIR/union-copy.rs:12:6
2+
--> $DIR/union-copy.rs:12:15
33
|
44
LL | a: std::mem::ManuallyDrop<String>
55
| --------------------------------- this field does not implement `Copy`
66
...
77
LL | impl Copy for W {}
8-
| ^^^^
8+
| ^
99
|
1010
note: the `Copy` impl for `ManuallyDrop<String>` requires that `String: Copy`
1111
--> $DIR/union-copy.rs:8:8

0 commit comments

Comments
 (0)