Skip to content

Commit

Permalink
Auto merge of #92268 - jswrenn:transmute, r=oli-obk
Browse files Browse the repository at this point in the history
Initial implementation of transmutability trait.

*T'was the night before Christmas and all through the codebase, not a miri was stirring — no hint of `unsafe`!*

This PR provides an initial, **incomplete** implementation of *[MCP 411: Lang Item for Transmutability](rust-lang/compiler-team#411. The `core::mem::BikeshedIntrinsicFrom` trait provided by this PR is implemented on-the-fly by the compiler for types `Src` and `Dst` when the bits of all possible values of type `Src` are safely reinterpretable as a value of type `Dst`.

What this PR provides is:
- [x] [support for transmutations involving primitives](https://github.com/jswrenn/rust/tree/transmute/src/test/ui/transmutability/primitives)
- [x] [support for transmutations involving arrays](https://github.com/jswrenn/rust/tree/transmute/src/test/ui/transmutability/arrays)
- [x] [support for transmutations involving structs](https://github.com/jswrenn/rust/tree/transmute/src/test/ui/transmutability/structs)
- [x] [support for transmutations involving enums](https://github.com/jswrenn/rust/tree/transmute/src/test/ui/transmutability/enums)
- [x] [support for transmutations involving unions](https://github.com/jswrenn/rust/tree/transmute/src/test/ui/transmutability/unions)
- [x] [support for weaker validity checks](https://github.com/jswrenn/rust/blob/transmute/src/test/ui/transmutability/unions/should_permit_intersecting_if_validity_is_assumed.rs) (i.e., `Assume::VALIDITY`)
- [x] visibility checking

What isn't yet implemented:
- [ ] transmutability options passed using the `Assume` struct
- [ ] [support for references](https://github.com/jswrenn/rust/blob/transmute/src/test/ui/transmutability/references.rs)
- [ ] smarter error messages

These features will be implemented in future PRs.
  • Loading branch information
bors committed Aug 2, 2022
2 parents 094a669 + 2d04c50 commit 8bf6594
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
4 changes: 4 additions & 0 deletions core/src/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ mod valid_align;
// alignment as a parameter, such as `Layout::padding_needed_for`.
pub(crate) use valid_align::ValidAlign;

mod transmutability;
#[unstable(feature = "transmutability", issue = "99571")]
pub use transmutability::{Assume, BikeshedIntrinsicFrom};

#[stable(feature = "rust1", since = "1.0.0")]
#[doc(inline)]
pub use crate::intrinsics::transmute;
Expand Down
43 changes: 43 additions & 0 deletions core/src/mem/transmutability.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/// Are values of a type transmutable into values of another type?
///
/// This trait is implemented on-the-fly by the compiler for types `Src` and `Self` when the bits of
/// any value of type `Self` are safely transmutable into a value of type `Dst`, in a given `Context`,
/// notwithstanding whatever safety checks you have asked the compiler to [`Assume`] are satisfied.
#[unstable(feature = "transmutability", issue = "99571")]
#[cfg_attr(not(bootstrap), lang = "transmute_trait")]
#[rustc_on_unimplemented(
message = "`{Src}` cannot be safely transmuted into `{Self}` in the defining scope of `{Context}`.",
label = "`{Src}` cannot be safely transmuted into `{Self}` in the defining scope of `{Context}`."
)]
pub unsafe trait BikeshedIntrinsicFrom<
Src,
Context,
const ASSUME_ALIGNMENT: bool,
const ASSUME_LIFETIMES: bool,
const ASSUME_VALIDITY: bool,
const ASSUME_VISIBILITY: bool,
> where
Src: ?Sized,
{
}

/// What transmutation safety conditions shall the compiler assume that *you* are checking?
#[unstable(feature = "transmutability", issue = "99571")]
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Assume {
/// When `true`, the compiler assumes that *you* are ensuring (either dynamically or statically) that
/// destination referents do not have stricter alignment requirements than source referents.
pub alignment: bool,

/// When `true`, the compiler assume that *you* are ensuring that lifetimes are not extended in a manner
/// that violates Rust's memory model.
pub lifetimes: bool,

/// When `true`, the compiler assumes that *you* are ensuring that the source type is actually a valid
/// instance of the destination type.
pub validity: bool,

/// When `true`, the compiler assumes that *you* have ensured that it is safe for you to violate the
/// type and field privacy of the destination type (and sometimes of the source type, too).
pub visibility: bool,
}

0 comments on commit 8bf6594

Please sign in to comment.