-
Notifications
You must be signed in to change notification settings - Fork 13k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of #134603 - kpreid:pointerlike-err, r=estebank
Explain why a type is not eligible for `impl PointerLike`. The rules were baffling when I ran in to them trying to add some impls (to `std`, not my own code, as it happens), so I made the compiler explain them to me. The logic of the successful cases is unchanged, but I did rearrange it to reverse the order of the primitive and `Adt` cases; this makes producing the errors easier. I'm still not very familiar with `rustc` internals, so let me know if there's a better way to do any of this. This also adds test coverage for which impls are accepted or rejected, which I didn't see any of already. The PR template tells me I should consider mentioning a tracking issue, but there isn't one for `pointer_like_trait`, so I'll mention `dyn_star`: #102425
- Loading branch information
Showing
3 changed files
with
236 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
//@ check-fail | ||
|
||
#![feature(extern_types)] | ||
#![feature(pointer_like_trait)] | ||
|
||
use std::marker::PointerLike; | ||
|
||
struct NotReprTransparent; | ||
impl PointerLike for NotReprTransparent {} | ||
//~^ ERROR: implementation must be applied to type that | ||
//~| NOTE: the struct `NotReprTransparent` is not `repr(transparent)` | ||
|
||
#[repr(transparent)] | ||
struct FieldIsPl(usize); | ||
impl PointerLike for FieldIsPl {} | ||
|
||
#[repr(transparent)] | ||
struct FieldIsPlAndHasOtherField(usize, ()); | ||
impl PointerLike for FieldIsPlAndHasOtherField {} | ||
|
||
#[repr(transparent)] | ||
struct FieldIsNotPl(u8); | ||
impl PointerLike for FieldIsNotPl {} | ||
//~^ ERROR: implementation must be applied to type that | ||
//~| NOTE: the field `0` of struct `FieldIsNotPl` does not implement `PointerLike` | ||
|
||
#[repr(transparent)] | ||
struct GenericFieldIsNotPl<T>(T); | ||
impl<T> PointerLike for GenericFieldIsNotPl<T> {} | ||
//~^ ERROR: implementation must be applied to type that | ||
//~| NOTE: the field `0` of struct `GenericFieldIsNotPl<T>` does not implement `PointerLike` | ||
|
||
#[repr(transparent)] | ||
struct GenericFieldIsPl<T>(T); | ||
impl<T: PointerLike> PointerLike for GenericFieldIsPl<T> {} | ||
|
||
#[repr(transparent)] | ||
struct IsZeroSized(()); | ||
impl PointerLike for IsZeroSized {} | ||
//~^ ERROR: implementation must be applied to type that | ||
//~| NOTE: the struct `IsZeroSized` is `repr(transparent)`, but does not have a non-trivial field | ||
|
||
trait SomeTrait {} | ||
impl PointerLike for dyn SomeTrait {} | ||
//~^ ERROR: implementation must be applied to type that | ||
//~| NOTE: types of dynamic or unknown size | ||
|
||
extern "C" { | ||
type ExternType; | ||
} | ||
impl PointerLike for ExternType {} | ||
//~^ ERROR: implementation must be applied to type that | ||
//~| NOTE: types of dynamic or unknown size | ||
|
||
struct LocalSizedType(&'static str); | ||
struct LocalUnsizedType(str); | ||
|
||
// This is not a special error but a normal coherence error, | ||
// which should still happen. | ||
impl PointerLike for &LocalSizedType {} | ||
//~^ ERROR: conflicting implementations of trait `PointerLike` | ||
//~| NOTE: conflicting implementation in crate `core` | ||
|
||
impl PointerLike for &LocalUnsizedType {} | ||
//~^ ERROR: implementation must be applied to type that | ||
//~| NOTE: references to dynamically-sized types are too large to be `PointerLike` | ||
|
||
impl PointerLike for Box<LocalSizedType> {} | ||
//~^ ERROR: conflicting implementations of trait `PointerLike` | ||
//~| NOTE: conflicting implementation in crate `alloc` | ||
|
||
impl PointerLike for Box<LocalUnsizedType> {} | ||
//~^ ERROR: implementation must be applied to type that | ||
//~| NOTE: boxes of dynamically-sized types are too large to be `PointerLike` | ||
|
||
fn expects_pointer_like(x: impl PointerLike) {} | ||
|
||
fn main() { | ||
expects_pointer_like(FieldIsPl(1usize)); | ||
expects_pointer_like(FieldIsPlAndHasOtherField(1usize, ())); | ||
expects_pointer_like(GenericFieldIsPl(1usize)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
error[E0119]: conflicting implementations of trait `PointerLike` for type `&LocalSizedType` | ||
--> $DIR/pointer-like-impl-rules.rs:60:1 | ||
| | ||
LL | impl PointerLike for &LocalSizedType {} | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | ||
= note: conflicting implementation in crate `core`: | ||
- impl<T> PointerLike for &T; | ||
|
||
error[E0119]: conflicting implementations of trait `PointerLike` for type `Box<LocalSizedType>` | ||
--> $DIR/pointer-like-impl-rules.rs:68:1 | ||
| | ||
LL | impl PointerLike for Box<LocalSizedType> {} | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | ||
= note: conflicting implementation in crate `alloc`: | ||
- impl<T> PointerLike for Box<T>; | ||
|
||
error: implementation must be applied to type that has the same ABI as a pointer, or is `repr(transparent)` and whose field is `PointerLike` | ||
--> $DIR/pointer-like-impl-rules.rs:9:1 | ||
| | ||
LL | impl PointerLike for NotReprTransparent {} | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | ||
= note: the struct `NotReprTransparent` is not `repr(transparent)` | ||
|
||
error: implementation must be applied to type that has the same ABI as a pointer, or is `repr(transparent)` and whose field is `PointerLike` | ||
--> $DIR/pointer-like-impl-rules.rs:23:1 | ||
| | ||
LL | impl PointerLike for FieldIsNotPl {} | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | ||
= note: the field `0` of struct `FieldIsNotPl` does not implement `PointerLike` | ||
|
||
error: implementation must be applied to type that has the same ABI as a pointer, or is `repr(transparent)` and whose field is `PointerLike` | ||
--> $DIR/pointer-like-impl-rules.rs:29:1 | ||
| | ||
LL | impl<T> PointerLike for GenericFieldIsNotPl<T> {} | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | ||
= note: the field `0` of struct `GenericFieldIsNotPl<T>` does not implement `PointerLike` | ||
|
||
error: implementation must be applied to type that has the same ABI as a pointer, or is `repr(transparent)` and whose field is `PointerLike` | ||
--> $DIR/pointer-like-impl-rules.rs:39:1 | ||
| | ||
LL | impl PointerLike for IsZeroSized {} | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | ||
= note: the struct `IsZeroSized` is `repr(transparent)`, but does not have a non-trivial field (it is zero-sized) | ||
|
||
error: implementation must be applied to type that has the same ABI as a pointer, or is `repr(transparent)` and whose field is `PointerLike` | ||
--> $DIR/pointer-like-impl-rules.rs:44:1 | ||
| | ||
LL | impl PointerLike for dyn SomeTrait {} | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | ||
= note: types of dynamic or unknown size may not implement `PointerLike` | ||
|
||
error: implementation must be applied to type that has the same ABI as a pointer, or is `repr(transparent)` and whose field is `PointerLike` | ||
--> $DIR/pointer-like-impl-rules.rs:51:1 | ||
| | ||
LL | impl PointerLike for ExternType {} | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | ||
= note: types of dynamic or unknown size may not implement `PointerLike` | ||
|
||
error: implementation must be applied to type that has the same ABI as a pointer, or is `repr(transparent)` and whose field is `PointerLike` | ||
--> $DIR/pointer-like-impl-rules.rs:64:1 | ||
| | ||
LL | impl PointerLike for &LocalUnsizedType {} | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | ||
= note: references to dynamically-sized types are too large to be `PointerLike` | ||
|
||
error: implementation must be applied to type that has the same ABI as a pointer, or is `repr(transparent)` and whose field is `PointerLike` | ||
--> $DIR/pointer-like-impl-rules.rs:72:1 | ||
| | ||
LL | impl PointerLike for Box<LocalUnsizedType> {} | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | ||
= note: boxes of dynamically-sized types are too large to be `PointerLike` | ||
|
||
error: aborting due to 10 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0119`. |