1
Fork 0

safe transmute: revise safety analysis

Migrate to a simplified safety analysis that does not use visibility.

Closes https://github.com/rust-lang/project-safe-transmute/issues/15
This commit is contained in:
Jack Wrenn 2024-02-26 16:49:25 +00:00
parent 9afdb8d1d5
commit 23ab1bda92
127 changed files with 1387 additions and 1948 deletions

View file

@ -167,7 +167,7 @@ language_item_table! {
// language items relating to transmutability // language items relating to transmutability
TransmuteOpts, sym::transmute_opts, transmute_opts, Target::Struct, GenericRequirement::Exact(0); TransmuteOpts, sym::transmute_opts, transmute_opts, Target::Struct, GenericRequirement::Exact(0);
TransmuteTrait, sym::transmute_trait, transmute_trait, Target::Trait, GenericRequirement::Exact(3); TransmuteTrait, sym::transmute_trait, transmute_trait, Target::Trait, GenericRequirement::Exact(2);
Add, sym::add, add_trait, Target::Trait, GenericRequirement::Exact(1); Add, sym::add, add_trait, Target::Trait, GenericRequirement::Exact(1);
Sub, sym::sub, sub_trait, Target::Trait, GenericRequirement::Exact(1); Sub, sym::sub, sub_trait, Target::Trait, GenericRequirement::Exact(1);

View file

@ -874,7 +874,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
pub(super) fn is_transmutable( pub(super) fn is_transmutable(
&self, &self,
src_and_dst: rustc_transmute::Types<'tcx>, src_and_dst: rustc_transmute::Types<'tcx>,
scope: Ty<'tcx>,
assume: rustc_transmute::Assume, assume: rustc_transmute::Assume,
) -> Result<Certainty, NoSolution> { ) -> Result<Certainty, NoSolution> {
use rustc_transmute::Answer; use rustc_transmute::Answer;
@ -882,7 +881,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable( match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable(
ObligationCause::dummy(), ObligationCause::dummy(),
src_and_dst, src_and_dst,
scope,
assume, assume,
) { ) {
Answer::Yes => Ok(Certainty::Yes), Answer::Yes => Ok(Certainty::Yes),

View file

@ -543,14 +543,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
let args = ecx.tcx().erase_regions(goal.predicate.trait_ref.args); let args = ecx.tcx().erase_regions(goal.predicate.trait_ref.args);
let Some(assume) = let Some(assume) =
rustc_transmute::Assume::from_const(ecx.tcx(), goal.param_env, args.const_at(3)) rustc_transmute::Assume::from_const(ecx.tcx(), goal.param_env, args.const_at(2))
else { else {
return Err(NoSolution); return Err(NoSolution);
}; };
let certainty = ecx.is_transmutable( let certainty = ecx.is_transmutable(
rustc_transmute::Types { dst: args.type_at(0), src: args.type_at(1) }, rustc_transmute::Types { dst: args.type_at(0), src: args.type_at(1) },
args.type_at(2),
assume, assume,
)?; )?;
ecx.evaluate_added_goals_and_make_canonical_response(certainty) ecx.evaluate_added_goals_and_make_canonical_response(certainty)

View file

@ -2970,11 +2970,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
dst: trait_ref.args.type_at(0), dst: trait_ref.args.type_at(0),
src: trait_ref.args.type_at(1), src: trait_ref.args.type_at(1),
}; };
let scope = trait_ref.args.type_at(2);
let Some(assume) = rustc_transmute::Assume::from_const( let Some(assume) = rustc_transmute::Assume::from_const(
self.infcx.tcx, self.infcx.tcx,
obligation.param_env, obligation.param_env,
trait_ref.args.const_at(3), trait_ref.args.const_at(2),
) else { ) else {
self.dcx().span_delayed_bug( self.dcx().span_delayed_bug(
span, span,
@ -2986,15 +2985,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable( match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable(
obligation.cause, obligation.cause,
src_and_dst, src_and_dst,
scope,
assume, assume,
) { ) {
Answer::No(reason) => { Answer::No(reason) => {
let dst = trait_ref.args.type_at(0); let dst = trait_ref.args.type_at(0);
let src = trait_ref.args.type_at(1); let src = trait_ref.args.type_at(1);
let err_msg = format!( let err_msg = format!("`{src}` cannot be safely transmuted into `{dst}`");
"`{src}` cannot be safely transmuted into `{dst}` in the defining scope of `{scope}`"
);
let safe_transmute_explanation = match reason { let safe_transmute_explanation = match reason {
rustc_transmute::Reason::SrcIsUnspecified => { rustc_transmute::Reason::SrcIsUnspecified => {
format!("`{src}` does not have a well-specified layout") format!("`{src}` does not have a well-specified layout")
@ -3008,9 +3004,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
format!("At least one value of `{src}` isn't a bit-valid value of `{dst}`") format!("At least one value of `{src}` isn't a bit-valid value of `{dst}`")
} }
rustc_transmute::Reason::DstIsPrivate => format!( rustc_transmute::Reason::DstMayHaveSafetyInvariants => {
"`{dst}` is or contains a type or field that is not visible in that scope" format!("`{dst}` may carry safety invariants")
), }
rustc_transmute::Reason::DstIsTooBig => { rustc_transmute::Reason::DstIsTooBig => {
format!("The size of `{src}` is smaller than the size of `{dst}`") format!("The size of `{src}` is smaller than the size of `{dst}`")
} }

View file

@ -310,8 +310,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.collect(), .collect(),
Condition::IfTransmutable { src, dst } => { Condition::IfTransmutable { src, dst } => {
let trait_def_id = obligation.predicate.def_id(); let trait_def_id = obligation.predicate.def_id();
let scope = predicate.trait_ref.args.type_at(2); let assume_const = predicate.trait_ref.args.const_at(2);
let assume_const = predicate.trait_ref.args.const_at(3);
let make_obl = |from_ty, to_ty| { let make_obl = |from_ty, to_ty| {
let trait_ref1 = ty::TraitRef::new( let trait_ref1 = ty::TraitRef::new(
tcx, tcx,
@ -319,7 +318,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
[ [
ty::GenericArg::from(to_ty), ty::GenericArg::from(to_ty),
ty::GenericArg::from(from_ty), ty::GenericArg::from(from_ty),
ty::GenericArg::from(scope),
ty::GenericArg::from(assume_const), ty::GenericArg::from(assume_const),
], ],
); );
@ -355,7 +353,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let Some(assume) = rustc_transmute::Assume::from_const( let Some(assume) = rustc_transmute::Assume::from_const(
self.infcx.tcx, self.infcx.tcx,
obligation.param_env, obligation.param_env,
predicate.trait_ref.args.const_at(3), predicate.trait_ref.args.const_at(2),
) else { ) else {
return Err(Unimplemented); return Err(Unimplemented);
}; };
@ -367,7 +365,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let maybe_transmutable = transmute_env.is_transmutable( let maybe_transmutable = transmute_env.is_transmutable(
obligation.cause.clone(), obligation.cause.clone(),
rustc_transmute::Types { dst, src }, rustc_transmute::Types { dst, src },
predicate.trait_ref.args.type_at(2),
assume, assume,
); );

View file

@ -29,14 +29,21 @@ impl fmt::Debug for Byte {
} }
} }
pub(crate) trait Def: Debug + Hash + Eq + PartialEq + Copy + Clone {} pub(crate) trait Def: Debug + Hash + Eq + PartialEq + Copy + Clone {
fn has_safety_invariants(&self) -> bool;
}
pub trait Ref: Debug + Hash + Eq + PartialEq + Copy + Clone { pub trait Ref: Debug + Hash + Eq + PartialEq + Copy + Clone {
fn min_align(&self) -> usize; fn min_align(&self) -> usize;
fn is_mutable(&self) -> bool; fn is_mutable(&self) -> bool;
} }
impl Def for ! {} impl Def for ! {
fn has_safety_invariants(&self) -> bool {
unreachable!()
}
}
impl Ref for ! { impl Ref for ! {
fn min_align(&self) -> usize { fn min_align(&self) -> usize {
unreachable!() unreachable!()
@ -83,5 +90,12 @@ pub mod rustc {
Primitive, Primitive,
} }
impl<'tcx> super::Def for Def<'tcx> {} impl<'tcx> super::Def for Def<'tcx> {
fn has_safety_invariants(&self) -> bool {
// Rust presently has no notion of 'unsafe fields', so for now we
// make the conservative assumption that everything besides
// primitive types carry safety invariants.
self != &Self::Primitive
}
}
} }

View file

@ -81,7 +81,8 @@ where
Self::Seq(vec![Self::uninit(); width_in_bytes]) Self::Seq(vec![Self::uninit(); width_in_bytes])
} }
/// Remove all `Def` nodes, and all branches of the layout for which `f` produces false. /// Remove all `Def` nodes, and all branches of the layout for which `f`
/// produces `true`.
pub(crate) fn prune<F>(self, f: &F) -> Tree<!, R> pub(crate) fn prune<F>(self, f: &F) -> Tree<!, R>
where where
F: Fn(D) -> bool, F: Fn(D) -> bool,
@ -106,7 +107,7 @@ where
Self::Byte(b) => Tree::Byte(b), Self::Byte(b) => Tree::Byte(b),
Self::Ref(r) => Tree::Ref(r), Self::Ref(r) => Tree::Ref(r),
Self::Def(d) => { Self::Def(d) => {
if !f(d) { if f(d) {
Tree::uninhabited() Tree::uninhabited()
} else { } else {
Tree::unit() Tree::unit()

View file

@ -2,11 +2,15 @@ use super::Tree;
#[derive(Debug, Hash, Eq, PartialEq, Clone, Copy)] #[derive(Debug, Hash, Eq, PartialEq, Clone, Copy)]
pub enum Def { pub enum Def {
Visible, NoSafetyInvariants,
Invisible, HasSafetyInvariants,
} }
impl super::Def for Def {} impl super::Def for Def {
fn has_safety_invariants(&self) -> bool {
self == &Self::HasSafetyInvariants
}
}
mod prune { mod prune {
use super::*; use super::*;
@ -16,17 +20,22 @@ mod prune {
#[test] #[test]
fn seq_1() { fn seq_1() {
let layout: Tree<Def, !> = Tree::def(Def::Visible).then(Tree::from_bits(0x00)); let layout: Tree<Def, !> =
assert_eq!(layout.prune(&|d| matches!(d, Def::Visible)), Tree::from_bits(0x00)); Tree::def(Def::NoSafetyInvariants).then(Tree::from_bits(0x00));
assert_eq!(
layout.prune(&|d| matches!(d, Def::HasSafetyInvariants)),
Tree::from_bits(0x00)
);
} }
#[test] #[test]
fn seq_2() { fn seq_2() {
let layout: Tree<Def, !> = let layout: Tree<Def, !> = Tree::from_bits(0x00)
Tree::from_bits(0x00).then(Tree::def(Def::Visible)).then(Tree::from_bits(0x01)); .then(Tree::def(Def::NoSafetyInvariants))
.then(Tree::from_bits(0x01));
assert_eq!( assert_eq!(
layout.prune(&|d| matches!(d, Def::Visible)), layout.prune(&|d| matches!(d, Def::HasSafetyInvariants)),
Tree::from_bits(0x00).then(Tree::from_bits(0x01)) Tree::from_bits(0x00).then(Tree::from_bits(0x01))
); );
} }
@ -37,21 +46,32 @@ mod prune {
#[test] #[test]
fn invisible_def() { fn invisible_def() {
let layout: Tree<Def, !> = Tree::def(Def::Invisible); let layout: Tree<Def, !> = Tree::def(Def::HasSafetyInvariants);
assert_eq!(layout.prune(&|d| matches!(d, Def::Visible)), Tree::uninhabited()); assert_eq!(
layout.prune(&|d| matches!(d, Def::HasSafetyInvariants)),
Tree::uninhabited()
);
} }
#[test] #[test]
fn invisible_def_in_seq_len_2() { fn invisible_def_in_seq_len_2() {
let layout: Tree<Def, !> = Tree::def(Def::Visible).then(Tree::def(Def::Invisible)); let layout: Tree<Def, !> =
assert_eq!(layout.prune(&|d| matches!(d, Def::Visible)), Tree::uninhabited()); Tree::def(Def::NoSafetyInvariants).then(Tree::def(Def::HasSafetyInvariants));
assert_eq!(
layout.prune(&|d| matches!(d, Def::HasSafetyInvariants)),
Tree::uninhabited()
);
} }
#[test] #[test]
fn invisible_def_in_seq_len_3() { fn invisible_def_in_seq_len_3() {
let layout: Tree<Def, !> = let layout: Tree<Def, !> = Tree::def(Def::NoSafetyInvariants)
Tree::def(Def::Visible).then(Tree::from_bits(0x00)).then(Tree::def(Def::Invisible)); .then(Tree::from_bits(0x00))
assert_eq!(layout.prune(&|d| matches!(d, Def::Visible)), Tree::uninhabited()); .then(Tree::def(Def::HasSafetyInvariants));
assert_eq!(
layout.prune(&|d| matches!(d, Def::HasSafetyInvariants)),
Tree::uninhabited()
);
} }
} }
@ -60,21 +80,26 @@ mod prune {
#[test] #[test]
fn visible_def() { fn visible_def() {
let layout: Tree<Def, !> = Tree::def(Def::Visible); let layout: Tree<Def, !> = Tree::def(Def::NoSafetyInvariants);
assert_eq!(layout.prune(&|d| matches!(d, Def::Visible)), Tree::unit()); assert_eq!(layout.prune(&|d| matches!(d, Def::HasSafetyInvariants)), Tree::unit());
} }
#[test] #[test]
fn visible_def_in_seq_len_2() { fn visible_def_in_seq_len_2() {
let layout: Tree<Def, !> = Tree::def(Def::Visible).then(Tree::def(Def::Visible)); let layout: Tree<Def, !> =
assert_eq!(layout.prune(&|d| matches!(d, Def::Visible)), Tree::unit()); Tree::def(Def::NoSafetyInvariants).then(Tree::def(Def::NoSafetyInvariants));
assert_eq!(layout.prune(&|d| matches!(d, Def::HasSafetyInvariants)), Tree::unit());
} }
#[test] #[test]
fn visible_def_in_seq_len_3() { fn visible_def_in_seq_len_3() {
let layout: Tree<Def, !> = let layout: Tree<Def, !> = Tree::def(Def::NoSafetyInvariants)
Tree::def(Def::Visible).then(Tree::from_bits(0x00)).then(Tree::def(Def::Visible)); .then(Tree::from_bits(0x00))
assert_eq!(layout.prune(&|d| matches!(d, Def::Visible)), Tree::from_bits(0x00)); .then(Tree::def(Def::NoSafetyInvariants));
assert_eq!(
layout.prune(&|d| matches!(d, Def::HasSafetyInvariants)),
Tree::from_bits(0x00)
);
} }
} }
} }

View file

@ -49,8 +49,8 @@ pub enum Reason {
DstIsUnspecified, DstIsUnspecified,
/// The layout of the destination type is bit-incompatible with the source type. /// The layout of the destination type is bit-incompatible with the source type.
DstIsBitIncompatible, DstIsBitIncompatible,
/// There aren't any public constructors for `Dst`. /// The destination type may carry safety invariants.
DstIsPrivate, DstMayHaveSafetyInvariants,
/// `Dst` is larger than `Src`, and the excess bytes were not exclusively uninitialized. /// `Dst` is larger than `Src`, and the excess bytes were not exclusively uninitialized.
DstIsTooBig, DstIsTooBig,
/// Src should have a stricter alignment than Dst, but it does not. /// Src should have a stricter alignment than Dst, but it does not.
@ -106,13 +106,11 @@ mod rustc {
&mut self, &mut self,
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
types: Types<'tcx>, types: Types<'tcx>,
scope: Ty<'tcx>,
assume: crate::Assume, assume: crate::Assume,
) -> crate::Answer<crate::layout::rustc::Ref<'tcx>> { ) -> crate::Answer<crate::layout::rustc::Ref<'tcx>> {
crate::maybe_transmutable::MaybeTransmutableQuery::new( crate::maybe_transmutable::MaybeTransmutableQuery::new(
types.src, types.src,
types.dst, types.dst,
scope,
assume, assume,
self.infcx.tcx, self.infcx.tcx,
) )

View file

@ -3,7 +3,7 @@ pub(crate) mod query_context;
mod tests; mod tests;
use crate::{ use crate::{
layout::{self, dfa, Byte, Dfa, Nfa, Ref, Tree, Uninhabited}, layout::{self, dfa, Byte, Def, Dfa, Nfa, Ref, Tree, Uninhabited},
maybe_transmutable::query_context::QueryContext, maybe_transmutable::query_context::QueryContext,
Answer, Condition, Map, Reason, Answer, Condition, Map, Reason,
}; };
@ -14,7 +14,6 @@ where
{ {
src: L, src: L,
dst: L, dst: L,
scope: <C as QueryContext>::Scope,
assume: crate::Assume, assume: crate::Assume,
context: C, context: C,
} }
@ -23,14 +22,8 @@ impl<L, C> MaybeTransmutableQuery<L, C>
where where
C: QueryContext, C: QueryContext,
{ {
pub(crate) fn new( pub(crate) fn new(src: L, dst: L, assume: crate::Assume, context: C) -> Self {
src: L, Self { src, dst, assume, context }
dst: L,
scope: <C as QueryContext>::Scope,
assume: crate::Assume,
context: C,
) -> Self {
Self { src, dst, scope, assume, context }
} }
} }
@ -48,7 +41,7 @@ mod rustc {
/// then computes an answer using those trees. /// then computes an answer using those trees.
#[instrument(level = "debug", skip(self), fields(src = ?self.src, dst = ?self.dst))] #[instrument(level = "debug", skip(self), fields(src = ?self.src, dst = ?self.dst))]
pub fn answer(self) -> Answer<<TyCtxt<'tcx> as QueryContext>::Ref> { pub fn answer(self) -> Answer<<TyCtxt<'tcx> as QueryContext>::Ref> {
let Self { src, dst, scope, assume, context } = self; let Self { src, dst, assume, context } = self;
// Convert `src` and `dst` from their rustc representations, to `Tree`-based // Convert `src` and `dst` from their rustc representations, to `Tree`-based
// representations. If these conversions fail, conclude that the transmutation is // representations. If these conversions fail, conclude that the transmutation is
@ -67,9 +60,7 @@ mod rustc {
(_, Err(Err::Unspecified)) => Answer::No(Reason::DstIsUnspecified), (_, Err(Err::Unspecified)) => Answer::No(Reason::DstIsUnspecified),
(Err(Err::SizeOverflow), _) => Answer::No(Reason::SrcSizeOverflow), (Err(Err::SizeOverflow), _) => Answer::No(Reason::SrcSizeOverflow),
(_, Err(Err::SizeOverflow)) => Answer::No(Reason::DstSizeOverflow), (_, Err(Err::SizeOverflow)) => Answer::No(Reason::DstSizeOverflow),
(Ok(src), Ok(dst)) => { (Ok(src), Ok(dst)) => MaybeTransmutableQuery { src, dst, assume, context }.answer(),
MaybeTransmutableQuery { src, dst, scope, assume, context }.answer()
}
} }
} }
} }
@ -86,43 +77,51 @@ where
#[inline(always)] #[inline(always)]
#[instrument(level = "debug", skip(self), fields(src = ?self.src, dst = ?self.dst))] #[instrument(level = "debug", skip(self), fields(src = ?self.src, dst = ?self.dst))]
pub(crate) fn answer(self) -> Answer<<C as QueryContext>::Ref> { pub(crate) fn answer(self) -> Answer<<C as QueryContext>::Ref> {
let assume_visibility = self.assume.safety; let Self { src, dst, assume, context } = self;
let Self { src, dst, scope, assume, context } = self; // Unconditionally all `Def` nodes from `src`, without pruning away the
// branches they appear in. This is valid to do for value-to-value
// Remove all `Def` nodes from `src`, without checking their visibility. // transmutations, but not for `&mut T` to `&mut U`; we will need to be
let src = src.prune(&|def| true); // more sophisticated to handle transmutations between mutable
// references.
let src = src.prune(&|def| false);
trace!(?src, "pruned src"); trace!(?src, "pruned src");
// Remove all `Def` nodes from `dst`, additionally... // Remove all `Def` nodes from `dst`, additionally...
let dst = if assume_visibility { let dst = if assume.safety {
// ...if visibility is assumed, don't check their visibility. // ...if safety is assumed, don't check if they carry safety
dst.prune(&|def| true) // invariants; retain all paths.
dst.prune(&|def| false)
} else { } else {
// ...otherwise, prune away all unreachable paths through the `Dst` layout. // ...otherwise, prune away all paths with safety invariants from
dst.prune(&|def| context.is_accessible_from(def, scope)) // the `Dst` layout.
dst.prune(&|def| def.has_safety_invariants())
}; };
trace!(?dst, "pruned dst"); trace!(?dst, "pruned dst");
// Convert `src` from a tree-based representation to an NFA-based representation. // Convert `src` from a tree-based representation to an NFA-based
// If the conversion fails because `src` is uninhabited, conclude that the transmutation // representation. If the conversion fails because `src` is uninhabited,
// is acceptable, because instances of the `src` type do not exist. // conclude that the transmutation is acceptable, because instances of
// the `src` type do not exist.
let src = match Nfa::from_tree(src) { let src = match Nfa::from_tree(src) {
Ok(src) => src, Ok(src) => src,
Err(Uninhabited) => return Answer::Yes, Err(Uninhabited) => return Answer::Yes,
}; };
// Convert `dst` from a tree-based representation to an NFA-based representation. // Convert `dst` from a tree-based representation to an NFA-based
// If the conversion fails because `src` is uninhabited, conclude that the transmutation // representation. If the conversion fails because `src` is uninhabited,
// is unacceptable, because instances of the `dst` type do not exist. // conclude that the transmutation is unacceptable. Valid instances of
// the `dst` type do not exist, either because it's genuinely
// uninhabited, or because there are no branches of the tree that are
// free of safety invariants.
let dst = match Nfa::from_tree(dst) { let dst = match Nfa::from_tree(dst) {
Ok(dst) => dst, Ok(dst) => dst,
Err(Uninhabited) => return Answer::No(Reason::DstIsPrivate), Err(Uninhabited) => return Answer::No(Reason::DstMayHaveSafetyInvariants),
}; };
MaybeTransmutableQuery { src, dst, scope, assume, context }.answer() MaybeTransmutableQuery { src, dst, assume, context }.answer()
} }
} }
@ -136,10 +135,10 @@ where
#[inline(always)] #[inline(always)]
#[instrument(level = "debug", skip(self), fields(src = ?self.src, dst = ?self.dst))] #[instrument(level = "debug", skip(self), fields(src = ?self.src, dst = ?self.dst))]
pub(crate) fn answer(self) -> Answer<<C as QueryContext>::Ref> { pub(crate) fn answer(self) -> Answer<<C as QueryContext>::Ref> {
let Self { src, dst, scope, assume, context } = self; let Self { src, dst, assume, context } = self;
let src = Dfa::from_nfa(src); let src = Dfa::from_nfa(src);
let dst = Dfa::from_nfa(dst); let dst = Dfa::from_nfa(dst);
MaybeTransmutableQuery { src, dst, scope, assume, context }.answer() MaybeTransmutableQuery { src, dst, assume, context }.answer()
} }
} }

View file

@ -6,9 +6,6 @@ pub(crate) trait QueryContext {
type Ref: layout::Ref; type Ref: layout::Ref;
type Scope: Copy; type Scope: Copy;
/// Is `def` accessible from the defining module of `scope`?
fn is_accessible_from(&self, def: Self::Def, scope: Self::Scope) -> bool;
fn min_align(&self, reference: Self::Ref) -> usize; fn min_align(&self, reference: Self::Ref) -> usize;
} }
@ -20,21 +17,21 @@ pub(crate) mod test {
#[derive(Debug, Hash, Eq, PartialEq, Clone, Copy)] #[derive(Debug, Hash, Eq, PartialEq, Clone, Copy)]
pub(crate) enum Def { pub(crate) enum Def {
Visible, HasSafetyInvariants,
Invisible, NoSafetyInvariants,
} }
impl crate::layout::Def for Def {} impl crate::layout::Def for Def {
fn has_safety_invariants(&self) -> bool {
self == &Self::HasSafetyInvariants
}
}
impl QueryContext for UltraMinimal { impl QueryContext for UltraMinimal {
type Def = Def; type Def = Def;
type Ref = !; type Ref = !;
type Scope = (); type Scope = ();
fn is_accessible_from(&self, def: Def, scope: ()) -> bool {
matches!(Def::Visible, def)
}
fn min_align(&self, reference: !) -> usize { fn min_align(&self, reference: !) -> usize {
unimplemented!() unimplemented!()
} }
@ -52,34 +49,6 @@ mod rustc {
type Scope = Ty<'tcx>; type Scope = Ty<'tcx>;
#[instrument(level = "debug", skip(self))]
fn is_accessible_from(&self, def: Self::Def, scope: Self::Scope) -> bool {
use layout::rustc::Def;
use rustc_middle::ty;
let parent = if let ty::Adt(adt_def, ..) = scope.kind() {
self.parent(adt_def.did())
} else {
// Is this always how we want to handle a non-ADT scope?
return false;
};
let def_id = match def {
Def::Adt(adt_def) => adt_def.did(),
Def::Variant(variant_def) => variant_def.def_id,
Def::Field(field_def) => field_def.did,
Def::Primitive => {
// primitives do not have a def_id, but they're always accessible
return true;
}
};
let ret: bool = self.visibility(def_id).is_accessible_from(parent, *self);
trace!(?ret, "ret");
ret
}
fn min_align(&self, reference: Self::Ref) -> usize { fn min_align(&self, reference: Self::Ref) -> usize {
unimplemented!() unimplemented!()
} }

View file

@ -3,6 +3,65 @@ use crate::maybe_transmutable::MaybeTransmutableQuery;
use crate::{layout, Reason}; use crate::{layout, Reason};
use itertools::Itertools; use itertools::Itertools;
mod safety {
use crate::Answer;
use super::*;
type Tree = layout::Tree<Def, !>;
const DST_HAS_SAFETY_INVARIANTS: Answer<!> =
Answer::No(crate::Reason::DstMayHaveSafetyInvariants);
fn is_transmutable(src: &Tree, dst: &Tree, assume_safety: bool) -> crate::Answer<!> {
let src = src.clone();
let dst = dst.clone();
// The only dimension of the transmutability analysis we want to test
// here is the safety analysis. To ensure this, we disable all other
// toggleable aspects of the transmutability analysis.
let assume = crate::Assume {
alignment: true,
lifetimes: true,
validity: true,
safety: assume_safety,
};
crate::maybe_transmutable::MaybeTransmutableQuery::new(src, dst, assume, UltraMinimal)
.answer()
}
#[test]
fn src_safe_dst_safe() {
let src = Tree::Def(Def::NoSafetyInvariants).then(Tree::u8());
let dst = Tree::Def(Def::NoSafetyInvariants).then(Tree::u8());
assert_eq!(is_transmutable(&src, &dst, false), Answer::Yes);
assert_eq!(is_transmutable(&src, &dst, true), Answer::Yes);
}
#[test]
fn src_safe_dst_unsafe() {
let src = Tree::Def(Def::NoSafetyInvariants).then(Tree::u8());
let dst = Tree::Def(Def::HasSafetyInvariants).then(Tree::u8());
assert_eq!(is_transmutable(&src, &dst, false), DST_HAS_SAFETY_INVARIANTS);
assert_eq!(is_transmutable(&src, &dst, true), Answer::Yes);
}
#[test]
fn src_unsafe_dst_safe() {
let src = Tree::Def(Def::HasSafetyInvariants).then(Tree::u8());
let dst = Tree::Def(Def::NoSafetyInvariants).then(Tree::u8());
assert_eq!(is_transmutable(&src, &dst, false), Answer::Yes);
assert_eq!(is_transmutable(&src, &dst, true), Answer::Yes);
}
#[test]
fn src_unsafe_dst_unsafe() {
let src = Tree::Def(Def::HasSafetyInvariants).then(Tree::u8());
let dst = Tree::Def(Def::HasSafetyInvariants).then(Tree::u8());
assert_eq!(is_transmutable(&src, &dst, false), DST_HAS_SAFETY_INVARIANTS);
assert_eq!(is_transmutable(&src, &dst, true), Answer::Yes);
}
}
mod bool { mod bool {
use crate::Answer; use crate::Answer;
@ -10,11 +69,9 @@ mod bool {
#[test] #[test]
fn should_permit_identity_transmutation_tree() { fn should_permit_identity_transmutation_tree() {
println!("{:?}", layout::Tree::<!, !>::bool());
let answer = crate::maybe_transmutable::MaybeTransmutableQuery::new( let answer = crate::maybe_transmutable::MaybeTransmutableQuery::new(
layout::Tree::<Def, !>::bool(), layout::Tree::<Def, !>::bool(),
layout::Tree::<Def, !>::bool(), layout::Tree::<Def, !>::bool(),
(),
crate::Assume { alignment: false, lifetimes: false, validity: true, safety: false }, crate::Assume { alignment: false, lifetimes: false, validity: true, safety: false },
UltraMinimal, UltraMinimal,
) )
@ -27,7 +84,6 @@ mod bool {
let answer = crate::maybe_transmutable::MaybeTransmutableQuery::new( let answer = crate::maybe_transmutable::MaybeTransmutableQuery::new(
layout::Dfa::<!>::bool(), layout::Dfa::<!>::bool(),
layout::Dfa::<!>::bool(), layout::Dfa::<!>::bool(),
(),
crate::Assume { alignment: false, lifetimes: false, validity: true, safety: false }, crate::Assume { alignment: false, lifetimes: false, validity: true, safety: false },
UltraMinimal, UltraMinimal,
) )
@ -71,7 +127,6 @@ mod bool {
MaybeTransmutableQuery::new( MaybeTransmutableQuery::new(
src_layout.clone(), src_layout.clone(),
dst_layout.clone(), dst_layout.clone(),
(),
crate::Assume { validity: false, ..crate::Assume::default() }, crate::Assume { validity: false, ..crate::Assume::default() },
UltraMinimal, UltraMinimal,
) )
@ -86,7 +141,6 @@ mod bool {
MaybeTransmutableQuery::new( MaybeTransmutableQuery::new(
src_layout.clone(), src_layout.clone(),
dst_layout.clone(), dst_layout.clone(),
(),
crate::Assume { validity: true, ..crate::Assume::default() }, crate::Assume { validity: true, ..crate::Assume::default() },
UltraMinimal, UltraMinimal,
) )
@ -101,7 +155,6 @@ mod bool {
MaybeTransmutableQuery::new( MaybeTransmutableQuery::new(
src_layout.clone(), src_layout.clone(),
dst_layout.clone(), dst_layout.clone(),
(),
crate::Assume { validity: false, ..crate::Assume::default() }, crate::Assume { validity: false, ..crate::Assume::default() },
UltraMinimal, UltraMinimal,
) )

View file

@ -6,10 +6,10 @@ use crate::marker::ConstParamTy;
/// any value of type `Self` are safely transmutable into a value of type `Dst`, in a given `Context`, /// 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. /// notwithstanding whatever safety checks you have asked the compiler to [`Assume`] are satisfied.
#[unstable(feature = "transmutability", issue = "99571")] #[unstable(feature = "transmutability", issue = "99571")]
#[lang = "transmute_trait"] #[cfg_attr(not(bootstrap), lang = "transmute_trait")]
#[rustc_deny_explicit_impl(implement_via_object = false)] #[rustc_deny_explicit_impl(implement_via_object = false)]
#[rustc_coinductive] #[rustc_coinductive]
pub unsafe trait BikeshedIntrinsicFrom<Src, Context, const ASSUME: Assume = { Assume::NOTHING }> pub unsafe trait BikeshedIntrinsicFrom<Src, const ASSUME: Assume = { Assume::NOTHING }>
where where
Src: ?Sized, Src: ?Sized,
{ {
@ -28,8 +28,9 @@ pub struct Assume {
/// that violates Rust's memory model. /// that violates Rust's memory model.
pub lifetimes: bool, pub lifetimes: bool,
/// When `true`, the compiler assumes that *you* have ensured that it is safe for you to violate the /// When `true`, the compiler assumes that *you* have ensured that no
/// type and field privacy of the destination type (and sometimes of the source type, too). /// unsoundness will arise from violating the safety invariants of the
/// destination type (and sometimes of the source type, too).
pub safety: bool, pub safety: bool,
/// When `true`, the compiler assumes that *you* are ensuring that the source type is actually a valid /// When `true`, the compiler assumes that *you* are ensuring that the source type is actually a valid

View file

@ -4133,7 +4133,6 @@
"ui/transmutability/issue-101739-2.rs", "ui/transmutability/issue-101739-2.rs",
"ui/transmutability/issue-110467.rs", "ui/transmutability/issue-110467.rs",
"ui/transmutability/issue-110892.rs", "ui/transmutability/issue-110892.rs",
"ui/transmute/issue-115402-overflow-size.rs",
"ui/trivial-bounds/issue-73021-impossible-inline.rs", "ui/trivial-bounds/issue-73021-impossible-inline.rs",
"ui/try-block/issue-45124.rs", "ui/try-block/issue-45124.rs",
"ui/try-trait/issue-32709.rs", "ui/try-trait/issue-32709.rs",

View file

@ -13,41 +13,27 @@ mod assert {
pub fn is_transmutable< pub fn is_transmutable<
Src, Src,
Dst, Dst,
Context,
const ASSUME: std::mem::Assume, const ASSUME: std::mem::Assume,
>() >()
where where
Dst: BikeshedIntrinsicFrom< Dst: BikeshedIntrinsicFrom<
Src, Src,
Context,
ASSUME, ASSUME,
>, >,
{} {}
} }
fn direct() { fn direct() {
struct Context; assert::is_transmutable::<(), (), { std::mem::Assume::NOTHING }>();
#[repr(C)] struct Src;
#[repr(C)] struct Dst;
assert::is_transmutable::<Src, Dst, Context, { std::mem::Assume::NOTHING }>();
} }
fn via_const() { fn via_const() {
struct Context;
#[repr(C)] struct Src;
#[repr(C)] struct Dst;
const FALSE: bool = false; const FALSE: bool = false;
assert::is_transmutable::<Src, Dst, Context, { std::mem::Assume::NOTHING }>(); assert::is_transmutable::<(), (), { std::mem::Assume::NOTHING }>();
} }
fn via_associated_const() { fn via_associated_const() {
struct Context;
#[repr(C)] struct Src;
#[repr(C)] struct Dst;
trait Trait { trait Trait {
const FALSE: bool = true; const FALSE: bool = true;
} }
@ -57,9 +43,8 @@ fn via_associated_const() {
impl Trait for Ty {} impl Trait for Ty {}
assert::is_transmutable::< assert::is_transmutable::<
Src, (),
Dst, (),
Context,
{ {
std::mem::Assume { std::mem::Assume {
alignment: {Ty::FALSE}, alignment: {Ty::FALSE},

View file

@ -7,12 +7,11 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn array_like<T, E, const N: usize>() pub fn array_like<T, E, const N: usize>()
where where
T: BikeshedIntrinsicFrom<[E; N], Context, { Assume::SAFETY }>, T: BikeshedIntrinsicFrom<[E; N], { Assume::SAFETY }>,
[E; N]: BikeshedIntrinsicFrom<T, Context, { Assume::SAFETY }> [E; N]: BikeshedIntrinsicFrom<T, { Assume::SAFETY }>
{} {}
} }

View file

@ -3,11 +3,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume { Assume {
alignment: false, alignment: false,
lifetimes: true, lifetimes: true,

View file

@ -1,16 +1,16 @@
error[E0277]: `&[u8; 0]` cannot be safely transmuted into `&[u16; 0]` in the defining scope of `assert::Context` error[E0277]: `&[u8; 0]` cannot be safely transmuted into `&[u16; 0]`
--> $DIR/align-fail.rs:22:55 --> $DIR/align-fail.rs:21:55
| |
LL | ...tatic [u8; 0], &'static [u16; 0]>(); LL | ...tatic [u8; 0], &'static [u16; 0]>();
| ^^^^^^^^^^^^^^^^^ The minimum alignment of `&[u8; 0]` (1) should be greater than that of `&[u16; 0]` (2) | ^^^^^^^^^^^^^^^^^ The minimum alignment of `&[u8; 0]` (1) should be greater than that of `&[u16; 0]` (2)
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/align-fail.rs:10:14 --> $DIR/align-fail.rs:9:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: false, LL | | alignment: false,

View file

@ -3,11 +3,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume { Assume {
alignment: false, alignment: false,
lifetimes: false, lifetimes: false,

View file

@ -2,11 +2,10 @@
#![feature(transmutability)] #![feature(transmutability)]
mod assert { mod assert {
use std::mem::BikeshedIntrinsicFrom; use std::mem::BikeshedIntrinsicFrom;
struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context>, Dst: BikeshedIntrinsicFrom<Src>,
{ {
} }
} }

View file

@ -1,32 +1,32 @@
error[E0277]: `()` cannot be safely transmuted into `ExplicitlyPadded` in the defining scope of `assert::Context` error[E0277]: `()` cannot be safely transmuted into `ExplicitlyPadded`
--> $DIR/issue-115402-overflow-size.rs:22:41 --> $DIR/huge-len.rs:21:41
| |
LL | assert::is_maybe_transmutable::<(), ExplicitlyPadded>(); LL | assert::is_maybe_transmutable::<(), ExplicitlyPadded>();
| ^^^^^^^^^^^^^^^^ values of the type `ExplicitlyPadded` are too big for the current architecture | ^^^^^^^^^^^^^^^^ values of the type `ExplicitlyPadded` are too big for the current architecture
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/issue-115402-overflow-size.rs:9:14 --> $DIR/huge-len.rs:8:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context>, LL | Dst: BikeshedIntrinsicFrom<Src>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
error[E0277]: `ExplicitlyPadded` cannot be safely transmuted into `()` in the defining scope of `assert::Context` error[E0277]: `ExplicitlyPadded` cannot be safely transmuted into `()`
--> $DIR/issue-115402-overflow-size.rs:25:55 --> $DIR/huge-len.rs:24:55
| |
LL | assert::is_maybe_transmutable::<ExplicitlyPadded, ()>(); LL | assert::is_maybe_transmutable::<ExplicitlyPadded, ()>();
| ^^ values of the type `ExplicitlyPadded` are too big for the current architecture | ^^ values of the type `ExplicitlyPadded` are too big for the current architecture
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/issue-115402-overflow-size.rs:9:14 --> $DIR/huge-len.rs:8:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context>, LL | Dst: BikeshedIntrinsicFrom<Src>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -4,13 +4,11 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom< Dst: BikeshedIntrinsicFrom<
Src, Src,
Context,
{ Assume { alignment: true, lifetimes: true, safety: true, validity: true } }, { Assume { alignment: true, lifetimes: true, safety: true, validity: true } },
>, >,
{ {

View file

@ -1,5 +1,5 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-103783-array-length.rs:21:34 --> $DIR/issue-103783-array-length.rs:19:34
| |
LL | type NaughtyLenArray = [u32; 3.14159]; LL | type NaughtyLenArray = [u32; 3.14159];
| ^^^^^^^ expected `usize`, found floating-point number | ^^^^^^^ expected `usize`, found floating-point number

View file

@ -7,11 +7,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY.and(Assume::VALIDITY) }> Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY.and(Assume::VALIDITY) }>
{} {}
} }

View file

@ -7,11 +7,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume::ALIGNMENT Assume::ALIGNMENT
.and(Assume::LIFETIMES) .and(Assume::LIFETIMES)
.and(Assume::SAFETY) .and(Assume::SAFETY)

View file

@ -6,11 +6,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume::ALIGNMENT Assume::ALIGNMENT
.and(Assume::LIFETIMES) .and(Assume::LIFETIMES)
.and(Assume::SAFETY) .and(Assume::SAFETY)

View file

@ -1,16 +1,16 @@
error[E0277]: `[String; 0]` cannot be safely transmuted into `()` in the defining scope of `assert::Context` error[E0277]: `[String; 0]` cannot be safely transmuted into `()`
--> $DIR/should_require_well_defined_layout.rs:26:52 --> $DIR/should_require_well_defined_layout.rs:25:52
| |
LL | assert::is_maybe_transmutable::<repr_rust, ()>(); LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `[String; 0]` does not have a well-specified layout | ^^ `[String; 0]` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14 --> $DIR/should_require_well_defined_layout.rs:12:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume::ALIGNMENT LL | | Assume::ALIGNMENT
LL | | .and(Assume::LIFETIMES) LL | | .and(Assume::LIFETIMES)
@ -19,19 +19,19 @@ LL | | .and(Assume::VALIDITY)
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `[String; 0]` in the defining scope of `assert::Context` error[E0277]: `u128` cannot be safely transmuted into `[String; 0]`
--> $DIR/should_require_well_defined_layout.rs:27:47 --> $DIR/should_require_well_defined_layout.rs:26:47
| |
LL | assert::is_maybe_transmutable::<u128, repr_rust>(); LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `[String; 0]` does not have a well-specified layout | ^^^^^^^^^ `[String; 0]` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14 --> $DIR/should_require_well_defined_layout.rs:12:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume::ALIGNMENT LL | | Assume::ALIGNMENT
LL | | .and(Assume::LIFETIMES) LL | | .and(Assume::LIFETIMES)
@ -40,19 +40,19 @@ LL | | .and(Assume::VALIDITY)
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `[String; 1]` cannot be safely transmuted into `()` in the defining scope of `assert::Context` error[E0277]: `[String; 1]` cannot be safely transmuted into `()`
--> $DIR/should_require_well_defined_layout.rs:32:52 --> $DIR/should_require_well_defined_layout.rs:31:52
| |
LL | assert::is_maybe_transmutable::<repr_rust, ()>(); LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `[String; 1]` does not have a well-specified layout | ^^ `[String; 1]` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14 --> $DIR/should_require_well_defined_layout.rs:12:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume::ALIGNMENT LL | | Assume::ALIGNMENT
LL | | .and(Assume::LIFETIMES) LL | | .and(Assume::LIFETIMES)
@ -61,19 +61,19 @@ LL | | .and(Assume::VALIDITY)
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `[String; 1]` in the defining scope of `assert::Context` error[E0277]: `u128` cannot be safely transmuted into `[String; 1]`
--> $DIR/should_require_well_defined_layout.rs:33:47 --> $DIR/should_require_well_defined_layout.rs:32:47
| |
LL | assert::is_maybe_transmutable::<u128, repr_rust>(); LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `[String; 1]` does not have a well-specified layout | ^^^^^^^^^ `[String; 1]` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14 --> $DIR/should_require_well_defined_layout.rs:12:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume::ALIGNMENT LL | | Assume::ALIGNMENT
LL | | .and(Assume::LIFETIMES) LL | | .and(Assume::LIFETIMES)
@ -82,19 +82,19 @@ LL | | .and(Assume::VALIDITY)
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `[String; 2]` cannot be safely transmuted into `()` in the defining scope of `assert::Context` error[E0277]: `[String; 2]` cannot be safely transmuted into `()`
--> $DIR/should_require_well_defined_layout.rs:38:52 --> $DIR/should_require_well_defined_layout.rs:37:52
| |
LL | assert::is_maybe_transmutable::<repr_rust, ()>(); LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `[String; 2]` does not have a well-specified layout | ^^ `[String; 2]` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14 --> $DIR/should_require_well_defined_layout.rs:12:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume::ALIGNMENT LL | | Assume::ALIGNMENT
LL | | .and(Assume::LIFETIMES) LL | | .and(Assume::LIFETIMES)
@ -103,19 +103,19 @@ LL | | .and(Assume::VALIDITY)
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `[String; 2]` in the defining scope of `assert::Context` error[E0277]: `u128` cannot be safely transmuted into `[String; 2]`
--> $DIR/should_require_well_defined_layout.rs:39:47 --> $DIR/should_require_well_defined_layout.rs:38:47
| |
LL | assert::is_maybe_transmutable::<u128, repr_rust>(); LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `[String; 2]` does not have a well-specified layout | ^^^^^^^^^ `[String; 2]` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14 --> $DIR/should_require_well_defined_layout.rs:12:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume::ALIGNMENT LL | | Assume::ALIGNMENT
LL | | .and(Assume::LIFETIMES) LL | | .and(Assume::LIFETIMES)

View file

@ -7,9 +7,9 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub fn is_transmutable<Src, Dst, Context>() pub fn is_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume { Assume {
alignment: true, alignment: true,
lifetimes: true, lifetimes: true,
@ -36,8 +36,6 @@ struct Zst;
#[repr(usize)] enum V0usize { V } #[repr(usize)] enum V0usize { V }
fn n8() { fn n8() {
struct Context;
type Smaller = Zst; type Smaller = Zst;
type Analog = u8; type Analog = u8;
type Larger = u16; type Larger = u16;
@ -45,23 +43,21 @@ fn n8() {
fn i_should_have_correct_length() { fn i_should_have_correct_length() {
type Current = V0i8; type Current = V0i8;
assert::is_transmutable::<Smaller, Current, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Smaller, Current>(); //~ ERROR cannot be safely transmuted
assert::is_transmutable::<Current, Analog, Context>(); assert::is_transmutable::<Current, Analog>();
assert::is_transmutable::<Current, Larger, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
} }
fn u_should_have_correct_length() { fn u_should_have_correct_length() {
type Current = V0u8; type Current = V0u8;
assert::is_transmutable::<Smaller, Current, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Smaller, Current>(); //~ ERROR cannot be safely transmuted
assert::is_transmutable::<Current, Analog, Context>(); assert::is_transmutable::<Current, Analog>();
assert::is_transmutable::<Current, Larger, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
} }
} }
fn n16() { fn n16() {
struct Context;
type Smaller = u8; type Smaller = u8;
type Analog = u16; type Analog = u16;
type Larger = u32; type Larger = u32;
@ -69,23 +65,21 @@ fn n16() {
fn i_should_have_correct_length() { fn i_should_have_correct_length() {
type Current = V0i16; type Current = V0i16;
assert::is_transmutable::<Smaller, Current, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Smaller, Current>(); //~ ERROR cannot be safely transmuted
assert::is_transmutable::<Current, Analog, Context>(); assert::is_transmutable::<Current, Analog>();
assert::is_transmutable::<Current, Larger, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
} }
fn u_should_have_correct_length() { fn u_should_have_correct_length() {
type Current = V0u16; type Current = V0u16;
assert::is_transmutable::<Smaller, Current, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Smaller, Current>(); //~ ERROR cannot be safely transmuted
assert::is_transmutable::<Current, Analog, Context>(); assert::is_transmutable::<Current, Analog>();
assert::is_transmutable::<Current, Larger, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
} }
} }
fn n32() { fn n32() {
struct Context;
type Smaller = u16; type Smaller = u16;
type Analog = u32; type Analog = u32;
type Larger = u64; type Larger = u64;
@ -93,23 +87,21 @@ fn n32() {
fn i_should_have_correct_length() { fn i_should_have_correct_length() {
type Current = V0i32; type Current = V0i32;
assert::is_transmutable::<Smaller, Current, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Smaller, Current>(); //~ ERROR cannot be safely transmuted
assert::is_transmutable::<Current, Analog, Context>(); assert::is_transmutable::<Current, Analog>();
assert::is_transmutable::<Current, Larger, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
} }
fn u_should_have_correct_length() { fn u_should_have_correct_length() {
type Current = V0u32; type Current = V0u32;
assert::is_transmutable::<Smaller, Current, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Smaller, Current>(); //~ ERROR cannot be safely transmuted
assert::is_transmutable::<Current, Analog, Context>(); assert::is_transmutable::<Current, Analog>();
assert::is_transmutable::<Current, Larger, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
} }
} }
fn n64() { fn n64() {
struct Context;
type Smaller = u32; type Smaller = u32;
type Analog = u64; type Analog = u64;
type Larger = u128; type Larger = u128;
@ -117,23 +109,21 @@ fn n64() {
fn i_should_have_correct_length() { fn i_should_have_correct_length() {
type Current = V0i64; type Current = V0i64;
assert::is_transmutable::<Smaller, Current, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Smaller, Current>(); //~ ERROR cannot be safely transmuted
assert::is_transmutable::<Current, Analog, Context>(); assert::is_transmutable::<Current, Analog>();
assert::is_transmutable::<Current, Larger, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
} }
fn u_should_have_correct_length() { fn u_should_have_correct_length() {
type Current = V0u64; type Current = V0u64;
assert::is_transmutable::<Smaller, Current, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Smaller, Current>(); //~ ERROR cannot be safely transmuted
assert::is_transmutable::<Current, Analog, Context>(); assert::is_transmutable::<Current, Analog>();
assert::is_transmutable::<Current, Larger, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
} }
} }
fn nsize() { fn nsize() {
struct Context;
type Smaller = u8; type Smaller = u8;
type Analog = usize; type Analog = usize;
type Larger = [usize; 2]; type Larger = [usize; 2];
@ -141,16 +131,16 @@ fn nsize() {
fn i_should_have_correct_length() { fn i_should_have_correct_length() {
type Current = V0isize; type Current = V0isize;
assert::is_transmutable::<Smaller, Current, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Smaller, Current>(); //~ ERROR cannot be safely transmuted
assert::is_transmutable::<Current, Analog, Context>(); assert::is_transmutable::<Current, Analog>();
assert::is_transmutable::<Current, Larger, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
} }
fn u_should_have_correct_length() { fn u_should_have_correct_length() {
type Current = V0usize; type Current = V0usize;
assert::is_transmutable::<Smaller, Current, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Smaller, Current>(); //~ ERROR cannot be safely transmuted
assert::is_transmutable::<Current, Analog, Context>(); assert::is_transmutable::<Current, Analog>();
assert::is_transmutable::<Current, Larger, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Current, Larger>(); //~ ERROR cannot be safely transmuted
} }
} }

View file

@ -1,16 +1,16 @@
error[E0277]: `Zst` cannot be safely transmuted into `V0i8` in the defining scope of `n8::Context` error[E0277]: `Zst` cannot be safely transmuted into `V0i8`
--> $DIR/primitive_reprs_should_have_correct_length.rs:48:44 --> $DIR/primitive_reprs_should_have_correct_length.rs:46:44
| |
LL | assert::is_transmutable::<Smaller, Current, Context>(); LL | assert::is_transmutable::<Smaller, Current>();
| ^^^^^^^ The size of `Zst` is smaller than the size of `V0i8` | ^^^^^^^ The size of `Zst` is smaller than the size of `V0i8`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -20,19 +20,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_transmutable` | |__________^ required by this bound in `is_transmutable`
error[E0277]: `V0i8` cannot be safely transmuted into `u16` in the defining scope of `n8::Context` error[E0277]: `V0i8` cannot be safely transmuted into `u16`
--> $DIR/primitive_reprs_should_have_correct_length.rs:50:44 --> $DIR/primitive_reprs_should_have_correct_length.rs:48:44
| |
LL | assert::is_transmutable::<Current, Larger, Context>(); LL | assert::is_transmutable::<Current, Larger>();
| ^^^^^^ The size of `V0i8` is smaller than the size of `u16` | ^^^^^^ The size of `V0i8` is smaller than the size of `u16`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -42,19 +42,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_transmutable` | |__________^ required by this bound in `is_transmutable`
error[E0277]: `Zst` cannot be safely transmuted into `V0u8` in the defining scope of `n8::Context` error[E0277]: `Zst` cannot be safely transmuted into `V0u8`
--> $DIR/primitive_reprs_should_have_correct_length.rs:56:44 --> $DIR/primitive_reprs_should_have_correct_length.rs:54:44
| |
LL | assert::is_transmutable::<Smaller, Current, Context>(); LL | assert::is_transmutable::<Smaller, Current>();
| ^^^^^^^ The size of `Zst` is smaller than the size of `V0u8` | ^^^^^^^ The size of `Zst` is smaller than the size of `V0u8`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -64,19 +64,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_transmutable` | |__________^ required by this bound in `is_transmutable`
error[E0277]: `V0u8` cannot be safely transmuted into `u16` in the defining scope of `n8::Context` error[E0277]: `V0u8` cannot be safely transmuted into `u16`
--> $DIR/primitive_reprs_should_have_correct_length.rs:58:44 --> $DIR/primitive_reprs_should_have_correct_length.rs:56:44
| |
LL | assert::is_transmutable::<Current, Larger, Context>(); LL | assert::is_transmutable::<Current, Larger>();
| ^^^^^^ The size of `V0u8` is smaller than the size of `u16` | ^^^^^^ The size of `V0u8` is smaller than the size of `u16`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -86,19 +86,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_transmutable` | |__________^ required by this bound in `is_transmutable`
error[E0277]: `u8` cannot be safely transmuted into `V0i16` in the defining scope of `n16::Context` error[E0277]: `u8` cannot be safely transmuted into `V0i16`
--> $DIR/primitive_reprs_should_have_correct_length.rs:72:44 --> $DIR/primitive_reprs_should_have_correct_length.rs:68:44
| |
LL | assert::is_transmutable::<Smaller, Current, Context>(); LL | assert::is_transmutable::<Smaller, Current>();
| ^^^^^^^ The size of `u8` is smaller than the size of `V0i16` | ^^^^^^^ The size of `u8` is smaller than the size of `V0i16`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -108,19 +108,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_transmutable` | |__________^ required by this bound in `is_transmutable`
error[E0277]: `V0i16` cannot be safely transmuted into `u32` in the defining scope of `n16::Context` error[E0277]: `V0i16` cannot be safely transmuted into `u32`
--> $DIR/primitive_reprs_should_have_correct_length.rs:74:44 --> $DIR/primitive_reprs_should_have_correct_length.rs:70:44
| |
LL | assert::is_transmutable::<Current, Larger, Context>(); LL | assert::is_transmutable::<Current, Larger>();
| ^^^^^^ The size of `V0i16` is smaller than the size of `u32` | ^^^^^^ The size of `V0i16` is smaller than the size of `u32`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -130,19 +130,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_transmutable` | |__________^ required by this bound in `is_transmutable`
error[E0277]: `u8` cannot be safely transmuted into `V0u16` in the defining scope of `n16::Context` error[E0277]: `u8` cannot be safely transmuted into `V0u16`
--> $DIR/primitive_reprs_should_have_correct_length.rs:80:44 --> $DIR/primitive_reprs_should_have_correct_length.rs:76:44
| |
LL | assert::is_transmutable::<Smaller, Current, Context>(); LL | assert::is_transmutable::<Smaller, Current>();
| ^^^^^^^ The size of `u8` is smaller than the size of `V0u16` | ^^^^^^^ The size of `u8` is smaller than the size of `V0u16`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -152,19 +152,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_transmutable` | |__________^ required by this bound in `is_transmutable`
error[E0277]: `V0u16` cannot be safely transmuted into `u32` in the defining scope of `n16::Context` error[E0277]: `V0u16` cannot be safely transmuted into `u32`
--> $DIR/primitive_reprs_should_have_correct_length.rs:82:44 --> $DIR/primitive_reprs_should_have_correct_length.rs:78:44
| |
LL | assert::is_transmutable::<Current, Larger, Context>(); LL | assert::is_transmutable::<Current, Larger>();
| ^^^^^^ The size of `V0u16` is smaller than the size of `u32` | ^^^^^^ The size of `V0u16` is smaller than the size of `u32`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -174,19 +174,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_transmutable` | |__________^ required by this bound in `is_transmutable`
error[E0277]: `u16` cannot be safely transmuted into `V0i32` in the defining scope of `n32::Context` error[E0277]: `u16` cannot be safely transmuted into `V0i32`
--> $DIR/primitive_reprs_should_have_correct_length.rs:96:44 --> $DIR/primitive_reprs_should_have_correct_length.rs:90:44
| |
LL | assert::is_transmutable::<Smaller, Current, Context>(); LL | assert::is_transmutable::<Smaller, Current>();
| ^^^^^^^ The size of `u16` is smaller than the size of `V0i32` | ^^^^^^^ The size of `u16` is smaller than the size of `V0i32`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -196,19 +196,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_transmutable` | |__________^ required by this bound in `is_transmutable`
error[E0277]: `V0i32` cannot be safely transmuted into `u64` in the defining scope of `n32::Context` error[E0277]: `V0i32` cannot be safely transmuted into `u64`
--> $DIR/primitive_reprs_should_have_correct_length.rs:98:44 --> $DIR/primitive_reprs_should_have_correct_length.rs:92:44
| |
LL | assert::is_transmutable::<Current, Larger, Context>(); LL | assert::is_transmutable::<Current, Larger>();
| ^^^^^^ The size of `V0i32` is smaller than the size of `u64` | ^^^^^^ The size of `V0i32` is smaller than the size of `u64`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -218,19 +218,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_transmutable` | |__________^ required by this bound in `is_transmutable`
error[E0277]: `u16` cannot be safely transmuted into `V0u32` in the defining scope of `n32::Context` error[E0277]: `u16` cannot be safely transmuted into `V0u32`
--> $DIR/primitive_reprs_should_have_correct_length.rs:104:44 --> $DIR/primitive_reprs_should_have_correct_length.rs:98:44
| |
LL | assert::is_transmutable::<Smaller, Current, Context>(); LL | assert::is_transmutable::<Smaller, Current>();
| ^^^^^^^ The size of `u16` is smaller than the size of `V0u32` | ^^^^^^^ The size of `u16` is smaller than the size of `V0u32`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -240,19 +240,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_transmutable` | |__________^ required by this bound in `is_transmutable`
error[E0277]: `V0u32` cannot be safely transmuted into `u64` in the defining scope of `n32::Context` error[E0277]: `V0u32` cannot be safely transmuted into `u64`
--> $DIR/primitive_reprs_should_have_correct_length.rs:106:44 --> $DIR/primitive_reprs_should_have_correct_length.rs:100:44
| |
LL | assert::is_transmutable::<Current, Larger, Context>(); LL | assert::is_transmutable::<Current, Larger>();
| ^^^^^^ The size of `V0u32` is smaller than the size of `u64` | ^^^^^^ The size of `V0u32` is smaller than the size of `u64`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -262,19 +262,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_transmutable` | |__________^ required by this bound in `is_transmutable`
error[E0277]: `u32` cannot be safely transmuted into `V0i64` in the defining scope of `n64::Context` error[E0277]: `u32` cannot be safely transmuted into `V0i64`
--> $DIR/primitive_reprs_should_have_correct_length.rs:120:44 --> $DIR/primitive_reprs_should_have_correct_length.rs:112:44
| |
LL | assert::is_transmutable::<Smaller, Current, Context>(); LL | assert::is_transmutable::<Smaller, Current>();
| ^^^^^^^ The size of `u32` is smaller than the size of `V0i64` | ^^^^^^^ The size of `u32` is smaller than the size of `V0i64`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -284,19 +284,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_transmutable` | |__________^ required by this bound in `is_transmutable`
error[E0277]: `V0i64` cannot be safely transmuted into `u128` in the defining scope of `n64::Context` error[E0277]: `V0i64` cannot be safely transmuted into `u128`
--> $DIR/primitive_reprs_should_have_correct_length.rs:122:44 --> $DIR/primitive_reprs_should_have_correct_length.rs:114:44
| |
LL | assert::is_transmutable::<Current, Larger, Context>(); LL | assert::is_transmutable::<Current, Larger>();
| ^^^^^^ The size of `V0i64` is smaller than the size of `u128` | ^^^^^^ The size of `V0i64` is smaller than the size of `u128`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -306,19 +306,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_transmutable` | |__________^ required by this bound in `is_transmutable`
error[E0277]: `u32` cannot be safely transmuted into `V0u64` in the defining scope of `n64::Context` error[E0277]: `u32` cannot be safely transmuted into `V0u64`
--> $DIR/primitive_reprs_should_have_correct_length.rs:128:44 --> $DIR/primitive_reprs_should_have_correct_length.rs:120:44
| |
LL | assert::is_transmutable::<Smaller, Current, Context>(); LL | assert::is_transmutable::<Smaller, Current>();
| ^^^^^^^ The size of `u32` is smaller than the size of `V0u64` | ^^^^^^^ The size of `u32` is smaller than the size of `V0u64`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -328,19 +328,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_transmutable` | |__________^ required by this bound in `is_transmutable`
error[E0277]: `V0u64` cannot be safely transmuted into `u128` in the defining scope of `n64::Context` error[E0277]: `V0u64` cannot be safely transmuted into `u128`
--> $DIR/primitive_reprs_should_have_correct_length.rs:130:44 --> $DIR/primitive_reprs_should_have_correct_length.rs:122:44
| |
LL | assert::is_transmutable::<Current, Larger, Context>(); LL | assert::is_transmutable::<Current, Larger>();
| ^^^^^^ The size of `V0u64` is smaller than the size of `u128` | ^^^^^^ The size of `V0u64` is smaller than the size of `u128`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -350,19 +350,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_transmutable` | |__________^ required by this bound in `is_transmutable`
error[E0277]: `u8` cannot be safely transmuted into `V0isize` in the defining scope of `nsize::Context` error[E0277]: `u8` cannot be safely transmuted into `V0isize`
--> $DIR/primitive_reprs_should_have_correct_length.rs:144:44 --> $DIR/primitive_reprs_should_have_correct_length.rs:134:44
| |
LL | assert::is_transmutable::<Smaller, Current, Context>(); LL | assert::is_transmutable::<Smaller, Current>();
| ^^^^^^^ The size of `u8` is smaller than the size of `V0isize` | ^^^^^^^ The size of `u8` is smaller than the size of `V0isize`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -372,19 +372,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_transmutable` | |__________^ required by this bound in `is_transmutable`
error[E0277]: `V0isize` cannot be safely transmuted into `[usize; 2]` in the defining scope of `nsize::Context` error[E0277]: `V0isize` cannot be safely transmuted into `[usize; 2]`
--> $DIR/primitive_reprs_should_have_correct_length.rs:146:44 --> $DIR/primitive_reprs_should_have_correct_length.rs:136:44
| |
LL | assert::is_transmutable::<Current, Larger, Context>(); LL | assert::is_transmutable::<Current, Larger>();
| ^^^^^^ The size of `V0isize` is smaller than the size of `[usize; 2]` | ^^^^^^ The size of `V0isize` is smaller than the size of `[usize; 2]`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -394,19 +394,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_transmutable` | |__________^ required by this bound in `is_transmutable`
error[E0277]: `u8` cannot be safely transmuted into `V0usize` in the defining scope of `nsize::Context` error[E0277]: `u8` cannot be safely transmuted into `V0usize`
--> $DIR/primitive_reprs_should_have_correct_length.rs:152:44 --> $DIR/primitive_reprs_should_have_correct_length.rs:142:44
| |
LL | assert::is_transmutable::<Smaller, Current, Context>(); LL | assert::is_transmutable::<Smaller, Current>();
| ^^^^^^^ The size of `u8` is smaller than the size of `V0usize` | ^^^^^^^ The size of `u8` is smaller than the size of `V0usize`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -416,19 +416,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_transmutable` | |__________^ required by this bound in `is_transmutable`
error[E0277]: `V0usize` cannot be safely transmuted into `[usize; 2]` in the defining scope of `nsize::Context` error[E0277]: `V0usize` cannot be safely transmuted into `[usize; 2]`
--> $DIR/primitive_reprs_should_have_correct_length.rs:154:44 --> $DIR/primitive_reprs_should_have_correct_length.rs:144:44
| |
LL | assert::is_transmutable::<Current, Larger, Context>(); LL | assert::is_transmutable::<Current, Larger>();
| ^^^^^^ The size of `V0usize` is smaller than the size of `[usize; 2]` | ^^^^^^ The size of `V0usize` is smaller than the size of `[usize; 2]`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,

View file

@ -7,11 +7,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume { Assume {
alignment: true, alignment: true,
lifetimes: true, lifetimes: true,

View file

@ -1,16 +1,16 @@
error[E0277]: `void::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context` error[E0277]: `void::repr_rust` cannot be safely transmuted into `()`
--> $DIR/should_require_well_defined_layout.rs:28:52 --> $DIR/should_require_well_defined_layout.rs:27:52
| |
LL | assert::is_maybe_transmutable::<repr_rust, ()>(); LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `void::repr_rust` does not have a well-specified layout | ^^ `void::repr_rust` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:14:14 --> $DIR/should_require_well_defined_layout.rs:13:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -20,19 +20,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `void::repr_rust` in the defining scope of `assert::Context` error[E0277]: `u128` cannot be safely transmuted into `void::repr_rust`
--> $DIR/should_require_well_defined_layout.rs:29:47 --> $DIR/should_require_well_defined_layout.rs:28:47
| |
LL | assert::is_maybe_transmutable::<u128, repr_rust>(); LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `void::repr_rust` does not have a well-specified layout | ^^^^^^^^^ `void::repr_rust` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:14:14 --> $DIR/should_require_well_defined_layout.rs:13:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -42,19 +42,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `singleton::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context` error[E0277]: `singleton::repr_rust` cannot be safely transmuted into `()`
--> $DIR/should_require_well_defined_layout.rs:34:52 --> $DIR/should_require_well_defined_layout.rs:33:52
| |
LL | assert::is_maybe_transmutable::<repr_rust, ()>(); LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `singleton::repr_rust` does not have a well-specified layout | ^^ `singleton::repr_rust` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:14:14 --> $DIR/should_require_well_defined_layout.rs:13:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -64,19 +64,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `singleton::repr_rust` in the defining scope of `assert::Context` error[E0277]: `u128` cannot be safely transmuted into `singleton::repr_rust`
--> $DIR/should_require_well_defined_layout.rs:35:47 --> $DIR/should_require_well_defined_layout.rs:34:47
| |
LL | assert::is_maybe_transmutable::<u128, repr_rust>(); LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `singleton::repr_rust` does not have a well-specified layout | ^^^^^^^^^ `singleton::repr_rust` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:14:14 --> $DIR/should_require_well_defined_layout.rs:13:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -86,19 +86,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `duplex::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context` error[E0277]: `duplex::repr_rust` cannot be safely transmuted into `()`
--> $DIR/should_require_well_defined_layout.rs:40:52 --> $DIR/should_require_well_defined_layout.rs:39:52
| |
LL | assert::is_maybe_transmutable::<repr_rust, ()>(); LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `duplex::repr_rust` does not have a well-specified layout | ^^ `duplex::repr_rust` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:14:14 --> $DIR/should_require_well_defined_layout.rs:13:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -108,19 +108,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `duplex::repr_rust` in the defining scope of `assert::Context` error[E0277]: `u128` cannot be safely transmuted into `duplex::repr_rust`
--> $DIR/should_require_well_defined_layout.rs:41:47 --> $DIR/should_require_well_defined_layout.rs:40:47
| |
LL | assert::is_maybe_transmutable::<u128, repr_rust>(); LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `duplex::repr_rust` does not have a well-specified layout | ^^^^^^^^^ `duplex::repr_rust` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:14:14 --> $DIR/should_require_well_defined_layout.rs:13:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,

View file

@ -7,11 +7,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_transmutable<Src, Dst>() pub fn is_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume::ALIGNMENT Assume::ALIGNMENT
.and(Assume::LIFETIMES) .and(Assume::LIFETIMES)
.and(Assume::SAFETY) .and(Assume::SAFETY)

View file

@ -8,9 +8,9 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub fn is_transmutable<Src, Dst, Context>() pub fn is_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume::ALIGNMENT Assume::ALIGNMENT
.and(Assume::LIFETIMES) .and(Assume::LIFETIMES)
.and(Assume::SAFETY) .and(Assume::SAFETY)
@ -38,8 +38,7 @@ enum Lopsided {
#[repr(C)] struct Dst(Lopsided, V2); #[repr(C)] struct Dst(Lopsided, V2);
fn should_pad_variants() { fn should_pad_variants() {
struct Context;
// If the implementation (incorrectly) fails to pad `Lopsided::Smol` with // If the implementation (incorrectly) fails to pad `Lopsided::Smol` with
// an uninitialized byte, this transmutation might be (wrongly) accepted: // an uninitialized byte, this transmutation might be (wrongly) accepted:
assert::is_transmutable::<Src, Dst, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Src, Dst>(); //~ ERROR cannot be safely transmuted
} }

View file

@ -1,16 +1,16 @@
error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `should_pad_variants::Context` error[E0277]: `Src` cannot be safely transmuted into `Dst`
--> $DIR/should_pad_variants.rs:44:36 --> $DIR/should_pad_variants.rs:43:36
| |
LL | assert::is_transmutable::<Src, Dst, Context>(); LL | assert::is_transmutable::<Src, Dst>();
| ^^^ The size of `Src` is smaller than the size of `Dst` | ^^^ The size of `Src` is smaller than the size of `Dst`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/should_pad_variants.rs:13:14 --> $DIR/should_pad_variants.rs:13:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume::ALIGNMENT LL | | Assume::ALIGNMENT
LL | | .and(Assume::LIFETIMES) LL | | .and(Assume::LIFETIMES)

View file

@ -7,11 +7,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_transmutable<Src, Dst>() pub fn is_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume::ALIGNMENT Assume::ALIGNMENT
.and(Assume::LIFETIMES) .and(Assume::LIFETIMES)
.and(Assume::SAFETY) .and(Assume::SAFETY)

View file

@ -1,16 +1,16 @@
error[E0277]: `Src` cannot be safely transmuted into `Unexpected` in the defining scope of `assert::Context` error[E0277]: `Src` cannot be safely transmuted into `Unexpected`
--> $DIR/should_respect_endianness.rs:36:36 --> $DIR/should_respect_endianness.rs:35:36
| |
LL | assert::is_transmutable::<Src, Unexpected>(); LL | assert::is_transmutable::<Src, Unexpected>();
| ^^^^^^^^^^ At least one value of `Src` isn't a bit-valid value of `Unexpected` | ^^^^^^^^^^ At least one value of `Src` isn't a bit-valid value of `Unexpected`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/should_respect_endianness.rs:14:14 --> $DIR/should_respect_endianness.rs:13:14
| |
LL | pub fn is_transmutable<Src, Dst>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume::ALIGNMENT LL | | Assume::ALIGNMENT
LL | | .and(Assume::LIFETIMES) LL | | .and(Assume::LIFETIMES)

View file

@ -3,9 +3,9 @@
mod assert { mod assert {
use std::mem::BikeshedIntrinsicFrom; use std::mem::BikeshedIntrinsicFrom;
pub fn is_transmutable<Src, Context, const ASSUME_ALIGNMENT: bool>() pub fn is_transmutable<Src, const ASSUME_ALIGNMENT: bool>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>, //~ ERROR cannot find type `Dst` in this scope Dst: BikeshedIntrinsicFrom<Src, ASSUME_ALIGNMENT>, //~ ERROR cannot find type `Dst` in this scope
//~^ the constant `ASSUME_ALIGNMENT` is not of type `Assume` //~^ the constant `ASSUME_ALIGNMENT` is not of type `Assume`
//~| ERROR: mismatched types //~| ERROR: mismatched types
{ {
@ -13,10 +13,9 @@ mod assert {
} }
fn via_const() { fn via_const() {
struct Context;
struct Src; struct Src;
assert::is_transmutable::<Src, Context, false>(); assert::is_transmutable::<Src, false>();
} }
fn main() {} fn main() {}

View file

@ -1,23 +1,23 @@
error[E0412]: cannot find type `Dst` in this scope error[E0412]: cannot find type `Dst` in this scope
--> $DIR/issue-101739-1.rs:8:9 --> $DIR/issue-101739-1.rs:8:9
| |
LL | Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>, LL | Dst: BikeshedIntrinsicFrom<Src, ASSUME_ALIGNMENT>,
| ^^^ not found in this scope | ^^^ not found in this scope
error: the constant `ASSUME_ALIGNMENT` is not of type `Assume` error: the constant `ASSUME_ALIGNMENT` is not of type `Assume`
--> $DIR/issue-101739-1.rs:8:14 --> $DIR/issue-101739-1.rs:8:14
| |
LL | Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>, LL | Dst: BikeshedIntrinsicFrom<Src, ASSUME_ALIGNMENT>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Assume`, found `bool` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Assume`, found `bool`
| |
note: required by a bound in `BikeshedIntrinsicFrom` note: required by a bound in `BikeshedIntrinsicFrom`
--> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL --> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-101739-1.rs:8:50 --> $DIR/issue-101739-1.rs:8:41
| |
LL | Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>, LL | Dst: BikeshedIntrinsicFrom<Src, ASSUME_ALIGNMENT>,
| ^^^^^^^^^^^^^^^^ expected `Assume`, found `bool` | ^^^^^^^^^^^^^^^^ expected `Assume`, found `bool`
error: aborting due to 3 previous errors error: aborting due to 3 previous errors

View file

@ -8,17 +8,15 @@ mod assert {
pub fn is_transmutable< pub fn is_transmutable<
Src, Src,
Dst, Dst,
Context,
const ASSUME_ALIGNMENT: bool, const ASSUME_ALIGNMENT: bool,
const ASSUME_LIFETIMES: bool, const ASSUME_LIFETIMES: bool,
const ASSUME_VALIDITY: bool, const ASSUME_VALIDITY: bool,
const ASSUME_VISIBILITY: bool, const ASSUME_VISIBILITY: bool,
>() >()
where where
Dst: BikeshedIntrinsicFrom< //~ ERROR trait takes at most 3 generic arguments but 6 generic arguments were supplied Dst: BikeshedIntrinsicFrom< //~ ERROR trait takes at most 2 generic arguments but 5 generic arguments were supplied
//~^ ERROR: the constant `ASSUME_ALIGNMENT` is not of type `Assume` //~^ ERROR: the constant `ASSUME_ALIGNMENT` is not of type `Assume`
Src, Src,
Context,
ASSUME_ALIGNMENT, //~ ERROR: mismatched types ASSUME_ALIGNMENT, //~ ERROR: mismatched types
ASSUME_LIFETIMES, ASSUME_LIFETIMES,
ASSUME_VALIDITY, ASSUME_VALIDITY,
@ -28,11 +26,10 @@ mod assert {
} }
fn via_const() { fn via_const() {
struct Context;
#[repr(C)] struct Src; #[repr(C)] struct Src;
#[repr(C)] struct Dst; #[repr(C)] struct Dst;
const FALSE: bool = false; const FALSE: bool = false;
assert::is_transmutable::<Src, Dst, Context, FALSE, FALSE, FALSE, FALSE>(); assert::is_transmutable::<Src, Dst, FALSE, FALSE, FALSE, FALSE>();
} }

View file

@ -1,8 +1,8 @@
error[E0107]: trait takes at most 3 generic arguments but 6 generic arguments were supplied error[E0107]: trait takes at most 2 generic arguments but 5 generic arguments were supplied
--> $DIR/issue-101739-2.rs:18:14 --> $DIR/issue-101739-2.rs:17:14
| |
LL | Dst: BikeshedIntrinsicFrom< LL | Dst: BikeshedIntrinsicFrom<
| ^^^^^^^^^^^^^^^^^^^^^ expected at most 3 generic arguments | ^^^^^^^^^^^^^^^^^^^^^ expected at most 2 generic arguments
... ...
LL | / ASSUME_LIFETIMES, LL | / ASSUME_LIFETIMES,
LL | | ASSUME_VALIDITY, LL | | ASSUME_VALIDITY,
@ -10,13 +10,13 @@ LL | | ASSUME_VISIBILITY,
| |_____________________________- help: remove these generic arguments | |_____________________________- help: remove these generic arguments
error: the constant `ASSUME_ALIGNMENT` is not of type `Assume` error: the constant `ASSUME_ALIGNMENT` is not of type `Assume`
--> $DIR/issue-101739-2.rs:18:14 --> $DIR/issue-101739-2.rs:17:14
| |
LL | Dst: BikeshedIntrinsicFrom< LL | Dst: BikeshedIntrinsicFrom<
| ______________^ | ______________^
LL | | LL | |
LL | | Src, LL | | Src,
LL | | Context, LL | | ASSUME_ALIGNMENT,
... | ... |
LL | | ASSUME_VISIBILITY, LL | | ASSUME_VISIBILITY,
LL | | >, LL | | >,
@ -26,7 +26,7 @@ note: required by a bound in `BikeshedIntrinsicFrom`
--> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL --> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-101739-2.rs:22:13 --> $DIR/issue-101739-2.rs:20:13
| |
LL | ASSUME_ALIGNMENT, LL | ASSUME_ALIGNMENT,
| ^^^^^^^^^^^^^^^^ expected `Assume`, found `bool` | ^^^^^^^^^^^^^^^^ expected `Assume`, found `bool`

View file

@ -2,11 +2,10 @@
#![crate_type = "lib"] #![crate_type = "lib"]
#![feature(transmutability)] #![feature(transmutability)]
use std::mem::BikeshedIntrinsicFrom; use std::mem::BikeshedIntrinsicFrom;
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context>, Dst: BikeshedIntrinsicFrom<Src>,
{ {
} }

View file

@ -8,7 +8,6 @@ mod assert {
pub fn is_transmutable< pub fn is_transmutable<
Src, Src,
Dst, Dst,
Context,
const ASSUME_ALIGNMENT: bool, const ASSUME_ALIGNMENT: bool,
const ASSUME_LIFETIMES: bool, const ASSUME_LIFETIMES: bool,
const ASSUME_SAFETY: bool, const ASSUME_SAFETY: bool,
@ -17,7 +16,6 @@ mod assert {
where where
Dst: BikeshedIntrinsicFrom< Dst: BikeshedIntrinsicFrom<
Src, Src,
Context,
{ from_options(ASSUME_ALIGNMENT, ASSUME_LIFETIMES, ASSUME_SAFETY, ASSUME_VALIDITY) } { from_options(ASSUME_ALIGNMENT, ASSUME_LIFETIMES, ASSUME_SAFETY, ASSUME_VALIDITY) }
>, >,
{} {}
@ -32,9 +30,8 @@ mod assert {
} }
fn main() { fn main() {
struct Context;
#[repr(C)] struct Src; #[repr(C)] struct Src;
#[repr(C)] struct Dst; #[repr(C)] struct Dst;
assert::is_transmutable::<Src, Dst, Context, false, false, { true }, false>(); assert::is_transmutable::<Src, Dst, false, false, { true }, false>();
} }

View file

@ -1,3 +1,15 @@
error: expected parameter name, found `,`
--> $DIR/issue-110892.rs:25:9
|
LL | ,
| ^ expected parameter name
error: expected parameter name, found `,`
--> $DIR/issue-110892.rs:26:9
|
LL | ,
| ^ expected parameter name
error: expected parameter name, found `,` error: expected parameter name, found `,`
--> $DIR/issue-110892.rs:27:9 --> $DIR/issue-110892.rs:27:9
| |
@ -10,20 +22,8 @@ error: expected parameter name, found `,`
LL | , LL | ,
| ^ expected parameter name | ^ expected parameter name
error: expected parameter name, found `,`
--> $DIR/issue-110892.rs:29:9
|
LL | ,
| ^ expected parameter name
error: expected parameter name, found `,`
--> $DIR/issue-110892.rs:30:9
|
LL | ,
| ^ expected parameter name
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-110892.rs:31:10 --> $DIR/issue-110892.rs:29:10
| |
LL | const fn from_options( LL | const fn from_options(
| ------------ implicitly returns `()` as its body has no tail or `return` expression | ------------ implicitly returns `()` as its body has no tail or `return` expression

View file

@ -6,16 +6,14 @@
mod assert { mod assert {
use std::mem::BikeshedIntrinsicFrom; use std::mem::BikeshedIntrinsicFrom;
pub struct Context;
pub fn is_transmutable<Src, Dst, Context>() pub fn is_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context> Dst: BikeshedIntrinsicFrom<Src>
{} {}
} }
fn should_gracefully_handle_unknown_dst() { fn should_gracefully_handle_unknown_dst() {
struct Context;
struct Src; struct Src;
assert::is_transmutable::<Src, Dst, Context>(); //~ cannot find type assert::is_transmutable::<Src, Dst>(); //~ cannot find type
} }

View file

@ -1,7 +1,7 @@
error[E0412]: cannot find type `Dst` in this scope error[E0412]: cannot find type `Dst` in this scope
--> $DIR/unknown_dst.rs:20:36 --> $DIR/unknown_dst.rs:18:36
| |
LL | assert::is_transmutable::<Src, Dst, Context>(); LL | assert::is_transmutable::<Src, Dst>();
| ^^^ not found in this scope | ^^^ not found in this scope
| |
help: you might be missing a type parameter help: you might be missing a type parameter

View file

@ -6,16 +6,14 @@
mod assert { mod assert {
use std::mem::BikeshedIntrinsicFrom; use std::mem::BikeshedIntrinsicFrom;
pub struct Context;
pub fn is_transmutable<Src, Dst, Context>() pub fn is_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context> Dst: BikeshedIntrinsicFrom<Src>
{} {}
} }
fn should_gracefully_handle_unknown_src() { fn should_gracefully_handle_unknown_src() {
struct Context;
#[repr(C)] struct Dst; #[repr(C)] struct Dst;
assert::is_transmutable::<Src, Dst, Context>(); //~ cannot find type assert::is_transmutable::<Src, Dst>(); //~ cannot find type
} }

View file

@ -1,7 +1,7 @@
error[E0412]: cannot find type `Src` in this scope error[E0412]: cannot find type `Src` in this scope
--> $DIR/unknown_src.rs:20:31 --> $DIR/unknown_src.rs:18:31
| |
LL | assert::is_transmutable::<Src, Dst, Context>(); LL | assert::is_transmutable::<Src, Dst>();
| ^^^ not found in this scope | ^^^ not found in this scope
| |
help: you might be missing a type parameter help: you might be missing a type parameter

View file

@ -6,17 +6,15 @@
mod assert { mod assert {
use std::mem::BikeshedIntrinsicFrom; use std::mem::BikeshedIntrinsicFrom;
pub struct Context;
pub fn is_transmutable<Src, Dst, Context>() pub fn is_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context> Dst: BikeshedIntrinsicFrom<Src>
{} {}
} }
fn should_gracefully_handle_unknown_dst_field() { fn should_gracefully_handle_unknown_dst_field() {
struct Context;
#[repr(C)] struct Src; #[repr(C)] struct Src;
#[repr(C)] struct Dst(Missing); //~ cannot find type #[repr(C)] struct Dst(Missing); //~ cannot find type
assert::is_transmutable::<Src, Dst, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Src, Dst>(); //~ ERROR cannot be safely transmuted
} }

View file

@ -1,23 +1,23 @@
error[E0412]: cannot find type `Missing` in this scope error[E0412]: cannot find type `Missing` in this scope
--> $DIR/unknown_src_field.rs:20:27 --> $DIR/unknown_src_field.rs:18:27
| |
LL | #[repr(C)] struct Dst(Missing); LL | #[repr(C)] struct Dst(Missing);
| ^^^^^^^ not found in this scope | ^^^^^^^ not found in this scope
error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `should_gracefully_handle_unknown_dst_field::Context` error[E0277]: `Src` cannot be safely transmuted into `Dst`
--> $DIR/unknown_src_field.rs:21:36 --> $DIR/unknown_src_field.rs:19:36
| |
LL | assert::is_transmutable::<Src, Dst, Context>(); LL | assert::is_transmutable::<Src, Dst>();
| ^^^ `Dst` has an unknown layout | ^^^ `Dst` has an unknown layout
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/unknown_src_field.rs:13:14 --> $DIR/unknown_src_field.rs:12:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context> LL | Dst: BikeshedIntrinsicFrom<Src>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -13,7 +13,6 @@ mod assert {
pub fn is_transmutable< pub fn is_transmutable<
Src, Src,
Dst, Dst,
Context,
const ASSUME_ALIGNMENT: bool, const ASSUME_ALIGNMENT: bool,
const ASSUME_LIFETIMES: bool, const ASSUME_LIFETIMES: bool,
const ASSUME_SAFETY: bool, const ASSUME_SAFETY: bool,
@ -22,7 +21,6 @@ mod assert {
where where
Dst: BikeshedIntrinsicFrom< Dst: BikeshedIntrinsicFrom<
Src, Src,
Context,
{ from_options(ASSUME_ALIGNMENT, ASSUME_LIFETIMES, ASSUME_SAFETY, ASSUME_VALIDITY) } { from_options(ASSUME_ALIGNMENT, ASSUME_LIFETIMES, ASSUME_SAFETY, ASSUME_VALIDITY) }
>, >,
{} {}
@ -43,11 +41,10 @@ mod assert {
} }
fn test() { fn test() {
struct Context;
#[repr(C)] struct Src; #[repr(C)] struct Src;
#[repr(C)] struct Dst; #[repr(C)] struct Dst;
assert::is_transmutable::<Src, Dst, Context, {0u8}, false, false, false>(); //~ ERROR mismatched types assert::is_transmutable::<Src, Dst, {0u8}, false, false, false>(); //~ ERROR mismatched types
assert::is_transmutable::<Src, Dst, Context, false, {0u8}, false, false>(); //~ ERROR mismatched types assert::is_transmutable::<Src, Dst, false, {0u8}, false, false>(); //~ ERROR mismatched types
assert::is_transmutable::<Src, Dst, Context, false, false, {0u8}, false>(); //~ ERROR mismatched types assert::is_transmutable::<Src, Dst, false, false, {0u8}, false>(); //~ ERROR mismatched types
assert::is_transmutable::<Src, Dst, Context, false, false, false, {0u8}>(); //~ ERROR mismatched types assert::is_transmutable::<Src, Dst, false, false, false, {0u8}>(); //~ ERROR mismatched types
} }

View file

@ -1,26 +1,26 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/wrong-type-assume.rs:49:51 --> $DIR/wrong-type-assume.rs:46:42
| |
LL | assert::is_transmutable::<Src, Dst, Context, {0u8}, false, false, false>(); LL | assert::is_transmutable::<Src, Dst, {0u8}, false, false, false>();
| ^^^ expected `bool`, found `u8` | ^^^ expected `bool`, found `u8`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/wrong-type-assume.rs:50:58 --> $DIR/wrong-type-assume.rs:47:49
| |
LL | assert::is_transmutable::<Src, Dst, Context, false, {0u8}, false, false>(); LL | assert::is_transmutable::<Src, Dst, false, {0u8}, false, false>();
| ^^^ expected `bool`, found `u8` | ^^^ expected `bool`, found `u8`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/wrong-type-assume.rs:51:65 --> $DIR/wrong-type-assume.rs:48:56
| |
LL | assert::is_transmutable::<Src, Dst, Context, false, false, {0u8}, false>(); LL | assert::is_transmutable::<Src, Dst, false, false, {0u8}, false>();
| ^^^ expected `bool`, found `u8` | ^^^ expected `bool`, found `u8`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/wrong-type-assume.rs:52:72 --> $DIR/wrong-type-assume.rs:49:63
| |
LL | assert::is_transmutable::<Src, Dst, Context, false, false, false, {0u8}>(); LL | assert::is_transmutable::<Src, Dst, false, false, false, {0u8}>();
| ^^^ expected `bool`, found `u8` | ^^^ expected `bool`, found `u8`
error: aborting due to 4 previous errors error: aborting due to 4 previous errors

View file

@ -4,11 +4,10 @@
#![feature(transmutability)] #![feature(transmutability)]
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_transmutable<Src, Dst>() pub fn is_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }> Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
{} {}
} }

View file

@ -1,17 +1,17 @@
error[E0277]: `u8` cannot be safely transmuted into `bool` in the defining scope of `assert::Context` error[E0277]: `u8` cannot be safely transmuted into `bool`
--> $DIR/bool-mut.rs:16:50 --> $DIR/bool-mut.rs:15:50
| |
LL | assert::is_transmutable::<&'static mut bool, &'static mut u8>() LL | assert::is_transmutable::<&'static mut bool, &'static mut u8>()
| ^^^^^^^^^^^^^^^ At least one value of `u8` isn't a bit-valid value of `bool` | ^^^^^^^^^^^^^^^ At least one value of `u8` isn't a bit-valid value of `bool`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/bool-mut.rs:11:14 --> $DIR/bool-mut.rs:10:14
| |
LL | pub fn is_transmutable<Src, Dst>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }> LL | Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error: aborting due to 1 previous error error: aborting due to 1 previous error

View file

@ -1,17 +1,17 @@
error[E0277]: `u8` cannot be safely transmuted into `bool` in the defining scope of `assert::Context` error[E0277]: `u8` cannot be safely transmuted into `bool`
--> $DIR/bool.rs:21:35 --> $DIR/bool.rs:20:35
| |
LL | assert::is_transmutable::<u8, bool>(); LL | assert::is_transmutable::<u8, bool>();
| ^^^^ At least one value of `u8` isn't a bit-valid value of `bool` | ^^^^ At least one value of `u8` isn't a bit-valid value of `bool`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/bool.rs:11:14 --> $DIR/bool.rs:10:14
| |
LL | pub fn is_transmutable<Src, Dst>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }> LL | Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error: aborting due to 1 previous error error: aborting due to 1 previous error

View file

@ -1,17 +1,17 @@
error[E0277]: `u8` cannot be safely transmuted into `bool` in the defining scope of `assert::Context` error[E0277]: `u8` cannot be safely transmuted into `bool`
--> $DIR/bool.rs:21:35 --> $DIR/bool.rs:20:35
| |
LL | assert::is_transmutable::<u8, bool>(); LL | assert::is_transmutable::<u8, bool>();
| ^^^^ At least one value of `u8` isn't a bit-valid value of `bool` | ^^^^ At least one value of `u8` isn't a bit-valid value of `bool`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/bool.rs:11:14 --> $DIR/bool.rs:10:14
| |
LL | pub fn is_transmutable<Src, Dst>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }> LL | Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error: aborting due to 1 previous error error: aborting due to 1 previous error

View file

@ -4,16 +4,15 @@
#![feature(transmutability)] #![feature(transmutability)]
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_transmutable<Src, Dst>() pub fn is_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }> Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
{} {}
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY.and(Assume::VALIDITY) }> Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY.and(Assume::VALIDITY) }>
{} {}
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -8,11 +8,10 @@
mod assert { mod assert {
use std::mem::BikeshedIntrinsicFrom; use std::mem::BikeshedIntrinsicFrom;
struct Context;
pub fn is_transmutable<Src, Dst>() pub fn is_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context> Dst: BikeshedIntrinsicFrom<Src>
{} {}
} }

View file

@ -1,16 +1,16 @@
error[E0277]: `()` cannot be safely transmuted into `u8` in the defining scope of `should_have_correct_size::Context` error[E0277]: `()` cannot be safely transmuted into `u8`
--> $DIR/unit.rs:31:35 --> $DIR/unit.rs:30:35
| |
LL | assert::is_transmutable::<(), u8, Context>(); LL | assert::is_transmutable::<(), u8>();
| ^^ The size of `()` is smaller than the size of `u8` | ^^ The size of `()` is smaller than the size of `u8`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/unit.rs:15:14 --> $DIR/unit.rs:15:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume::ALIGNMENT LL | | Assume::ALIGNMENT
LL | | .and(Assume::LIFETIMES) LL | | .and(Assume::LIFETIMES)

View file

@ -1,16 +1,16 @@
error[E0277]: `()` cannot be safely transmuted into `u8` in the defining scope of `should_have_correct_size::Context` error[E0277]: `()` cannot be safely transmuted into `u8`
--> $DIR/unit.rs:31:35 --> $DIR/unit.rs:30:35
| |
LL | assert::is_transmutable::<(), u8, Context>(); LL | assert::is_transmutable::<(), u8>();
| ^^ The size of `()` is smaller than the size of `u8` | ^^ The size of `()` is smaller than the size of `u8`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/unit.rs:15:14 --> $DIR/unit.rs:15:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume::ALIGNMENT LL | | Assume::ALIGNMENT
LL | | .and(Assume::LIFETIMES) LL | | .and(Assume::LIFETIMES)

View file

@ -10,9 +10,9 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub fn is_transmutable<Src, Dst, Context>() pub fn is_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume::ALIGNMENT Assume::ALIGNMENT
.and(Assume::LIFETIMES) .and(Assume::LIFETIMES)
.and(Assume::SAFETY) .and(Assume::SAFETY)
@ -25,8 +25,7 @@ mod assert {
struct Zst; struct Zst;
fn should_have_correct_size() { fn should_have_correct_size() {
struct Context; assert::is_transmutable::<(), Zst>();
assert::is_transmutable::<(), Zst, Context>(); assert::is_transmutable::<Zst, ()>();
assert::is_transmutable::<Zst, (), Context>(); assert::is_transmutable::<(), u8>(); //~ ERROR cannot be safely transmuted
assert::is_transmutable::<(), u8, Context>(); //~ ERROR cannot be safely transmuted
} }

View file

@ -3,11 +3,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume { Assume {
alignment: true, alignment: true,
lifetimes: false, lifetimes: false,

View file

@ -1,16 +1,16 @@
error[E0277]: `&A` cannot be safely transmuted into `&mut B` in the defining scope of `assert::Context` error[E0277]: `&A` cannot be safely transmuted into `&mut B`
--> $DIR/recursive-wrapper-types-bit-compatible-mut.rs:24:49 --> $DIR/recursive-wrapper-types-bit-compatible-mut.rs:23:49
| |
LL | assert::is_maybe_transmutable::<&'static A, &'static mut B>(); LL | assert::is_maybe_transmutable::<&'static A, &'static mut B>();
| ^^^^^^^^^^^^^^ `&A` is a shared reference, but `&mut B` is a unique reference | ^^^^^^^^^^^^^^ `&A` is a shared reference, but `&mut B` is a unique reference
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/recursive-wrapper-types-bit-compatible-mut.rs:10:14 --> $DIR/recursive-wrapper-types-bit-compatible-mut.rs:9:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,

View file

@ -3,11 +3,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume { Assume {
alignment: true, alignment: true,
lifetimes: false, lifetimes: false,

View file

@ -3,11 +3,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume { Assume {
alignment: true, alignment: true,
lifetimes: false, lifetimes: false,

View file

@ -1,16 +1,16 @@
error[E0277]: `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context` error[E0277]: `B` cannot be safely transmuted into `A`
--> $DIR/recursive-wrapper-types-bit-incompatible.rs:24:49 --> $DIR/recursive-wrapper-types-bit-incompatible.rs:23:49
| |
LL | assert::is_maybe_transmutable::<&'static B, &'static A>(); LL | assert::is_maybe_transmutable::<&'static B, &'static A>();
| ^^^^^^^^^^ At least one value of `B` isn't a bit-valid value of `A` | ^^^^^^^^^^ At least one value of `B` isn't a bit-valid value of `A`
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/recursive-wrapper-types-bit-incompatible.rs:10:14 --> $DIR/recursive-wrapper-types-bit-incompatible.rs:9:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,

View file

@ -3,11 +3,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume { Assume {
alignment: true, alignment: true,
lifetimes: false, lifetimes: false,

View file

@ -3,11 +3,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume { Assume {
alignment: false, alignment: false,
lifetimes: true, lifetimes: true,

View file

@ -3,11 +3,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume { Assume {
alignment: true, alignment: true,
lifetimes: false, lifetimes: false,

View file

@ -3,11 +3,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume { Assume {
alignment: true, alignment: true,
lifetimes: true, lifetimes: true,

View file

@ -1,16 +1,16 @@
error[E0277]: `Unit` cannot be safely transmuted into `u8` in the defining scope of `assert::Context` error[E0277]: `Unit` cannot be safely transmuted into `u8`
--> $DIR/unit-to-u8.rs:23:52 --> $DIR/unit-to-u8.rs:22:52
| |
LL | assert::is_maybe_transmutable::<&'static Unit, &'static u8>(); LL | assert::is_maybe_transmutable::<&'static Unit, &'static u8>();
| ^^^^^^^^^^^ The size of `Unit` is smaller than the size of `u8` | ^^^^^^^^^^^ The size of `Unit` is smaller than the size of `u8`
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/unit-to-u8.rs:10:14 --> $DIR/unit-to-u8.rs:9:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,

View file

@ -1,7 +1,6 @@
#![feature(transmutability)] #![feature(transmutability)]
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
#[repr(C)] #[repr(C)]
struct W<'a>(&'a ()); struct W<'a>(&'a ());
@ -10,7 +9,6 @@ fn test<'a>()
where where
W<'a>: BikeshedIntrinsicFrom< W<'a>: BikeshedIntrinsicFrom<
(), (),
Context,
{ Assume { alignment: true, lifetimes: true, safety: true, validity: true } }, { Assume { alignment: true, lifetimes: true, safety: true, validity: true } },
>, >,
{ {

View file

@ -1,11 +1,11 @@
error[E0277]: `()` cannot be safely transmuted into `W<'_>` in the defining scope of `Context` error[E0277]: `()` cannot be safely transmuted into `W<'_>`
--> $DIR/region-infer.rs:20:5 --> $DIR/region-infer.rs:18:5
| |
LL | test(); LL | test();
| ^^^^^^ The size of `()` is smaller than the size of `W<'_>` | ^^^^^^ The size of `()` is smaller than the size of `W<'_>`
| |
note: required by a bound in `test` note: required by a bound in `test`
--> $DIR/region-infer.rs:11:12 --> $DIR/region-infer.rs:10:12
| |
LL | fn test<'a>() LL | fn test<'a>()
| ---- required by a bound in this function | ---- required by a bound in this function
@ -13,7 +13,6 @@ LL | where
LL | W<'a>: BikeshedIntrinsicFrom< LL | W<'a>: BikeshedIntrinsicFrom<
| ____________^ | ____________^
LL | | (), LL | | (),
LL | | Context,
LL | | { Assume { alignment: true, lifetimes: true, safety: true, validity: true } }, LL | | { Assume { alignment: true, lifetimes: true, safety: true, validity: true } },
LL | | >, LL | | >,
| |_________^ required by this bound in `test` | |_________^ required by this bound in `test`

View file

@ -0,0 +1,24 @@
//@ check-pass
//! When safety is assumed, a transmutation should be accepted if the
//! destination type might carry a safety invariant.
#![crate_type = "lib"]
#![feature(transmutability)]
#![allow(dead_code)]
mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom};
pub fn is_transmutable<Src, Dst>()
where
Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
{}
}
fn test() {
type Src = ();
#[repr(C)]
struct Dst;
assert::is_transmutable::<Src, Dst>();
}

View file

@ -0,0 +1,26 @@
//@ check-pass
//! When safety is assumed, a transmutation over exclusive references should be
//! accepted if the source type potentially carries safety invariants.
#![crate_type = "lib"]
#![feature(transmutability)]
#![allow(dead_code)]
mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom};
pub fn is_transmutable<Src, Dst>()
where
Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
{}
}
fn test() {
#[repr(C)]
struct Src {
non_zero: u8,
}
type Dst = u8;
assert::is_transmutable::<&mut Src, &mut Dst>();
}

View file

@ -0,0 +1,24 @@
//@ check-pass
//! The presence of safety invariants in the source type does not affect
//! transmutability.
#![crate_type = "lib"]
#![feature(transmutability)]
#![allow(dead_code)]
mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom};
pub fn is_transmutable<Src, Dst>()
where
Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
{}
}
fn test() {
#[repr(C)]
struct Src;
type Dst = ();
assert::is_transmutable::<Src, Dst>();
}

View file

@ -0,0 +1,24 @@
//@ check-pass
//! The presence of safety invariants in the source type does not affect
//! transmutability.
#![crate_type = "lib"]
#![feature(transmutability)]
#![allow(dead_code)]
mod assert {
use std::mem::BikeshedIntrinsicFrom;
pub fn is_transmutable<Src, Dst>()
where
Dst: BikeshedIntrinsicFrom<Src> // safety is NOT assumed
{}
}
fn test() {
#[repr(C)]
struct Src;
type Dst = ();
assert::is_transmutable::<Src, Dst>();
}

View file

@ -0,0 +1,22 @@
//! Unless safety is assumed, a transmutation should be rejected if the
//! destination type may have a safety invariant.
#![crate_type = "lib"]
#![feature(transmutability)]
#![allow(dead_code)]
mod assert {
use std::mem::BikeshedIntrinsicFrom;
pub fn is_transmutable<Src, Dst>()
where
Dst: BikeshedIntrinsicFrom<Src> // safety is NOT assumed
{}
}
fn test() {
type Src = ();
#[repr(C)]
struct Dst;
assert::is_transmutable::<Src, Dst>(); //~ ERROR cannot be safely transmuted
}

View file

@ -0,0 +1,18 @@
error[E0277]: `()` cannot be safely transmuted into `Dst`
--> $DIR/should_reject_if_dst_has_safety_invariant.rs:21:36
|
LL | assert::is_transmutable::<Src, Dst>();
| ^^^ `Dst` may carry safety invariants
|
note: required by a bound in `is_transmutable`
--> $DIR/should_reject_if_dst_has_safety_invariant.rs:13:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function
LL | where
LL | Dst: BikeshedIntrinsicFrom<Src> // safety is NOT assumed
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -0,0 +1,24 @@
//! Unless safety is assumed, a transmutation over exclusive references should
//! be rejected if the source potentially carries safety invariants.
#![crate_type = "lib"]
#![feature(transmutability)]
#![allow(dead_code)]
mod assert {
use std::mem::BikeshedIntrinsicFrom;
pub fn is_transmutable<Src, Dst>()
where
Dst: BikeshedIntrinsicFrom<Src> // safety is NOT assumed
{}
}
fn test() {
#[repr(C)]
struct Src {
non_zero: u8,
}
type Dst = u8;
assert::is_transmutable::<&mut Src, &mut Dst>(); //~ ERROR cannot be safely transmuted
}

View file

@ -0,0 +1,18 @@
error[E0277]: `u8` cannot be safely transmuted into `Src`
--> $DIR/should_reject_if_ref_src_has_safety_invariant.rs:23:41
|
LL | assert::is_transmutable::<&mut Src, &mut Dst>();
| ^^^^^^^^ `Src` may carry safety invariants
|
note: required by a bound in `is_transmutable`
--> $DIR/should_reject_if_ref_src_has_safety_invariant.rs:13:14
|
LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function
LL | where
LL | Dst: BikeshedIntrinsicFrom<Src> // safety is NOT assumed
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -7,11 +7,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume { Assume {
alignment: true, alignment: true,
lifetimes: true, lifetimes: true,

View file

@ -7,11 +7,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume { Assume {
alignment: true, alignment: true,
lifetimes: true, lifetimes: true,

View file

@ -6,11 +6,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume { Assume {
alignment: true, alignment: true,
lifetimes: true, lifetimes: true,

View file

@ -1,16 +1,16 @@
error[E0277]: `should_reject_repr_rust::unit::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context` error[E0277]: `should_reject_repr_rust::unit::repr_rust` cannot be safely transmuted into `()`
--> $DIR/should_require_well_defined_layout.rs:28:52 --> $DIR/should_require_well_defined_layout.rs:27:52
| |
LL | assert::is_maybe_transmutable::<repr_rust, ()>(); LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `should_reject_repr_rust::unit::repr_rust` does not have a well-specified layout | ^^ `should_reject_repr_rust::unit::repr_rust` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14 --> $DIR/should_require_well_defined_layout.rs:12:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -20,19 +20,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::unit::repr_rust` in the defining scope of `assert::Context` error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::unit::repr_rust`
--> $DIR/should_require_well_defined_layout.rs:29:47 --> $DIR/should_require_well_defined_layout.rs:28:47
| |
LL | assert::is_maybe_transmutable::<u128, repr_rust>(); LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `should_reject_repr_rust::unit::repr_rust` does not have a well-specified layout | ^^^^^^^^^ `should_reject_repr_rust::unit::repr_rust` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14 --> $DIR/should_require_well_defined_layout.rs:12:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -42,19 +42,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `should_reject_repr_rust::tuple::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context` error[E0277]: `should_reject_repr_rust::tuple::repr_rust` cannot be safely transmuted into `()`
--> $DIR/should_require_well_defined_layout.rs:34:52 --> $DIR/should_require_well_defined_layout.rs:33:52
| |
LL | assert::is_maybe_transmutable::<repr_rust, ()>(); LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `should_reject_repr_rust::tuple::repr_rust` does not have a well-specified layout | ^^ `should_reject_repr_rust::tuple::repr_rust` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14 --> $DIR/should_require_well_defined_layout.rs:12:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -64,19 +64,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::tuple::repr_rust` in the defining scope of `assert::Context` error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::tuple::repr_rust`
--> $DIR/should_require_well_defined_layout.rs:35:47 --> $DIR/should_require_well_defined_layout.rs:34:47
| |
LL | assert::is_maybe_transmutable::<u128, repr_rust>(); LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `should_reject_repr_rust::tuple::repr_rust` does not have a well-specified layout | ^^^^^^^^^ `should_reject_repr_rust::tuple::repr_rust` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14 --> $DIR/should_require_well_defined_layout.rs:12:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -86,19 +86,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `should_reject_repr_rust::braces::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context` error[E0277]: `should_reject_repr_rust::braces::repr_rust` cannot be safely transmuted into `()`
--> $DIR/should_require_well_defined_layout.rs:40:52 --> $DIR/should_require_well_defined_layout.rs:39:52
| |
LL | assert::is_maybe_transmutable::<repr_rust, ()>(); LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `should_reject_repr_rust::braces::repr_rust` does not have a well-specified layout | ^^ `should_reject_repr_rust::braces::repr_rust` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14 --> $DIR/should_require_well_defined_layout.rs:12:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -108,19 +108,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::braces::repr_rust` in the defining scope of `assert::Context` error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::braces::repr_rust`
--> $DIR/should_require_well_defined_layout.rs:41:47 --> $DIR/should_require_well_defined_layout.rs:40:47
| |
LL | assert::is_maybe_transmutable::<u128, repr_rust>(); LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `should_reject_repr_rust::braces::repr_rust` does not have a well-specified layout | ^^^^^^^^^ `should_reject_repr_rust::braces::repr_rust` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14 --> $DIR/should_require_well_defined_layout.rs:12:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -130,19 +130,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `aligned::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context` error[E0277]: `aligned::repr_rust` cannot be safely transmuted into `()`
--> $DIR/should_require_well_defined_layout.rs:46:52 --> $DIR/should_require_well_defined_layout.rs:45:52
| |
LL | assert::is_maybe_transmutable::<repr_rust, ()>(); LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `aligned::repr_rust` does not have a well-specified layout | ^^ `aligned::repr_rust` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14 --> $DIR/should_require_well_defined_layout.rs:12:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -152,19 +152,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `aligned::repr_rust` in the defining scope of `assert::Context` error[E0277]: `u128` cannot be safely transmuted into `aligned::repr_rust`
--> $DIR/should_require_well_defined_layout.rs:47:47 --> $DIR/should_require_well_defined_layout.rs:46:47
| |
LL | assert::is_maybe_transmutable::<u128, repr_rust>(); LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `aligned::repr_rust` does not have a well-specified layout | ^^^^^^^^^ `aligned::repr_rust` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14 --> $DIR/should_require_well_defined_layout.rs:12:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -174,19 +174,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `packed::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context` error[E0277]: `packed::repr_rust` cannot be safely transmuted into `()`
--> $DIR/should_require_well_defined_layout.rs:52:52 --> $DIR/should_require_well_defined_layout.rs:51:52
| |
LL | assert::is_maybe_transmutable::<repr_rust, ()>(); LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `packed::repr_rust` does not have a well-specified layout | ^^ `packed::repr_rust` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14 --> $DIR/should_require_well_defined_layout.rs:12:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -196,19 +196,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `packed::repr_rust` in the defining scope of `assert::Context` error[E0277]: `u128` cannot be safely transmuted into `packed::repr_rust`
--> $DIR/should_require_well_defined_layout.rs:53:47 --> $DIR/should_require_well_defined_layout.rs:52:47
| |
LL | assert::is_maybe_transmutable::<u128, repr_rust>(); LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `packed::repr_rust` does not have a well-specified layout | ^^^^^^^^^ `packed::repr_rust` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14 --> $DIR/should_require_well_defined_layout.rs:12:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -218,19 +218,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `nested::repr_c` cannot be safely transmuted into `()` in the defining scope of `assert::Context` error[E0277]: `nested::repr_c` cannot be safely transmuted into `()`
--> $DIR/should_require_well_defined_layout.rs:59:49 --> $DIR/should_require_well_defined_layout.rs:58:49
| |
LL | assert::is_maybe_transmutable::<repr_c, ()>(); LL | assert::is_maybe_transmutable::<repr_c, ()>();
| ^^ `nested::repr_c` does not have a well-specified layout | ^^ `nested::repr_c` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14 --> $DIR/should_require_well_defined_layout.rs:12:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -240,19 +240,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `nested::repr_c` in the defining scope of `assert::Context` error[E0277]: `u128` cannot be safely transmuted into `nested::repr_c`
--> $DIR/should_require_well_defined_layout.rs:60:47 --> $DIR/should_require_well_defined_layout.rs:59:47
| |
LL | assert::is_maybe_transmutable::<u128, repr_c>(); LL | assert::is_maybe_transmutable::<u128, repr_c>();
| ^^^^^^ `nested::repr_c` does not have a well-specified layout | ^^^^^^ `nested::repr_c` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14 --> $DIR/should_require_well_defined_layout.rs:12:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,

View file

@ -8,11 +8,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context>, Dst: BikeshedIntrinsicFrom<Src>,
{ {
} }
} }

View file

@ -1,5 +1,5 @@
error[E0072]: recursive type `ExplicitlyPadded` has infinite size error[E0072]: recursive type `ExplicitlyPadded` has infinite size
--> $DIR/transmute_infinitely_recursive_type.rs:22:5 --> $DIR/transmute_infinitely_recursive_type.rs:21:5
| |
LL | struct ExplicitlyPadded(ExplicitlyPadded); LL | struct ExplicitlyPadded(ExplicitlyPadded);
| ^^^^^^^^^^^^^^^^^^^^^^^ ---------------- recursive without indirection | ^^^^^^^^^^^^^^^^^^^^^^^ ---------------- recursive without indirection
@ -12,7 +12,7 @@ LL | struct ExplicitlyPadded(Box<ExplicitlyPadded>);
error[E0391]: cycle detected when computing layout of `should_pad_explicitly_packed_field::ExplicitlyPadded` error[E0391]: cycle detected when computing layout of `should_pad_explicitly_packed_field::ExplicitlyPadded`
| |
= note: ...which immediately requires computing layout of `should_pad_explicitly_packed_field::ExplicitlyPadded` again = note: ...which immediately requires computing layout of `should_pad_explicitly_packed_field::ExplicitlyPadded` again
= note: cycle used when evaluating trait selection obligation `(): core::mem::transmutability::BikeshedIntrinsicFrom<should_pad_explicitly_packed_field::ExplicitlyPadded, assert::Context, core::mem::transmutability::Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` = note: cycle used when evaluating trait selection obligation `(): core::mem::transmutability::BikeshedIntrinsicFrom<should_pad_explicitly_packed_field::ExplicitlyPadded, core::mem::transmutability::Assume { alignment: false, lifetimes: false, safety: false, validity: false }>`
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -7,11 +7,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_transmutable<Src, Dst>() pub fn is_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume::ALIGNMENT Assume::ALIGNMENT
.and(Assume::LIFETIMES) .and(Assume::LIFETIMES)
.and(Assume::SAFETY) .and(Assume::SAFETY)

View file

@ -4,13 +4,11 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom< Dst: BikeshedIntrinsicFrom<
Src, Src,
Context,
{ Assume { alignment: true, lifetimes: true, safety: true, validity: true } }, { Assume { alignment: true, lifetimes: true, safety: true, validity: true } },
>, >,
{ {

View file

@ -1,11 +1,11 @@
error[E0277]: `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context` error[E0277]: `B` cannot be safely transmuted into `A`
--> $DIR/transmute-padding-ice.rs:27:40 --> $DIR/transmute-padding-ice.rs:25:40
| |
LL | assert::is_maybe_transmutable::<B, A>(); LL | assert::is_maybe_transmutable::<B, A>();
| ^ The size of `B` is smaller than the size of `A` | ^ The size of `B` is smaller than the size of `A`
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/transmute-padding-ice.rs:11:14 --> $DIR/transmute-padding-ice.rs:10:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
@ -13,7 +13,6 @@ LL | where
LL | Dst: BikeshedIntrinsicFrom< LL | Dst: BikeshedIntrinsicFrom<
| ______________^ | ______________^
LL | | Src, LL | | Src,
LL | | Context,
LL | | { Assume { alignment: true, lifetimes: true, safety: true, validity: true } }, LL | | { Assume { alignment: true, lifetimes: true, safety: true, validity: true } },
LL | | >, LL | | >,
| |_________^ required by this bound in `is_maybe_transmutable` | |_________^ required by this bound in `is_maybe_transmutable`

View file

@ -8,11 +8,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_transmutable<Src, Dst>() pub fn is_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }> Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
{} {}
} }

View file

@ -7,11 +7,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume { Assume {
alignment: true, alignment: true,
lifetimes: true, lifetimes: true,

View file

@ -7,11 +7,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume { Assume {
alignment: true, alignment: true,
lifetimes: true, lifetimes: true,

View file

@ -6,11 +6,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume { Assume {
alignment: true, alignment: true,
lifetimes: true, lifetimes: true,

View file

@ -1,16 +1,16 @@
error[E0277]: `should_reject_repr_rust::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context` error[E0277]: `should_reject_repr_rust::repr_rust` cannot be safely transmuted into `()`
--> $DIR/should_require_well_defined_layout.rs:30:48 --> $DIR/should_require_well_defined_layout.rs:29:48
| |
LL | assert::is_maybe_transmutable::<repr_rust, ()>(); LL | assert::is_maybe_transmutable::<repr_rust, ()>();
| ^^ `should_reject_repr_rust::repr_rust` does not have a well-specified layout | ^^ `should_reject_repr_rust::repr_rust` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14 --> $DIR/should_require_well_defined_layout.rs:12:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,
@ -20,19 +20,19 @@ LL | | }
LL | | }> LL | | }>
| |__________^ required by this bound in `is_maybe_transmutable` | |__________^ required by this bound in `is_maybe_transmutable`
error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::repr_rust` in the defining scope of `assert::Context` error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::repr_rust`
--> $DIR/should_require_well_defined_layout.rs:31:43 --> $DIR/should_require_well_defined_layout.rs:30:43
| |
LL | assert::is_maybe_transmutable::<u128, repr_rust>(); LL | assert::is_maybe_transmutable::<u128, repr_rust>();
| ^^^^^^^^^ `should_reject_repr_rust::repr_rust` does not have a well-specified layout | ^^^^^^^^^ `should_reject_repr_rust::repr_rust` does not have a well-specified layout
| |
note: required by a bound in `is_maybe_transmutable` note: required by a bound in `is_maybe_transmutable`
--> $DIR/should_require_well_defined_layout.rs:13:14 --> $DIR/should_require_well_defined_layout.rs:12:14
| |
LL | pub fn is_maybe_transmutable<Src, Dst>() LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function | --------------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume { LL | | Assume {
LL | | alignment: true, LL | | alignment: true,

View file

@ -8,9 +8,9 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub fn is_transmutable<Src, Dst, Context>() pub fn is_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Dst: BikeshedIntrinsicFrom<Src, {
Assume::ALIGNMENT Assume::ALIGNMENT
.and(Assume::LIFETIMES) .and(Assume::LIFETIMES)
.and(Assume::SAFETY) .and(Assume::SAFETY)
@ -38,8 +38,7 @@ union Lopsided {
#[repr(C)] struct Dst(V0, Lopsided, V2); #[repr(C)] struct Dst(V0, Lopsided, V2);
fn should_pad_variants() { fn should_pad_variants() {
struct Context;
// If the implementation (incorrectly) fails to pad `Lopsided::smol` with // If the implementation (incorrectly) fails to pad `Lopsided::smol` with
// an uninitialized byte, this transmutation might be (wrongly) accepted: // an uninitialized byte, this transmutation might be (wrongly) accepted:
assert::is_transmutable::<Src, Dst, Context>(); //~ ERROR cannot be safely transmuted assert::is_transmutable::<Src, Dst>(); //~ ERROR cannot be safely transmuted
} }

View file

@ -1,16 +1,16 @@
error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `should_pad_variants::Context` error[E0277]: `Src` cannot be safely transmuted into `Dst`
--> $DIR/should_pad_variants.rs:44:36 --> $DIR/should_pad_variants.rs:43:36
| |
LL | assert::is_transmutable::<Src, Dst, Context>(); LL | assert::is_transmutable::<Src, Dst>();
| ^^^ The size of `Src` is smaller than the size of `Dst` | ^^^ The size of `Src` is smaller than the size of `Dst`
| |
note: required by a bound in `is_transmutable` note: required by a bound in `is_transmutable`
--> $DIR/should_pad_variants.rs:13:14 --> $DIR/should_pad_variants.rs:13:14
| |
LL | pub fn is_transmutable<Src, Dst, Context>() LL | pub fn is_transmutable<Src, Dst>()
| --------------- required by a bound in this function | --------------- required by a bound in this function
LL | where LL | where
LL | Dst: BikeshedIntrinsicFrom<Src, Context, { LL | Dst: BikeshedIntrinsicFrom<Src, {
| ______________^ | ______________^
LL | | Assume::ALIGNMENT LL | | Assume::ALIGNMENT
LL | | .and(Assume::LIFETIMES) LL | | .and(Assume::LIFETIMES)

View file

@ -8,11 +8,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_maybe_transmutable<Src, Dst>() pub fn is_maybe_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY.and(Assume::VALIDITY) }> Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY.and(Assume::VALIDITY) }>
{} {}
} }

View file

@ -6,11 +6,10 @@
mod assert { mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom}; use std::mem::{Assume, BikeshedIntrinsicFrom};
pub struct Context;
pub fn is_transmutable<Src, Dst>() pub fn is_transmutable<Src, Dst>()
where where
Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }> Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
{} {}
} }

Some files were not shown because too many files have changed in this diff Show more