Skip to content

Commit

Permalink
Auto merge of #113175 - bryangarza:safe-transmute-rustc-coinductive, …
Browse files Browse the repository at this point in the history
…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`.
  • Loading branch information
bors committed Jul 11, 2023
2 parents d8899c5 + 6b214bb commit b3ab80c
Show file tree
Hide file tree
Showing 5 changed files with 5 additions and 56 deletions.
1 change: 1 addition & 0 deletions library/core/src/mem/transmutability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::marker::ConstParamTy;
#[lang = "transmute_trait"]
#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl(implement_via_object = false))]
#[cfg_attr(bootstrap, rustc_deny_explicit_impl)]
#[rustc_coinductive]
pub unsafe trait BikeshedIntrinsicFrom<Src, Context, const ASSUME: Assume = { Assume::NOTHING }>
where
Src: ?Sized,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// check-fail
// FIXME(bryangarza): Change to check-pass when coinduction is supported for BikeshedIntrinsicFrom
// check-pass
#![feature(transmutability)]

mod assert {
Expand All @@ -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>();
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// check-fail
// FIXME(bryangarza): Change to check-pass when coinduction is supported for BikeshedIntrinsicFrom
// check-pass
#![feature(transmutability)]

mod assert {
Expand All @@ -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>();
}
25 changes: 0 additions & 25 deletions tests/ui/transmutability/references/recursive-wrapper-types.stderr

This file was deleted.

0 comments on commit b3ab80c

Please sign in to comment.