Auto merge of #92268 - jswrenn:transmute, r=oli-obk
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](https://github.com/rust-lang/compiler-team/issues/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.
This commit is contained in:
commit
e4417cf020
96 changed files with 6026 additions and 2 deletions
|
@ -109,6 +109,10 @@ pub enum SelectionCandidate<'tcx> {
|
|||
/// `false` if there are no *further* obligations.
|
||||
has_nested: bool,
|
||||
},
|
||||
|
||||
/// Implementation of transmutability trait.
|
||||
TransmutabilityCandidate,
|
||||
|
||||
ParamCandidate(ty::PolyTraitPredicate<'tcx>),
|
||||
ImplCandidate(DefId),
|
||||
AutoImplCandidate(DefId),
|
||||
|
|
|
@ -48,7 +48,7 @@ pub use subst::*;
|
|||
pub use vtable::*;
|
||||
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::ops::ControlFlow;
|
||||
use std::{fmt, str};
|
||||
|
||||
|
@ -1704,6 +1704,59 @@ impl VariantDef {
|
|||
}
|
||||
}
|
||||
|
||||
impl PartialEq for VariantDef {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
// There should be only one `VariantDef` for each `def_id`, therefore
|
||||
// it is fine to implement `PartialEq` only based on `def_id`.
|
||||
//
|
||||
// Below, we exhaustively destructure `self` and `other` so that if the
|
||||
// definition of `VariantDef` changes, a compile-error will be produced,
|
||||
// reminding us to revisit this assumption.
|
||||
|
||||
let Self {
|
||||
def_id: lhs_def_id,
|
||||
ctor_def_id: _,
|
||||
name: _,
|
||||
discr: _,
|
||||
fields: _,
|
||||
ctor_kind: _,
|
||||
flags: _,
|
||||
} = &self;
|
||||
|
||||
let Self {
|
||||
def_id: rhs_def_id,
|
||||
ctor_def_id: _,
|
||||
name: _,
|
||||
discr: _,
|
||||
fields: _,
|
||||
ctor_kind: _,
|
||||
flags: _,
|
||||
} = other;
|
||||
|
||||
lhs_def_id == rhs_def_id
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for VariantDef {}
|
||||
|
||||
impl Hash for VariantDef {
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, s: &mut H) {
|
||||
// There should be only one `VariantDef` for each `def_id`, therefore
|
||||
// it is fine to implement `Hash` only based on `def_id`.
|
||||
//
|
||||
// Below, we exhaustively destructure `self` so that if the definition
|
||||
// of `VariantDef` changes, a compile-error will be produced, reminding
|
||||
// us to revisit this assumption.
|
||||
|
||||
let Self { def_id, ctor_def_id: _, name: _, discr: _, fields: _, ctor_kind: _, flags: _ } =
|
||||
&self;
|
||||
|
||||
def_id.hash(s)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
|
||||
pub enum VariantDiscr {
|
||||
/// Explicit value for this variant, i.e., `X = 123`.
|
||||
|
@ -1724,6 +1777,42 @@ pub struct FieldDef {
|
|||
pub vis: Visibility,
|
||||
}
|
||||
|
||||
impl PartialEq for FieldDef {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
// There should be only one `FieldDef` for each `did`, therefore it is
|
||||
// fine to implement `PartialEq` only based on `did`.
|
||||
//
|
||||
// Below, we exhaustively destructure `self` so that if the definition
|
||||
// of `FieldDef` changes, a compile-error will be produced, reminding
|
||||
// us to revisit this assumption.
|
||||
|
||||
let Self { did: lhs_did, name: _, vis: _ } = &self;
|
||||
|
||||
let Self { did: rhs_did, name: _, vis: _ } = other;
|
||||
|
||||
lhs_did == rhs_did
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for FieldDef {}
|
||||
|
||||
impl Hash for FieldDef {
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, s: &mut H) {
|
||||
// There should be only one `FieldDef` for each `did`, therefore it is
|
||||
// fine to implement `Hash` only based on `did`.
|
||||
//
|
||||
// Below, we exhaustively destructure `self` so that if the definition
|
||||
// of `FieldDef` changes, a compile-error will be produced, reminding
|
||||
// us to revisit this assumption.
|
||||
|
||||
let Self { did, name: _, vis: _ } = &self;
|
||||
|
||||
did.hash(s)
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
#[derive(TyEncodable, TyDecodable, Default, HashStable)]
|
||||
pub struct ReprFlags: u8 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue