diff options
| author | bors <bors@rust-lang.org> | 2023-07-11 13:48:59 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-07-11 13:48:59 +0000 |
| commit | b3ab80c1190d8be65aa3727e0a1f77cfd2e6a1dd (patch) | |
| tree | 7ad7f7b7db0431d11be4fb5f25bb1cd4288dfa0e /tests | |
| parent | d8899c577bc11308a0db96e8378373be93330a8f (diff) | |
| parent | 6b214bbc1128aa6bd9ddf732396fda7230dfeb64 (diff) | |
| download | rust-b3ab80c1190d8be65aa3727e0a1f77cfd2e6a1dd.tar.gz rust-b3ab80c1190d8be65aa3727e0a1f77cfd2e6a1dd.zip | |
Auto merge of #113175 - bryangarza:safe-transmute-rustc-coinductive, r=compiler-errors
Enable coinduction support for Safe Transmute
This patch adds the `#[rustc_coinductive]` annotation to `BikeshedIntrinsicFrom`, so that it's possible to compute transmutability for recursive types.
## Motivation
Safe Transmute currently already supports references (#110662). However, if a type is implemented recursively, it leads to an infinite loop when we try to check if transmutation is safe.
A couple simple examples that one might want to write, that are currently not possible to check transmutability for:
```rs
#[repr(C)] struct A(&'static B);
#[repr(C)] struct B(&'static A);
```
```rs
#[repr(C)]
enum IList<'a> { Nil, Cons(isize, &'a IList<'a>) }
#[repr(C)]
enum UList<'a> { Nil, Cons(usize, &'a UList<'a>) }
```
Previously, `@jswrenn` was considering writing a co-inductive solver from scratch, just for the `rustc_tranmsute` crate. Later on as I started working on Safe Transmute myself, I came across the `#[rustc_coinductive]` annotation, which is currently only being used for the `Sized` trait. Leveraging this trait actually solved the problem entirely, and it saves a lot of duplicate work that would have had to happen in `rustc_transmute`.
Diffstat (limited to 'tests')
4 files changed, 4 insertions, 56 deletions
diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs index 3ea80173afa..709d8cdc762 100644 --- a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs +++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs @@ -1,5 +1,4 @@ -// check-fail -// FIXME(bryangarza): Change to check-pass when coinduction is supported for BikeshedIntrinsicFrom +// check-pass #![feature(transmutability)] mod assert { @@ -22,5 +21,5 @@ mod assert { fn main() { #[repr(C)] struct A(bool, &'static A); #[repr(C)] struct B(u8, &'static B); - assert::is_maybe_transmutable::<&'static A, &'static B>(); //~ ERROR overflow evaluating the requirement + assert::is_maybe_transmutable::<&'static A, &'static B>(); } diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.stderr b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.stderr deleted file mode 100644 index fae332e6af9..00000000000 --- a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.stderr +++ /dev/null @@ -1,25 +0,0 @@ -error[E0275]: overflow evaluating the requirement `B: BikeshedIntrinsicFrom<A, assert::Context, Assume { alignment: true, lifetimes: false, safety: true, validity: false }>` - --> $DIR/recursive-wrapper-types-bit-compatible.rs:25:5 - | -LL | assert::is_maybe_transmutable::<&'static A, &'static B>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/recursive-wrapper-types-bit-compatible.rs:11:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, Context, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: false, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/transmutability/references/recursive-wrapper-types.rs b/tests/ui/transmutability/references/recursive-wrapper-types.rs index 59d1ad84a5d..090c1fea6db 100644 --- a/tests/ui/transmutability/references/recursive-wrapper-types.rs +++ b/tests/ui/transmutability/references/recursive-wrapper-types.rs @@ -1,5 +1,4 @@ -// check-fail -// FIXME(bryangarza): Change to check-pass when coinduction is supported for BikeshedIntrinsicFrom +// check-pass #![feature(transmutability)] mod assert { @@ -22,6 +21,6 @@ mod assert { fn main() { #[repr(C)] struct A(&'static B); #[repr(C)] struct B(&'static A); - assert::is_maybe_transmutable::<&'static A, &'static B>(); //~ overflow evaluating the requirement + assert::is_maybe_transmutable::<&'static A, &'static B>(); assert::is_maybe_transmutable::<&'static B, &'static A>(); } diff --git a/tests/ui/transmutability/references/recursive-wrapper-types.stderr b/tests/ui/transmutability/references/recursive-wrapper-types.stderr deleted file mode 100644 index 35a60c22643..00000000000 --- a/tests/ui/transmutability/references/recursive-wrapper-types.stderr +++ /dev/null @@ -1,25 +0,0 @@ -error[E0275]: overflow evaluating the requirement `A: BikeshedIntrinsicFrom<B, assert::Context, Assume { alignment: true, lifetimes: false, safety: true, validity: false }>` - --> $DIR/recursive-wrapper-types.rs:25:5 - | -LL | assert::is_maybe_transmutable::<&'static A, &'static B>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/recursive-wrapper-types.rs:11:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, Context, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: false, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0275`. |
