From 64d98f8ee037282c35007b64c2649055c56af1db Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:03 +0200 Subject: Merging upstream version 1.68.2+dfsg1. Signed-off-by: Daniel Baumann --- .../abstraction/abstracted_assume.rs | 72 ++ .../abstraction/const_generic_fn.rs | 41 + .../arrays/issue-103783-array-length.rs | 24 + .../arrays/issue-103783-array-length.stderr | 9 + .../arrays/should_have_correct_length.rs | 44 + .../arrays/should_inherit_alignment.rs | 60 ++ .../arrays/should_require_well_defined_layout.rs | 66 ++ .../should_require_well_defined_layout.stderr | 135 +++ .../primitive_reprs_should_have_correct_length.rs | 156 ++++ ...imitive_reprs_should_have_correct_length.stderr | 463 +++++++++++ .../repr/should_require_well_defined_layout.rs | 124 +++ .../repr/should_require_well_defined_layout.stderr | 141 ++++ .../enums/should_order_correctly.rs | 36 + .../transmutability/enums/should_pad_variants.rs | 45 + .../enums/should_pad_variants.stderr | 25 + .../enums/should_respect_endianness.rs | 37 + .../enums/should_respect_endianness.stderr | 25 + tests/ui/transmutability/issue-101739-1.rs | 21 + tests/ui/transmutability/issue-101739-1.stderr | 16 + tests/ui/transmutability/issue-101739-2.rs | 37 + tests/ui/transmutability/issue-101739-2.stderr | 14 + .../feature-missing.rs | 9 + .../feature-missing.stderr | 21 + .../malformed-program-gracefulness/unknown_dst.rs | 21 + .../unknown_dst.stderr | 14 + .../malformed-program-gracefulness/unknown_src.rs | 21 + .../unknown_src.stderr | 14 + .../unknown_src_field.rs | 22 + .../unknown_src_field.stderr | 9 + .../wrong-type-assume.rs | 53 ++ .../wrong-type-assume.stderr | 27 + tests/ui/transmutability/primitives/bool.rs | 25 + tests/ui/transmutability/primitives/bool.stderr | 19 + tests/ui/transmutability/primitives/numbers.rs | 128 +++ tests/ui/transmutability/primitives/numbers.stderr | 915 +++++++++++++++++++++ tests/ui/transmutability/primitives/unit.rs | 29 + tests/ui/transmutability/primitives/unit.stderr | 25 + tests/ui/transmutability/references.rs | 27 + tests/ui/transmutability/references.stderr | 26 + .../structs/repr/should_handle_align.rs | 43 + .../structs/repr/should_handle_packed.rs | 42 + .../repr/should_require_well_defined_layout.rs | 83 ++ .../repr/should_require_well_defined_layout.stderr | 279 +++++++ .../structs/should_order_fields_correctly.rs | 36 + tests/ui/transmutability/unions/boolish.rs | 31 + .../unions/repr/should_handle_align.rs | 47 ++ .../unions/repr/should_handle_packed.rs | 48 ++ .../repr/should_require_well_defined_layout.rs | 44 + .../repr/should_require_well_defined_layout.stderr | 49 ++ .../transmutability/unions/should_pad_variants.rs | 45 + .../unions/should_pad_variants.stderr | 25 + ...d_permit_intersecting_if_validity_is_assumed.rs | 38 + .../unions/should_reject_contraction.rs | 36 + .../unions/should_reject_contraction.stderr | 19 + .../unions/should_reject_disjoint.rs | 35 + .../unions/should_reject_disjoint.stderr | 35 + .../unions/should_reject_intersecting.rs | 38 + .../unions/should_reject_intersecting.stderr | 35 + .../should_accept_if_dst_has_private_field.rs | 38 + .../should_accept_if_dst_has_private_variant.rs | 39 + ...d_accept_if_dst_has_tricky_unreachable_field.rs | 46 ++ .../should_accept_if_dst_has_unreachable_field.rs | 39 + ...ould_accept_if_dst_has_unreachable_field.stderr | 12 + .../should_accept_if_dst_has_unreachable_ty.rs | 40 + .../should_accept_if_dst_has_unreachable_ty.stderr | 15 + .../should_accept_if_src_has_private_field.rs | 37 + .../should_accept_if_src_has_private_variant.rs | 38 + .../should_accept_if_src_has_unreachable_field.rs | 37 + ...ould_accept_if_src_has_unreachable_field.stderr | 12 + .../should_accept_if_src_has_unreachable_ty.rs | 38 + .../should_accept_if_src_has_unreachable_ty.stderr | 15 + .../should_reject_if_dst_has_private_field.rs | 36 + .../should_reject_if_dst_has_private_field.stderr | 19 + .../should_reject_if_dst_has_private_variant.rs | 37 + ...should_reject_if_dst_has_private_variant.stderr | 19 + ...d_reject_if_dst_has_tricky_unreachable_field.rs | 51 ++ .../should_reject_if_dst_has_unreachable_field.rs | 38 + ...ould_reject_if_dst_has_unreachable_field.stderr | 19 + .../should_reject_if_dst_has_unreachable_ty.rs | 41 + .../should_reject_if_dst_has_unreachable_ty.stderr | 32 + 80 files changed, 4702 insertions(+) create mode 100644 tests/ui/transmutability/abstraction/abstracted_assume.rs create mode 100644 tests/ui/transmutability/abstraction/const_generic_fn.rs create mode 100644 tests/ui/transmutability/arrays/issue-103783-array-length.rs create mode 100644 tests/ui/transmutability/arrays/issue-103783-array-length.stderr create mode 100644 tests/ui/transmutability/arrays/should_have_correct_length.rs create mode 100644 tests/ui/transmutability/arrays/should_inherit_alignment.rs create mode 100644 tests/ui/transmutability/arrays/should_require_well_defined_layout.rs create mode 100644 tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr create mode 100644 tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.rs create mode 100644 tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr create mode 100644 tests/ui/transmutability/enums/repr/should_require_well_defined_layout.rs create mode 100644 tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr create mode 100644 tests/ui/transmutability/enums/should_order_correctly.rs create mode 100644 tests/ui/transmutability/enums/should_pad_variants.rs create mode 100644 tests/ui/transmutability/enums/should_pad_variants.stderr create mode 100644 tests/ui/transmutability/enums/should_respect_endianness.rs create mode 100644 tests/ui/transmutability/enums/should_respect_endianness.stderr create mode 100644 tests/ui/transmutability/issue-101739-1.rs create mode 100644 tests/ui/transmutability/issue-101739-1.stderr create mode 100644 tests/ui/transmutability/issue-101739-2.rs create mode 100644 tests/ui/transmutability/issue-101739-2.stderr create mode 100644 tests/ui/transmutability/malformed-program-gracefulness/feature-missing.rs create mode 100644 tests/ui/transmutability/malformed-program-gracefulness/feature-missing.stderr create mode 100644 tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.rs create mode 100644 tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.stderr create mode 100644 tests/ui/transmutability/malformed-program-gracefulness/unknown_src.rs create mode 100644 tests/ui/transmutability/malformed-program-gracefulness/unknown_src.stderr create mode 100644 tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs create mode 100644 tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr create mode 100644 tests/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.rs create mode 100644 tests/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.stderr create mode 100644 tests/ui/transmutability/primitives/bool.rs create mode 100644 tests/ui/transmutability/primitives/bool.stderr create mode 100644 tests/ui/transmutability/primitives/numbers.rs create mode 100644 tests/ui/transmutability/primitives/numbers.stderr create mode 100644 tests/ui/transmutability/primitives/unit.rs create mode 100644 tests/ui/transmutability/primitives/unit.stderr create mode 100644 tests/ui/transmutability/references.rs create mode 100644 tests/ui/transmutability/references.stderr create mode 100644 tests/ui/transmutability/structs/repr/should_handle_align.rs create mode 100644 tests/ui/transmutability/structs/repr/should_handle_packed.rs create mode 100644 tests/ui/transmutability/structs/repr/should_require_well_defined_layout.rs create mode 100644 tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr create mode 100644 tests/ui/transmutability/structs/should_order_fields_correctly.rs create mode 100644 tests/ui/transmutability/unions/boolish.rs create mode 100644 tests/ui/transmutability/unions/repr/should_handle_align.rs create mode 100644 tests/ui/transmutability/unions/repr/should_handle_packed.rs create mode 100644 tests/ui/transmutability/unions/repr/should_require_well_defined_layout.rs create mode 100644 tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr create mode 100644 tests/ui/transmutability/unions/should_pad_variants.rs create mode 100644 tests/ui/transmutability/unions/should_pad_variants.stderr create mode 100644 tests/ui/transmutability/unions/should_permit_intersecting_if_validity_is_assumed.rs create mode 100644 tests/ui/transmutability/unions/should_reject_contraction.rs create mode 100644 tests/ui/transmutability/unions/should_reject_contraction.stderr create mode 100644 tests/ui/transmutability/unions/should_reject_disjoint.rs create mode 100644 tests/ui/transmutability/unions/should_reject_disjoint.stderr create mode 100644 tests/ui/transmutability/unions/should_reject_intersecting.rs create mode 100644 tests/ui/transmutability/unions/should_reject_intersecting.stderr create mode 100644 tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_field.rs create mode 100644 tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_variant.rs create mode 100644 tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_tricky_unreachable_field.rs create mode 100644 tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs create mode 100644 tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.stderr create mode 100644 tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.rs create mode 100644 tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.stderr create mode 100644 tests/ui/transmutability/visibility/should_accept_if_src_has_private_field.rs create mode 100644 tests/ui/transmutability/visibility/should_accept_if_src_has_private_variant.rs create mode 100644 tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs create mode 100644 tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr create mode 100644 tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.rs create mode 100644 tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.stderr create mode 100644 tests/ui/transmutability/visibility/should_reject_if_dst_has_private_field.rs create mode 100644 tests/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr create mode 100644 tests/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.rs create mode 100644 tests/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr create mode 100644 tests/ui/transmutability/visibility/should_reject_if_dst_has_tricky_unreachable_field.rs create mode 100644 tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.rs create mode 100644 tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr create mode 100644 tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.rs create mode 100644 tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr (limited to 'tests/ui/transmutability') diff --git a/tests/ui/transmutability/abstraction/abstracted_assume.rs b/tests/ui/transmutability/abstraction/abstracted_assume.rs new file mode 100644 index 000000000..0225c4230 --- /dev/null +++ b/tests/ui/transmutability/abstraction/abstracted_assume.rs @@ -0,0 +1,72 @@ +// check-pass +//! The implementation should behave correctly when the `ASSUME` parameters are +//! provided indirectly through an abstraction. + +#![crate_type = "lib"] +#![feature(adt_const_params)] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable< + Src, + Dst, + Context, + const ASSUME: std::mem::Assume, + >() + where + Dst: BikeshedIntrinsicFrom< + Src, + Context, + ASSUME, + >, + {} +} + +fn direct() { + struct Context; + #[repr(C)] struct Src; + #[repr(C)] struct Dst; + + assert::is_transmutable::(); +} + +fn via_const() { + struct Context; + #[repr(C)] struct Src; + #[repr(C)] struct Dst; + + const FALSE: bool = false; + + assert::is_transmutable::(); +} + +fn via_associated_const() { + struct Context; + #[repr(C)] struct Src; + #[repr(C)] struct Dst; + + trait Trait { + const FALSE: bool = true; + } + + struct Ty; + + impl Trait for Ty {} + + assert::is_transmutable::< + Src, + Dst, + Context, + { + std::mem::Assume { + alignment: {Ty::FALSE}, + lifetimes: {Ty::FALSE}, + safety: {Ty::FALSE}, + validity: {Ty::FALSE}, + } + } + >(); +} diff --git a/tests/ui/transmutability/abstraction/const_generic_fn.rs b/tests/ui/transmutability/abstraction/const_generic_fn.rs new file mode 100644 index 000000000..e693a0957 --- /dev/null +++ b/tests/ui/transmutability/abstraction/const_generic_fn.rs @@ -0,0 +1,41 @@ +// check-pass +//! An array must have the correct length. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn array_like() + where + T: BikeshedIntrinsicFrom<[E; N], Context, { Assume::SAFETY }>, + [E; N]: BikeshedIntrinsicFrom + {} +} + +fn len_0() { + type Array = [u8; 0]; + #[repr(C)] struct Struct(); + assert::array_like::(); +} + +fn len_1() { + type Array = [u8; 1]; + #[repr(C)] struct Struct(u8); + assert::array_like::(); +} + +fn len_2() { + type Array = [u8; 2]; + #[repr(C)] struct Struct(u8, u8); + assert::array_like::(); +} + +fn len_3() { + type Array = [u8; 3]; + #[repr(C)] struct Struct(u8, u8, u8); + assert::array_like::(); +} diff --git a/tests/ui/transmutability/arrays/issue-103783-array-length.rs b/tests/ui/transmutability/arrays/issue-103783-array-length.rs new file mode 100644 index 000000000..cb36e539e --- /dev/null +++ b/tests/ui/transmutability/arrays/issue-103783-array-length.rs @@ -0,0 +1,24 @@ +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom< + Src, + Context, + { Assume { alignment: true, lifetimes: true, safety: true, validity: true } }, + >, + { + } +} + +fn test() { + type NaughtyLenArray = [u32; 3.14159]; //~ ERROR mismatched types + type JustUnit = (); + assert::is_maybe_transmutable::(); +} diff --git a/tests/ui/transmutability/arrays/issue-103783-array-length.stderr b/tests/ui/transmutability/arrays/issue-103783-array-length.stderr new file mode 100644 index 000000000..37774c59e --- /dev/null +++ b/tests/ui/transmutability/arrays/issue-103783-array-length.stderr @@ -0,0 +1,9 @@ +error[E0308]: mismatched types + --> $DIR/issue-103783-array-length.rs:21:34 + | +LL | type NaughtyLenArray = [u32; 3.14159]; + | ^^^^^^^ expected `usize`, found floating-point number + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/transmutability/arrays/should_have_correct_length.rs b/tests/ui/transmutability/arrays/should_have_correct_length.rs new file mode 100644 index 000000000..353797d0c --- /dev/null +++ b/tests/ui/transmutability/arrays/should_have_correct_length.rs @@ -0,0 +1,44 @@ +// check-pass +//! An array must have the correct length. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn should_have_len_0() { + type Array = [u8; 0]; + #[repr(C)] struct Struct(); + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); +} + +fn should_have_len_1() { + type Array = [u8; 1]; + #[repr(C)] struct Struct(u8); + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); +} + +fn should_have_len_2() { + type Array = [u8; 2]; + #[repr(C)] struct Struct(u8, u8); + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); +} + +fn should_have_len_3() { + type Array = [u8; 3]; + #[repr(C)] struct Struct(u8, u8, u8); + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); +} diff --git a/tests/ui/transmutability/arrays/should_inherit_alignment.rs b/tests/ui/transmutability/arrays/should_inherit_alignment.rs new file mode 100644 index 000000000..b00e5c7e4 --- /dev/null +++ b/tests/ui/transmutability/arrays/should_inherit_alignment.rs @@ -0,0 +1,60 @@ +// check-pass +//! An array must inherit the alignment of its inner type. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +#[derive(Clone, Copy)] #[repr(u8)] enum Ox00 { V = 0x00 } +#[derive(Clone, Copy)] #[repr(u8)] enum Ox01 { V = 0x01 } +#[derive(Clone, Copy)] #[repr(u8)] enum OxFF { V = 0xFF } + +#[repr(C)] +union Uninit { + a: (), + b: OxFF, +} + +#[repr(C, align(2))] struct align_2(Ox00); + +fn len_0() { + #[repr(C)] struct ImplicitlyPadded([align_2; 0], Ox01); + #[repr(C)] struct ExplicitlyPadded(Ox01, Uninit); + + #[repr(C)] struct Struct(); + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); +} + +fn len_1() { + #[repr(C)] struct ImplicitlyPadded([align_2; 1], Ox01); + #[repr(C)] struct ExplicitlyPadded(Ox00, Uninit, Ox01, Uninit); + + #[repr(C)] struct Struct(); + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); +} + +fn len_2() { + #[repr(C)] struct ImplicitlyPadded([align_2; 2], Ox01); + #[repr(C)] struct ExplicitlyPadded(Ox00, Uninit, Ox00, Uninit, Ox01, Uninit); + + #[repr(C)] struct Struct(); + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); +} diff --git a/tests/ui/transmutability/arrays/should_require_well_defined_layout.rs b/tests/ui/transmutability/arrays/should_require_well_defined_layout.rs new file mode 100644 index 000000000..853bd9cbc --- /dev/null +++ b/tests/ui/transmutability/arrays/should_require_well_defined_layout.rs @@ -0,0 +1,66 @@ +//! An array must have a well-defined layout to participate in a transmutation. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn should_reject_repr_rust() +{ + fn unit() { + type repr_rust = [String; 0]; + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + } + + fn singleton() { + type repr_rust = [String; 1]; + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + } + + fn duplex() { + type repr_rust = [String; 2]; + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + } +} + +fn should_accept_repr_C() +{ + fn unit() { + #[repr(C)] struct repr_c(u8, u16, u8); + type array = [repr_c; 0]; + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); + } + + fn singleton() { + #[repr(C)] struct repr_c(u8, u16, u8); + type array = [repr_c; 1]; + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); + } + + fn duplex() { + #[repr(C)] struct repr_c(u8, u16, u8); + #[repr(C)] struct duplex(repr_c, repr_c); + type array = [repr_c; 2]; + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); + } +} diff --git a/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr b/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr new file mode 100644 index 000000000..96a2fdc54 --- /dev/null +++ b/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr @@ -0,0 +1,135 @@ +error[E0277]: `[String; 0]` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:26:52 + | +LL | assert::is_maybe_transmutable::(); + | ^^ `[String; 0]` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<[String; 0], assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `()` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ 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`. + --> $DIR/should_require_well_defined_layout.rs:27:47 + | +LL | assert::is_maybe_transmutable::(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `[String; 0]` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `[String; 0]` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `[String; 1]` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:32:52 + | +LL | assert::is_maybe_transmutable::(); + | ^^ `[String; 1]` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<[String; 1], assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `()` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ 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`. + --> $DIR/should_require_well_defined_layout.rs:33:47 + | +LL | assert::is_maybe_transmutable::(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `[String; 1]` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `[String; 1]` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `[String; 2]` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:38:52 + | +LL | assert::is_maybe_transmutable::(); + | ^^ `[String; 2]` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<[String; 2], assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `()` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ 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`. + --> $DIR/should_require_well_defined_layout.rs:39:47 + | +LL | assert::is_maybe_transmutable::(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `[String; 2]` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `[String; 2]` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_maybe_transmutable` + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.rs b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.rs new file mode 100644 index 000000000..940f070e7 --- /dev/null +++ b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.rs @@ -0,0 +1,156 @@ +//! An enum with a primitive repr should have exactly the size of that primitive. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +#[repr(C)] +struct Zst; + +#[derive(Clone, Copy)] +#[repr(i8)] enum V0i8 { V } +#[repr(u8)] enum V0u8 { V } +#[repr(i16)] enum V0i16 { V } +#[repr(u16)] enum V0u16 { V } +#[repr(i32)] enum V0i32 { V } +#[repr(u32)] enum V0u32 { V } +#[repr(i64)] enum V0i64 { V } +#[repr(u64)] enum V0u64 { V } +#[repr(isize)] enum V0isize { V } +#[repr(usize)] enum V0usize { V } + +fn n8() { + struct Context; + + type Smaller = Zst; + type Analog = u8; + type Larger = u16; + + fn i_should_have_correct_length() { + type Current = V0i8; + + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::(); + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + } + + fn u_should_have_correct_length() { + type Current = V0u8; + + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::(); + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + } +} + +fn n16() { + struct Context; + + type Smaller = u8; + type Analog = u16; + type Larger = u32; + + fn i_should_have_correct_length() { + type Current = V0i16; + + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::(); + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + } + + fn u_should_have_correct_length() { + type Current = V0u16; + + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::(); + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + } +} + +fn n32() { + struct Context; + + type Smaller = u16; + type Analog = u32; + type Larger = u64; + + fn i_should_have_correct_length() { + type Current = V0i32; + + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::(); + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + } + + fn u_should_have_correct_length() { + type Current = V0u32; + + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::(); + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + } +} + +fn n64() { + struct Context; + + type Smaller = u32; + type Analog = u64; + type Larger = u128; + + fn i_should_have_correct_length() { + type Current = V0i64; + + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::(); + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + } + + fn u_should_have_correct_length() { + type Current = V0u64; + + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::(); + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + } +} + +fn nsize() { + struct Context; + + type Smaller = u8; + type Analog = usize; + type Larger = [usize; 2]; + + fn i_should_have_correct_length() { + type Current = V0isize; + + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::(); + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + } + + fn u_should_have_correct_length() { + type Current = V0usize; + + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::(); + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + } +} diff --git a/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr new file mode 100644 index 000000000..4da5fcea3 --- /dev/null +++ b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr @@ -0,0 +1,463 @@ +error[E0277]: `Zst` cannot be safely transmuted into `V0i8` in the defining scope of `n8::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:48:44 + | +LL | assert::is_transmutable::(); + | ^^^^^^^ `Zst` cannot be safely transmuted into `V0i8` in the defining scope of `n8::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `V0i8` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error[E0277]: `V0i8` cannot be safely transmuted into `u16` in the defining scope of `n8::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:50:44 + | +LL | assert::is_transmutable::(); + | ^^^^^^ `V0i8` cannot be safely transmuted into `u16` in the defining scope of `n8::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u16` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error[E0277]: `Zst` cannot be safely transmuted into `V0u8` in the defining scope of `n8::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:56:44 + | +LL | assert::is_transmutable::(); + | ^^^^^^^ `Zst` cannot be safely transmuted into `V0u8` in the defining scope of `n8::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `V0u8` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error[E0277]: `V0u8` cannot be safely transmuted into `u16` in the defining scope of `n8::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:58:44 + | +LL | assert::is_transmutable::(); + | ^^^^^^ `V0u8` cannot be safely transmuted into `u16` in the defining scope of `n8::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u16` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `V0i16` in the defining scope of `n16::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:72:44 + | +LL | assert::is_transmutable::(); + | ^^^^^^^ `u8` cannot be safely transmuted into `V0i16` in the defining scope of `n16::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `V0i16` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error[E0277]: `V0i16` cannot be safely transmuted into `u32` in the defining scope of `n16::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:74:44 + | +LL | assert::is_transmutable::(); + | ^^^^^^ `V0i16` cannot be safely transmuted into `u32` in the defining scope of `n16::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u32` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `V0u16` in the defining scope of `n16::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:80:44 + | +LL | assert::is_transmutable::(); + | ^^^^^^^ `u8` cannot be safely transmuted into `V0u16` in the defining scope of `n16::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `V0u16` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error[E0277]: `V0u16` cannot be safely transmuted into `u32` in the defining scope of `n16::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:82:44 + | +LL | assert::is_transmutable::(); + | ^^^^^^ `V0u16` cannot be safely transmuted into `u32` in the defining scope of `n16::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u32` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error[E0277]: `u16` cannot be safely transmuted into `V0i32` in the defining scope of `n32::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:96:44 + | +LL | assert::is_transmutable::(); + | ^^^^^^^ `u16` cannot be safely transmuted into `V0i32` in the defining scope of `n32::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `V0i32` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error[E0277]: `V0i32` cannot be safely transmuted into `u64` in the defining scope of `n32::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:98:44 + | +LL | assert::is_transmutable::(); + | ^^^^^^ `V0i32` cannot be safely transmuted into `u64` in the defining scope of `n32::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u64` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error[E0277]: `u16` cannot be safely transmuted into `V0u32` in the defining scope of `n32::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:104:44 + | +LL | assert::is_transmutable::(); + | ^^^^^^^ `u16` cannot be safely transmuted into `V0u32` in the defining scope of `n32::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `V0u32` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error[E0277]: `V0u32` cannot be safely transmuted into `u64` in the defining scope of `n32::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:106:44 + | +LL | assert::is_transmutable::(); + | ^^^^^^ `V0u32` cannot be safely transmuted into `u64` in the defining scope of `n32::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u64` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error[E0277]: `u32` cannot be safely transmuted into `V0i64` in the defining scope of `n64::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:120:44 + | +LL | assert::is_transmutable::(); + | ^^^^^^^ `u32` cannot be safely transmuted into `V0i64` in the defining scope of `n64::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `V0i64` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error[E0277]: `V0i64` cannot be safely transmuted into `u128` in the defining scope of `n64::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:122:44 + | +LL | assert::is_transmutable::(); + | ^^^^^^ `V0i64` cannot be safely transmuted into `u128` in the defining scope of `n64::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error[E0277]: `u32` cannot be safely transmuted into `V0u64` in the defining scope of `n64::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:128:44 + | +LL | assert::is_transmutable::(); + | ^^^^^^^ `u32` cannot be safely transmuted into `V0u64` in the defining scope of `n64::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `V0u64` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error[E0277]: `V0u64` cannot be safely transmuted into `u128` in the defining scope of `n64::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:130:44 + | +LL | assert::is_transmutable::(); + | ^^^^^^ `V0u64` cannot be safely transmuted into `u128` in the defining scope of `n64::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `V0isize` in the defining scope of `nsize::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:144:44 + | +LL | assert::is_transmutable::(); + | ^^^^^^^ `u8` cannot be safely transmuted into `V0isize` in the defining scope of `nsize::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `V0isize` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error[E0277]: `V0isize` cannot be safely transmuted into `[usize; 2]` in the defining scope of `nsize::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:146:44 + | +LL | assert::is_transmutable::(); + | ^^^^^^ `V0isize` cannot be safely transmuted into `[usize; 2]` in the defining scope of `nsize::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `[usize; 2]` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `V0usize` in the defining scope of `nsize::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:152:44 + | +LL | assert::is_transmutable::(); + | ^^^^^^^ `u8` cannot be safely transmuted into `V0usize` in the defining scope of `nsize::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `V0usize` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error[E0277]: `V0usize` cannot be safely transmuted into `[usize; 2]` in the defining scope of `nsize::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:154:44 + | +LL | assert::is_transmutable::(); + | ^^^^^^ `V0usize` cannot be safely transmuted into `[usize; 2]` in the defining scope of `nsize::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `[usize; 2]` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error: aborting due to 20 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.rs b/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.rs new file mode 100644 index 000000000..102111ae2 --- /dev/null +++ b/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.rs @@ -0,0 +1,124 @@ +//! An enum must have a well-defined layout to participate in a transmutation. + +#![crate_type = "lib"] +#![feature(repr128)] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn should_reject_repr_rust() { + fn void() { + enum repr_rust {} + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + } + + fn singleton() { + enum repr_rust { V } + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + } + + fn duplex() { + enum repr_rust { A, B } + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + } +} + +fn should_accept_primitive_reprs() +{ + fn should_accept_repr_i8() { + #[repr(i8)] enum repr_i8 { V } + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); + } + + fn should_accept_repr_u8() { + #[repr(u8)] enum repr_u8 { V } + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); + } + + fn should_accept_repr_i16() { + #[repr(i16)] enum repr_i16 { V } + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); + } + + fn should_accept_repr_u16() { + #[repr(u16)] enum repr_u16 { V } + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); + } + + fn should_accept_repr_i32() { + #[repr(i32)] enum repr_i32 { V } + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); + } + + fn should_accept_repr_u32() { + #[repr(u32)] enum repr_u32 { V } + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); + } + + fn should_accept_repr_i64() { + #[repr(i64)] enum repr_i64 { V } + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); + } + + fn should_accept_repr_u64() { + #[repr(u64)] enum repr_u64 { V } + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); + } + + fn should_accept_repr_i128() { + #[repr(i128)] enum repr_i128 { V } + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); + } + + fn should_accept_repr_u128() { + #[repr(u128)] enum repr_u128 { V } + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); + } + + fn should_accept_repr_isize() { + #[repr(isize)] enum repr_isize { V } + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); + } + + fn should_accept_repr_usize() { + #[repr(usize)] enum repr_usize { V } + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); + } +} + +fn should_accept_repr_C() { + #[repr(C)] enum repr_c { V } + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); +} diff --git a/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr new file mode 100644 index 000000000..510b8c56e --- /dev/null +++ b/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr @@ -0,0 +1,141 @@ +error[E0277]: `void::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:28:52 + | +LL | assert::is_maybe_transmutable::(); + | ^^ `void::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `()` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:14:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ 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`. + --> $DIR/should_require_well_defined_layout.rs:29:47 + | +LL | assert::is_maybe_transmutable::(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `void::repr_rust` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `void::repr_rust` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:14:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ 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`. + --> $DIR/should_require_well_defined_layout.rs:34:52 + | +LL | assert::is_maybe_transmutable::(); + | ^^ `singleton::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `()` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:14:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ 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`. + --> $DIR/should_require_well_defined_layout.rs:35:47 + | +LL | assert::is_maybe_transmutable::(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `singleton::repr_rust` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `singleton::repr_rust` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:14:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ 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`. + --> $DIR/should_require_well_defined_layout.rs:40:52 + | +LL | assert::is_maybe_transmutable::(); + | ^^ `duplex::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `()` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:14:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ 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`. + --> $DIR/should_require_well_defined_layout.rs:41:47 + | +LL | assert::is_maybe_transmutable::(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `duplex::repr_rust` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `duplex::repr_rust` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:14:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_maybe_transmutable` + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/enums/should_order_correctly.rs b/tests/ui/transmutability/enums/should_order_correctly.rs new file mode 100644 index 000000000..1335cc9d2 --- /dev/null +++ b/tests/ui/transmutability/enums/should_order_correctly.rs @@ -0,0 +1,36 @@ +// check-pass +//! The payloads of an enum variant should be ordered after its tag. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +#[repr(u8)] enum V0 { V = 0 } +#[repr(u8)] enum V1 { V = 1 } +#[repr(u8)] enum V2 { V = 2 } + +#[repr(u8)] enum E01 { V0(V1) = 0u8 } +#[repr(u8)] enum E012 { V0(V1, V2) = 0u8 } + +fn should_order_tag_and_fields_correctly() { + // An implementation that (incorrectly) arranges E01 as [0x01, 0x00] will, + // in principle, reject this transmutation. + assert::is_transmutable::(); + // Again, but with one more field. + assert::is_transmutable::(); +} diff --git a/tests/ui/transmutability/enums/should_pad_variants.rs b/tests/ui/transmutability/enums/should_pad_variants.rs new file mode 100644 index 000000000..c077c52a3 --- /dev/null +++ b/tests/ui/transmutability/enums/should_pad_variants.rs @@ -0,0 +1,45 @@ +//! The variants of an enum must be padded with uninit bytes such that they have +//! the same length (in bytes). + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +#[derive(Clone, Copy)] +#[repr(C)] struct Zst; + +#[derive(Clone, Copy)] +#[repr(u8)] enum V0 { V = 0 } + +#[derive(Clone, Copy)] +#[repr(u8)] enum V2 { V = 2 } + +#[repr(C, u8)] +enum Lopsided { + Smol(Zst), + Lorg(V0), +} + +#[repr(C)] struct Src(V0, Zst, V2); +#[repr(C)] struct Dst(Lopsided, V2); + +fn should_pad_variants() { + struct Context; + // If the implementation (incorrectly) fails to pad `Lopsided::Smol` with + // an uninitialized byte, this transmutation might be (wrongly) accepted: + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted +} diff --git a/tests/ui/transmutability/enums/should_pad_variants.stderr b/tests/ui/transmutability/enums/should_pad_variants.stderr new file mode 100644 index 000000000..a823503d5 --- /dev/null +++ b/tests/ui/transmutability/enums/should_pad_variants.stderr @@ -0,0 +1,25 @@ +error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `should_pad_variants::Context`. + --> $DIR/should_pad_variants.rs:44:36 + | +LL | assert::is_transmutable::(); + | ^^^ `Src` cannot be safely transmuted into `Dst` in the defining scope of `should_pad_variants::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `Dst` +note: required by a bound in `is_transmutable` + --> $DIR/should_pad_variants.rs:13:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/enums/should_respect_endianness.rs b/tests/ui/transmutability/enums/should_respect_endianness.rs new file mode 100644 index 000000000..f3567b405 --- /dev/null +++ b/tests/ui/transmutability/enums/should_respect_endianness.rs @@ -0,0 +1,37 @@ +//! The target endianness should be a consideration in computing the layout of +//! an enum with a multi-byte tag. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +#[repr(u16)] enum Src { V = 0xCAFE } + +#[repr(u8)] enum OxCA { V = 0xCA } +#[repr(u8)] enum OxFE { V = 0xFE } + +#[cfg(target_endian = "big")] #[repr(C)] struct Expected(OxCA, OxFE); +#[cfg(target_endian = "big")] #[repr(C)] struct Unexpected(OxFE, OxCA); + +#[cfg(target_endian = "little")] #[repr(C)] struct Expected(OxFE, OxCA); +#[cfg(target_endian = "little")] #[repr(C)] struct Unexpected(OxCA, OxFE); + +fn should_respect_endianness() { + assert::is_transmutable::(); + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted +} diff --git a/tests/ui/transmutability/enums/should_respect_endianness.stderr b/tests/ui/transmutability/enums/should_respect_endianness.stderr new file mode 100644 index 000000000..0845a5edf --- /dev/null +++ b/tests/ui/transmutability/enums/should_respect_endianness.stderr @@ -0,0 +1,25 @@ +error[E0277]: `Src` cannot be safely transmuted into `Unexpected` in the defining scope of `assert::Context`. + --> $DIR/should_respect_endianness.rs:36:36 + | +LL | assert::is_transmutable::(); + | ^^^^^^^^^^ `Src` cannot be safely transmuted into `Unexpected` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `Unexpected` +note: required by a bound in `is_transmutable` + --> $DIR/should_respect_endianness.rs:14:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/issue-101739-1.rs b/tests/ui/transmutability/issue-101739-1.rs new file mode 100644 index 000000000..bcb8b158e --- /dev/null +++ b/tests/ui/transmutability/issue-101739-1.rs @@ -0,0 +1,21 @@ +#![feature(transmutability)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom, //~ ERROR cannot find type `Dst` in this scope + //~^ ERROR mismatched types + { + } +} + +fn via_const() { + struct Context; + struct Src; + + assert::is_transmutable::(); +} + +fn main() {} diff --git a/tests/ui/transmutability/issue-101739-1.stderr b/tests/ui/transmutability/issue-101739-1.stderr new file mode 100644 index 000000000..5fa741f26 --- /dev/null +++ b/tests/ui/transmutability/issue-101739-1.stderr @@ -0,0 +1,16 @@ +error[E0412]: cannot find type `Dst` in this scope + --> $DIR/issue-101739-1.rs:8:9 + | +LL | Dst: BikeshedIntrinsicFrom, + | ^^^ not found in this scope + +error[E0308]: mismatched types + --> $DIR/issue-101739-1.rs:8:50 + | +LL | Dst: BikeshedIntrinsicFrom, + | ^^^^^^^^^^^^^^^^ expected struct `Assume`, found `bool` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0308, E0412. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/transmutability/issue-101739-2.rs b/tests/ui/transmutability/issue-101739-2.rs new file mode 100644 index 000000000..964a7e49e --- /dev/null +++ b/tests/ui/transmutability/issue-101739-2.rs @@ -0,0 +1,37 @@ +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable< + Src, + Dst, + Context, + const ASSUME_ALIGNMENT: bool, + const ASSUME_LIFETIMES: bool, + const ASSUME_VALIDITY: bool, + const ASSUME_VISIBILITY: bool, + >() + where + Dst: BikeshedIntrinsicFrom< //~ ERROR this trait takes at most 3 generic arguments but 6 generic arguments were supplied + Src, + Context, + ASSUME_ALIGNMENT, + ASSUME_LIFETIMES, + ASSUME_VALIDITY, + ASSUME_VISIBILITY, + >, + {} +} + +fn via_const() { + struct Context; + #[repr(C)] struct Src; + #[repr(C)] struct Dst; + + const FALSE: bool = false; + + assert::is_transmutable::(); +} diff --git a/tests/ui/transmutability/issue-101739-2.stderr b/tests/ui/transmutability/issue-101739-2.stderr new file mode 100644 index 000000000..1b3d20259 --- /dev/null +++ b/tests/ui/transmutability/issue-101739-2.stderr @@ -0,0 +1,14 @@ +error[E0107]: this trait takes at most 3 generic arguments but 6 generic arguments were supplied + --> $DIR/issue-101739-2.rs:18:14 + | +LL | Dst: BikeshedIntrinsicFrom< + | ^^^^^^^^^^^^^^^^^^^^^ expected at most 3 generic arguments +... +LL | / ASSUME_LIFETIMES, +LL | | ASSUME_VALIDITY, +LL | | ASSUME_VISIBILITY, + | |_____________________________- help: remove these generic arguments + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/transmutability/malformed-program-gracefulness/feature-missing.rs b/tests/ui/transmutability/malformed-program-gracefulness/feature-missing.rs new file mode 100644 index 000000000..30c381745 --- /dev/null +++ b/tests/ui/transmutability/malformed-program-gracefulness/feature-missing.rs @@ -0,0 +1,9 @@ +// The trait must not be available if its feature flag is absent. + +#![crate_type = "lib"] + +use std::mem::BikeshedIntrinsicFrom; +//~^ ERROR use of unstable library feature 'transmutability' [E0658] + +use std::mem::Assume; +//~^ ERROR use of unstable library feature 'transmutability' [E0658] diff --git a/tests/ui/transmutability/malformed-program-gracefulness/feature-missing.stderr b/tests/ui/transmutability/malformed-program-gracefulness/feature-missing.stderr new file mode 100644 index 000000000..ba8093f86 --- /dev/null +++ b/tests/ui/transmutability/malformed-program-gracefulness/feature-missing.stderr @@ -0,0 +1,21 @@ +error[E0658]: use of unstable library feature 'transmutability' + --> $DIR/feature-missing.rs:5:5 + | +LL | use std::mem::BikeshedIntrinsicFrom; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #99571 for more information + = help: add `#![feature(transmutability)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'transmutability' + --> $DIR/feature-missing.rs:8:5 + | +LL | use std::mem::Assume; + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #99571 for more information + = help: add `#![feature(transmutability)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.rs b/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.rs new file mode 100644 index 000000000..b3a1e13b8 --- /dev/null +++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.rs @@ -0,0 +1,21 @@ +// An unknown destination type should be gracefully handled. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn should_gracefully_handle_unknown_dst() { + struct Context; + struct Src; + assert::is_transmutable::(); //~ cannot find type +} diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.stderr b/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.stderr new file mode 100644 index 000000000..b4591778f --- /dev/null +++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.stderr @@ -0,0 +1,14 @@ +error[E0412]: cannot find type `Dst` in this scope + --> $DIR/unknown_dst.rs:20:36 + | +LL | assert::is_transmutable::(); + | ^^^ not found in this scope + | +help: you might be missing a type parameter + | +LL | fn should_gracefully_handle_unknown_dst() { + | +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.rs b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.rs new file mode 100644 index 000000000..092b205b7 --- /dev/null +++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.rs @@ -0,0 +1,21 @@ +// An unknown source type should be gracefully handled. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn should_gracefully_handle_unknown_src() { + struct Context; + #[repr(C)] struct Dst; + assert::is_transmutable::(); //~ cannot find type +} diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.stderr b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.stderr new file mode 100644 index 000000000..a55d71d80 --- /dev/null +++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.stderr @@ -0,0 +1,14 @@ +error[E0412]: cannot find type `Src` in this scope + --> $DIR/unknown_src.rs:20:31 + | +LL | assert::is_transmutable::(); + | ^^^ not found in this scope + | +help: you might be missing a type parameter + | +LL | fn should_gracefully_handle_unknown_src() { + | +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs new file mode 100644 index 000000000..ebe34e134 --- /dev/null +++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs @@ -0,0 +1,22 @@ +// An unknown destination type should be gracefully handled. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn should_gracefully_handle_unknown_dst_field() { + struct Context; + #[repr(C)] struct Src; + #[repr(C)] struct Dst(Missing); //~ cannot find type + assert::is_transmutable::(); +} diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr new file mode 100644 index 000000000..475e6f429 --- /dev/null +++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `Missing` in this scope + --> $DIR/unknown_src_field.rs:20:27 + | +LL | #[repr(C)] struct Dst(Missing); + | ^^^^^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.rs b/tests/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.rs new file mode 100644 index 000000000..52aa4bb31 --- /dev/null +++ b/tests/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.rs @@ -0,0 +1,53 @@ +//! The implementation must behave well if const values of wrong types are +//! provided. + +#![crate_type = "lib"] +#![feature(adt_const_params)] +#![feature(generic_const_exprs)] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + + pub fn is_transmutable< + Src, + Dst, + Context, + const ASSUME_ALIGNMENT: bool, + const ASSUME_LIFETIMES: bool, + const ASSUME_SAFETY: bool, + const ASSUME_VALIDITY: bool, + >() + where + Dst: BikeshedIntrinsicFrom< + Src, + Context, + { from_options(ASSUME_ALIGNMENT, ASSUME_LIFETIMES, ASSUME_SAFETY, ASSUME_VALIDITY) } + >, + {} + + const fn from_options( + alignment: bool, + lifetimes: bool, + safety: bool, + validity: bool, + ) -> Assume { + Assume { + alignment, + lifetimes, + safety, + validity, + } + } +} + +fn test() { + struct Context; + #[repr(C)] struct Src; + #[repr(C)] struct Dst; + assert::is_transmutable::(); //~ ERROR mismatched types + assert::is_transmutable::(); //~ ERROR mismatched types + assert::is_transmutable::(); //~ ERROR mismatched types + assert::is_transmutable::(); //~ ERROR mismatched types +} diff --git a/tests/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.stderr b/tests/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.stderr new file mode 100644 index 000000000..c6d93876c --- /dev/null +++ b/tests/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.stderr @@ -0,0 +1,27 @@ +error[E0308]: mismatched types + --> $DIR/wrong-type-assume.rs:49:51 + | +LL | assert::is_transmutable::(); + | ^^^ expected `bool`, found `u8` + +error[E0308]: mismatched types + --> $DIR/wrong-type-assume.rs:50:58 + | +LL | assert::is_transmutable::(); + | ^^^ expected `bool`, found `u8` + +error[E0308]: mismatched types + --> $DIR/wrong-type-assume.rs:51:65 + | +LL | assert::is_transmutable::(); + | ^^^ expected `bool`, found `u8` + +error[E0308]: mismatched types + --> $DIR/wrong-type-assume.rs:52:72 + | +LL | assert::is_transmutable::(); + | ^^^ expected `bool`, found `u8` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/transmutability/primitives/bool.rs b/tests/ui/transmutability/primitives/bool.rs new file mode 100644 index 000000000..eebb74fff --- /dev/null +++ b/tests/ui/transmutability/primitives/bool.rs @@ -0,0 +1,25 @@ +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] +#![allow(incomplete_features)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn contrast_with_u8() { + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::(); + assert::is_transmutable::(); +} diff --git a/tests/ui/transmutability/primitives/bool.stderr b/tests/ui/transmutability/primitives/bool.stderr new file mode 100644 index 000000000..214b5e150 --- /dev/null +++ b/tests/ui/transmutability/primitives/bool.stderr @@ -0,0 +1,19 @@ +error[E0277]: `u8` cannot be safely transmuted into `bool` in the defining scope of `assert::Context`. + --> $DIR/bool.rs:22:35 + | +LL | assert::is_transmutable::(); + | ^^^^ `u8` cannot be safely transmuted into `bool` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `bool` +note: required by a bound in `is_transmutable` + --> $DIR/bool.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/primitives/numbers.rs b/tests/ui/transmutability/primitives/numbers.rs new file mode 100644 index 000000000..0df43d204 --- /dev/null +++ b/tests/ui/transmutability/primitives/numbers.rs @@ -0,0 +1,128 @@ +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] +#![allow(incomplete_features)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + struct Context; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn should_accept_identity() { + assert::is_transmutable::< i8, i8>(); + assert::is_transmutable::< u8, u8>(); + assert::is_transmutable::< i16, i16>(); + assert::is_transmutable::< u16, u16>(); + assert::is_transmutable::< i32, i32>(); + assert::is_transmutable::< f32, f32>(); + assert::is_transmutable::< u32, u32>(); + assert::is_transmutable::< i64, i64>(); + assert::is_transmutable::< f64, f64>(); + assert::is_transmutable::< u64, u64>(); + assert::is_transmutable::< i128, i128>(); + assert::is_transmutable::< u128, u128>(); + assert::is_transmutable::(); + assert::is_transmutable::(); +} + +fn should_be_bitransmutable() { + assert::is_transmutable::< i8, u8>(); + assert::is_transmutable::< u8, i8>(); + + assert::is_transmutable::< i16, u16>(); + assert::is_transmutable::< u16, i16>(); + + assert::is_transmutable::< i32, f32>(); + assert::is_transmutable::< i32, u32>(); + assert::is_transmutable::< f32, i32>(); + assert::is_transmutable::< f32, u32>(); + assert::is_transmutable::< u32, i32>(); + assert::is_transmutable::< u32, f32>(); + + assert::is_transmutable::< u64, i64>(); + assert::is_transmutable::< u64, f64>(); + assert::is_transmutable::< i64, u64>(); + assert::is_transmutable::< i64, f64>(); + assert::is_transmutable::< f64, u64>(); + assert::is_transmutable::< f64, i64>(); + + assert::is_transmutable::< u128, i128>(); + assert::is_transmutable::< i128, u128>(); + + assert::is_transmutable::(); + assert::is_transmutable::(); +} + +fn should_reject_extension() { + assert::is_transmutable::< i8, i16>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i8, u16>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i8, i32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i8, f32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i8, u32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i8, u64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i8, i64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i8, f64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i8, u128>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i8, i128>(); //~ ERROR cannot be safely transmuted + + assert::is_transmutable::< u8, i16>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u8, u16>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u8, i32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u8, f32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u8, u32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u8, u64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u8, i64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u8, f64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u8, u128>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u8, i128>(); //~ ERROR cannot be safely transmuted + + assert::is_transmutable::< i16, i32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i16, f32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i16, u32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i16, u64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i16, i64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i16, f64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i16, u128>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i16, i128>(); //~ ERROR cannot be safely transmuted + + assert::is_transmutable::< u16, i32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u16, f32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u16, u32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u16, u64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u16, i64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u16, f64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u16, u128>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u16, i128>(); //~ ERROR cannot be safely transmuted + + assert::is_transmutable::< i32, u64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i32, i64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i32, f64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i32, u128>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i32, i128>(); //~ ERROR cannot be safely transmuted + + assert::is_transmutable::< f32, u64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< f32, i64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< f32, f64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< f32, u128>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< f32, i128>(); //~ ERROR cannot be safely transmuted + + assert::is_transmutable::< u32, u64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u32, i64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u32, f64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u32, u128>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u32, i128>(); //~ ERROR cannot be safely transmuted + + assert::is_transmutable::< u64, u128>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u64, i128>(); //~ ERROR cannot be safely transmuted + + assert::is_transmutable::< i64, u128>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i64, i128>(); //~ ERROR cannot be safely transmuted + + assert::is_transmutable::< f64, u128>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< f64, i128>(); //~ ERROR cannot be safely transmuted +} diff --git a/tests/ui/transmutability/primitives/numbers.stderr b/tests/ui/transmutability/primitives/numbers.stderr new file mode 100644 index 000000000..7cb7ca8e6 --- /dev/null +++ b/tests/ui/transmutability/primitives/numbers.stderr @@ -0,0 +1,915 @@ +error[E0277]: `i8` cannot be safely transmuted into `i16` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:62:40 + | +LL | assert::is_transmutable::< i8, i16>(); + | ^^^ `i8` cannot be safely transmuted into `i16` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i16` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i8` cannot be safely transmuted into `u16` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:63:40 + | +LL | assert::is_transmutable::< i8, u16>(); + | ^^^ `i8` cannot be safely transmuted into `u16` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u16` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i8` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:64:40 + | +LL | assert::is_transmutable::< i8, i32>(); + | ^^^ `i8` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i8` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:65:40 + | +LL | assert::is_transmutable::< i8, f32>(); + | ^^^ `i8` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `f32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i8` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:66:40 + | +LL | assert::is_transmutable::< i8, u32>(); + | ^^^ `i8` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i8` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:67:40 + | +LL | assert::is_transmutable::< i8, u64>(); + | ^^^ `i8` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i8` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:68:40 + | +LL | assert::is_transmutable::< i8, i64>(); + | ^^^ `i8` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i8` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:69:40 + | +LL | assert::is_transmutable::< i8, f64>(); + | ^^^ `i8` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `f64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i8` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:70:39 + | +LL | assert::is_transmutable::< i8, u128>(); + | ^^^^ `i8` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i8` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:71:39 + | +LL | assert::is_transmutable::< i8, i128>(); + | ^^^^ `i8` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `i16` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:73:40 + | +LL | assert::is_transmutable::< u8, i16>(); + | ^^^ `u8` cannot be safely transmuted into `i16` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i16` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `u16` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:74:40 + | +LL | assert::is_transmutable::< u8, u16>(); + | ^^^ `u8` cannot be safely transmuted into `u16` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u16` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:75:40 + | +LL | assert::is_transmutable::< u8, i32>(); + | ^^^ `u8` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:76:40 + | +LL | assert::is_transmutable::< u8, f32>(); + | ^^^ `u8` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `f32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:77:40 + | +LL | assert::is_transmutable::< u8, u32>(); + | ^^^ `u8` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:78:40 + | +LL | assert::is_transmutable::< u8, u64>(); + | ^^^ `u8` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:79:40 + | +LL | assert::is_transmutable::< u8, i64>(); + | ^^^ `u8` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:80:40 + | +LL | assert::is_transmutable::< u8, f64>(); + | ^^^ `u8` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `f64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:81:39 + | +LL | assert::is_transmutable::< u8, u128>(); + | ^^^^ `u8` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:82:39 + | +LL | assert::is_transmutable::< u8, i128>(); + | ^^^^ `u8` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i16` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:84:40 + | +LL | assert::is_transmutable::< i16, i32>(); + | ^^^ `i16` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i16` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:85:40 + | +LL | assert::is_transmutable::< i16, f32>(); + | ^^^ `i16` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `f32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i16` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:86:40 + | +LL | assert::is_transmutable::< i16, u32>(); + | ^^^ `i16` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i16` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:87:40 + | +LL | assert::is_transmutable::< i16, u64>(); + | ^^^ `i16` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i16` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:88:40 + | +LL | assert::is_transmutable::< i16, i64>(); + | ^^^ `i16` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i16` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:89:40 + | +LL | assert::is_transmutable::< i16, f64>(); + | ^^^ `i16` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `f64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i16` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:90:39 + | +LL | assert::is_transmutable::< i16, u128>(); + | ^^^^ `i16` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i16` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:91:39 + | +LL | assert::is_transmutable::< i16, i128>(); + | ^^^^ `i16` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u16` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:93:40 + | +LL | assert::is_transmutable::< u16, i32>(); + | ^^^ `u16` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u16` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:94:40 + | +LL | assert::is_transmutable::< u16, f32>(); + | ^^^ `u16` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `f32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u16` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:95:40 + | +LL | assert::is_transmutable::< u16, u32>(); + | ^^^ `u16` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u16` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:96:40 + | +LL | assert::is_transmutable::< u16, u64>(); + | ^^^ `u16` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u16` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:97:40 + | +LL | assert::is_transmutable::< u16, i64>(); + | ^^^ `u16` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u16` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:98:40 + | +LL | assert::is_transmutable::< u16, f64>(); + | ^^^ `u16` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `f64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u16` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:99:39 + | +LL | assert::is_transmutable::< u16, u128>(); + | ^^^^ `u16` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u16` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:100:39 + | +LL | assert::is_transmutable::< u16, i128>(); + | ^^^^ `u16` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i32` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:102:40 + | +LL | assert::is_transmutable::< i32, u64>(); + | ^^^ `i32` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i32` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:103:40 + | +LL | assert::is_transmutable::< i32, i64>(); + | ^^^ `i32` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i32` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:104:40 + | +LL | assert::is_transmutable::< i32, f64>(); + | ^^^ `i32` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `f64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i32` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:105:39 + | +LL | assert::is_transmutable::< i32, u128>(); + | ^^^^ `i32` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i32` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:106:39 + | +LL | assert::is_transmutable::< i32, i128>(); + | ^^^^ `i32` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `f32` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:108:40 + | +LL | assert::is_transmutable::< f32, u64>(); + | ^^^ `f32` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `f32` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:109:40 + | +LL | assert::is_transmutable::< f32, i64>(); + | ^^^ `f32` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `f32` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:110:40 + | +LL | assert::is_transmutable::< f32, f64>(); + | ^^^ `f32` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `f64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `f32` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:111:39 + | +LL | assert::is_transmutable::< f32, u128>(); + | ^^^^ `f32` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `f32` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:112:39 + | +LL | assert::is_transmutable::< f32, i128>(); + | ^^^^ `f32` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u32` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:114:40 + | +LL | assert::is_transmutable::< u32, u64>(); + | ^^^ `u32` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u32` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:115:40 + | +LL | assert::is_transmutable::< u32, i64>(); + | ^^^ `u32` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u32` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:116:40 + | +LL | assert::is_transmutable::< u32, f64>(); + | ^^^ `u32` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `f64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u32` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:117:39 + | +LL | assert::is_transmutable::< u32, u128>(); + | ^^^^ `u32` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u32` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:118:39 + | +LL | assert::is_transmutable::< u32, i128>(); + | ^^^^ `u32` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u64` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:120:39 + | +LL | assert::is_transmutable::< u64, u128>(); + | ^^^^ `u64` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u64` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:121:39 + | +LL | assert::is_transmutable::< u64, i128>(); + | ^^^^ `u64` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i64` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:123:39 + | +LL | assert::is_transmutable::< i64, u128>(); + | ^^^^ `i64` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i64` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:124:39 + | +LL | assert::is_transmutable::< i64, i128>(); + | ^^^^ `i64` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `f64` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:126:39 + | +LL | assert::is_transmutable::< f64, u128>(); + | ^^^^ `f64` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `f64` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:127:39 + | +LL | assert::is_transmutable::< f64, i128>(); + | ^^^^ `f64` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `i128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to 57 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/primitives/unit.rs b/tests/ui/transmutability/primitives/unit.rs new file mode 100644 index 000000000..1975a61de --- /dev/null +++ b/tests/ui/transmutability/primitives/unit.rs @@ -0,0 +1,29 @@ +//! The unit type, `()`, should be one byte. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +#[repr(C)] +struct Zst; + +fn should_have_correct_size() { + struct Context; + assert::is_transmutable::<(), Zst, Context>(); + assert::is_transmutable::(); + assert::is_transmutable::<(), u8, Context>(); //~ ERROR cannot be safely transmuted +} diff --git a/tests/ui/transmutability/primitives/unit.stderr b/tests/ui/transmutability/primitives/unit.stderr new file mode 100644 index 000000000..8cabe44a0 --- /dev/null +++ b/tests/ui/transmutability/primitives/unit.stderr @@ -0,0 +1,25 @@ +error[E0277]: `()` cannot be safely transmuted into `u8` in the defining scope of `should_have_correct_size::Context`. + --> $DIR/unit.rs:28:35 + | +LL | assert::is_transmutable::<(), u8, Context>(); + | ^^ `()` cannot be safely transmuted into `u8` in the defining scope of `should_have_correct_size::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<(), should_have_correct_size::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `u8` +note: required by a bound in `is_transmutable` + --> $DIR/unit.rs:12:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/references.rs b/tests/ui/transmutability/references.rs new file mode 100644 index 000000000..af3ff0ec1 --- /dev/null +++ b/tests/ui/transmutability/references.rs @@ -0,0 +1,27 @@ +//! Transmutations involving references are not yet supported. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn not_yet_implemented() { + #[repr(C)] struct Unit; + assert::is_maybe_transmutable::<&'static Unit, &'static Unit>(); //~ ERROR cannot be safely transmuted +} diff --git a/tests/ui/transmutability/references.stderr b/tests/ui/transmutability/references.stderr new file mode 100644 index 000000000..e9c7b144a --- /dev/null +++ b/tests/ui/transmutability/references.stderr @@ -0,0 +1,26 @@ +error[E0277]: `&'static Unit` cannot be safely transmuted into `&'static Unit` in the defining scope of `assert::Context`. + --> $DIR/references.rs:26:52 + | +LL | assert::is_maybe_transmutable::<&'static Unit, &'static Unit>(); + | ^^^^^^^^^^^^^ `&'static Unit` cannot be safely transmuted into `&'static Unit` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<&'static Unit, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `&'static Unit` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/references.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_maybe_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/structs/repr/should_handle_align.rs b/tests/ui/transmutability/structs/repr/should_handle_align.rs new file mode 100644 index 000000000..ea9bf2a23 --- /dev/null +++ b/tests/ui/transmutability/structs/repr/should_handle_align.rs @@ -0,0 +1,43 @@ +// check-pass +//! The presence of an `align(X)` annotation must be accounted for. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn should_pad_explicitly_aligned_field() { + #[derive(Clone, Copy)] #[repr(u8)] enum V0u8 { V = 0 } + + #[repr(C)] + pub union Uninit { + a: (), + b: V0u8, + } + + #[repr(C, align(2))] struct align_2(V0u8); + + #[repr(C)] struct ImplicitlyPadded(align_2, V0u8); + #[repr(C)] struct ExplicitlyPadded(V0u8, Uninit, V0u8); + + // An implementation that (incorrectly) does not place a padding byte after + // `align_2` will, incorrectly, reject the following transmutations. + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); +} diff --git a/tests/ui/transmutability/structs/repr/should_handle_packed.rs b/tests/ui/transmutability/structs/repr/should_handle_packed.rs new file mode 100644 index 000000000..17dc995fc --- /dev/null +++ b/tests/ui/transmutability/structs/repr/should_handle_packed.rs @@ -0,0 +1,42 @@ +// check-pass +//! The presence of an `align(X)` annotation must be accounted for. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn should_pad_explicitly_packed_field() { + #[derive(Clone, Copy)] #[repr(u8)] enum V0u8 { V = 0 } + #[derive(Clone, Copy)] #[repr(u32)] enum V0u32 { V = 0 } + + #[repr(C)] + pub union Uninit { + a: (), + b: V0u8, + } + + #[repr(C, packed(2))] struct ImplicitlyPadded(V0u8, V0u32); + #[repr(C)] struct ExplicitlyPadded(V0u8, Uninit, V0u8, V0u8, V0u8, V0u8); + + // An implementation that (incorrectly) does not place a padding byte after + // `align_2` will, incorrectly, reject the following transmutations. + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); +} diff --git a/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.rs b/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.rs new file mode 100644 index 000000000..9a65b4d70 --- /dev/null +++ b/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.rs @@ -0,0 +1,83 @@ +//! A struct must have a well-defined layout to participate in a transmutation. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn should_reject_repr_rust() +{ + fn unit() { + struct repr_rust; + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + } + + fn tuple() { + struct repr_rust(); + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + } + + fn braces() { + struct repr_rust{} + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + } + + fn aligned() { + #[repr(align(1))] struct repr_rust{} + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + } + + fn packed() { + #[repr(packed)] struct repr_rust{} + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + } + + fn nested() { + struct repr_rust; + #[repr(C)] struct repr_c(repr_rust); + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + } +} + +fn should_accept_repr_C() +{ + fn unit() { + #[repr(C)] struct repr_c; + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); + } + + fn tuple() { + #[repr(C)] struct repr_c(); + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); + } + + fn braces() { + #[repr(C)] struct repr_c{} + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); + } +} diff --git a/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr new file mode 100644 index 000000000..621dbee84 --- /dev/null +++ b/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr @@ -0,0 +1,279 @@ +error[E0277]: `should_reject_repr_rust::unit::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:28:52 + | +LL | assert::is_maybe_transmutable::(); + | ^^ `should_reject_repr_rust::unit::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `()` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ 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`. + --> $DIR/should_require_well_defined_layout.rs:29:47 + | +LL | assert::is_maybe_transmutable::(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `should_reject_repr_rust::unit::repr_rust` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `should_reject_repr_rust::unit::repr_rust` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ 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`. + --> $DIR/should_require_well_defined_layout.rs:34:52 + | +LL | assert::is_maybe_transmutable::(); + | ^^ `should_reject_repr_rust::tuple::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `()` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ 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`. + --> $DIR/should_require_well_defined_layout.rs:35:47 + | +LL | assert::is_maybe_transmutable::(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `should_reject_repr_rust::tuple::repr_rust` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `should_reject_repr_rust::tuple::repr_rust` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ 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`. + --> $DIR/should_require_well_defined_layout.rs:40:52 + | +LL | assert::is_maybe_transmutable::(); + | ^^ `should_reject_repr_rust::braces::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `()` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ 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`. + --> $DIR/should_require_well_defined_layout.rs:41:47 + | +LL | assert::is_maybe_transmutable::(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `should_reject_repr_rust::braces::repr_rust` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `should_reject_repr_rust::braces::repr_rust` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ 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`. + --> $DIR/should_require_well_defined_layout.rs:46:52 + | +LL | assert::is_maybe_transmutable::(); + | ^^ `aligned::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `()` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ 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`. + --> $DIR/should_require_well_defined_layout.rs:47:47 + | +LL | assert::is_maybe_transmutable::(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `aligned::repr_rust` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `aligned::repr_rust` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ 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`. + --> $DIR/should_require_well_defined_layout.rs:52:52 + | +LL | assert::is_maybe_transmutable::(); + | ^^ `packed::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `()` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ 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`. + --> $DIR/should_require_well_defined_layout.rs:53:47 + | +LL | assert::is_maybe_transmutable::(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `packed::repr_rust` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `packed::repr_rust` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ 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`. + --> $DIR/should_require_well_defined_layout.rs:59:49 + | +LL | assert::is_maybe_transmutable::(); + | ^^ `nested::repr_c` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `()` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ 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`. + --> $DIR/should_require_well_defined_layout.rs:60:47 + | +LL | assert::is_maybe_transmutable::(); + | ^^^^^^ `u128` cannot be safely transmuted into `nested::repr_c` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `nested::repr_c` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_maybe_transmutable` + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/structs/should_order_fields_correctly.rs b/tests/ui/transmutability/structs/should_order_fields_correctly.rs new file mode 100644 index 000000000..28724562b --- /dev/null +++ b/tests/ui/transmutability/structs/should_order_fields_correctly.rs @@ -0,0 +1,36 @@ +// check-pass +//! The fields of a struct should be laid out in lexical order. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +#[repr(u8)] enum V0 { V = 0 } +#[repr(u8)] enum V1 { V = 1 } +#[repr(u8)] enum V2 { V = 2 } + +#[repr(C)] struct S01(V0, V1); +#[repr(C)] struct S012(V0, V1, V2); + +fn should_order_tag_and_fields_correctly() { + // An implementation that (incorrectly) arranges S01 as [0x01, 0x00] will, + // in principle, reject this transmutation. + assert::is_transmutable::(); + // Again, but with one more field. + assert::is_transmutable::(); +} diff --git a/tests/ui/transmutability/unions/boolish.rs b/tests/ui/transmutability/unions/boolish.rs new file mode 100644 index 000000000..e469c4973 --- /dev/null +++ b/tests/ui/transmutability/unions/boolish.rs @@ -0,0 +1,31 @@ +// check-pass + +#![crate_type = "lib"] +#![feature(transmutability)] +#![feature(marker_trait_attr)] +#![allow(dead_code)] +#![allow(incomplete_features)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn should_match_bool() { + #[derive(Copy, Clone)] #[repr(u8)] pub enum False { V = 0 } + #[derive(Copy, Clone)] #[repr(u8)] pub enum True { V = 1 } + + #[repr(C)] + pub union Bool { + pub f: False, + pub t: True, + } + + assert::is_transmutable::(); + assert::is_transmutable::(); +} diff --git a/tests/ui/transmutability/unions/repr/should_handle_align.rs b/tests/ui/transmutability/unions/repr/should_handle_align.rs new file mode 100644 index 000000000..09c13cc4d --- /dev/null +++ b/tests/ui/transmutability/unions/repr/should_handle_align.rs @@ -0,0 +1,47 @@ +// check-pass +//! The presence of an `align(X)` annotation must be accounted for. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn should_pad_explicitly_aligned_field() { + #[derive(Clone, Copy)] #[repr(u8)] enum V0u8 { V = 0 } + #[derive(Clone, Copy)] #[repr(u8)] enum V1u8 { V = 1 } + + #[repr(C)] + pub union Uninit { + a: (), + b: V1u8, + } + + #[repr(C, align(2))] + pub union align_2 { + a: V0u8, + } + + #[repr(C)] struct ImplicitlyPadded(align_2, V0u8); + #[repr(C)] struct ExplicitlyPadded(V0u8, Uninit, V0u8); + + // An implementation that (incorrectly) does not place a padding byte after + // `align_2` will, incorrectly, reject the following transmutations. + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); +} diff --git a/tests/ui/transmutability/unions/repr/should_handle_packed.rs b/tests/ui/transmutability/unions/repr/should_handle_packed.rs new file mode 100644 index 000000000..24c2abd69 --- /dev/null +++ b/tests/ui/transmutability/unions/repr/should_handle_packed.rs @@ -0,0 +1,48 @@ +// check-pass +//! The presence of an `align(X)` annotation must be accounted for. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn should_pad_explicitly_packed_field() { + #[derive(Clone, Copy)] #[repr(u8)] enum V0u8 { V = 0 } + #[derive(Clone, Copy)] #[repr(u8)] enum V1u8 { V = 1 } + #[derive(Clone, Copy)] #[repr(u8)] enum V2u8 { V = 2 } + #[derive(Clone, Copy)] #[repr(u32)] enum V3u32 { V = 3 } + + #[repr(C)] + pub union Uninit { + a: (), + b: V1u8, + } + + #[repr(C, packed(2))] + pub union Packed { + a: [V3u32; 0], + b: V0u8, + } + + #[repr(C)] struct ImplicitlyPadded(Packed, V2u8); + #[repr(C)] struct ExplicitlyPadded(V0u8, Uninit, V2u8); + + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); +} diff --git a/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.rs b/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.rs new file mode 100644 index 000000000..b1d5f71dc --- /dev/null +++ b/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.rs @@ -0,0 +1,44 @@ +//! A struct must have a well-defined layout to participate in a transmutation. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +fn should_reject_repr_rust() +{ + union repr_rust { + a: u8 + } + + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted +} + +fn should_accept_repr_C() +{ + #[repr(C)] + union repr_c { + a: u8 + } + + struct repr_rust; + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); +} diff --git a/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr new file mode 100644 index 000000000..523bde85a --- /dev/null +++ b/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr @@ -0,0 +1,49 @@ +error[E0277]: `should_reject_repr_rust::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:30:48 + | +LL | assert::is_maybe_transmutable::(); + | ^^ `should_reject_repr_rust::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `()` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ 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`. + --> $DIR/should_require_well_defined_layout.rs:31:43 + | +LL | assert::is_maybe_transmutable::(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `should_reject_repr_rust::repr_rust` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `should_reject_repr_rust::repr_rust` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_maybe_transmutable` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/unions/should_pad_variants.rs b/tests/ui/transmutability/unions/should_pad_variants.rs new file mode 100644 index 000000000..cabe54467 --- /dev/null +++ b/tests/ui/transmutability/unions/should_pad_variants.rs @@ -0,0 +1,45 @@ +//! The variants of a union must be padded with uninit bytes such that they have +//! the same length (in bytes). + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +#[derive(Clone, Copy)] +#[repr(C)] struct Zst; + +#[derive(Clone, Copy)] +#[repr(u8)] enum V0 { V = 0 } + +#[derive(Clone, Copy)] +#[repr(u8)] enum V2 { V = 2 } + +#[repr(C)] +union Lopsided { + smol: Zst, + lorg: V0, +} + +#[repr(C)] struct Src(V0, Zst, V2); +#[repr(C)] struct Dst(V0, Lopsided, V2); + +fn should_pad_variants() { + struct Context; + // If the implementation (incorrectly) fails to pad `Lopsided::smol` with + // an uninitialized byte, this transmutation might be (wrongly) accepted: + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted +} diff --git a/tests/ui/transmutability/unions/should_pad_variants.stderr b/tests/ui/transmutability/unions/should_pad_variants.stderr new file mode 100644 index 000000000..a823503d5 --- /dev/null +++ b/tests/ui/transmutability/unions/should_pad_variants.stderr @@ -0,0 +1,25 @@ +error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `should_pad_variants::Context`. + --> $DIR/should_pad_variants.rs:44:36 + | +LL | assert::is_transmutable::(); + | ^^^ `Src` cannot be safely transmuted into `Dst` in the defining scope of `should_pad_variants::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `Dst` +note: required by a bound in `is_transmutable` + --> $DIR/should_pad_variants.rs:13:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | |__________^ required by this bound in `is_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/unions/should_permit_intersecting_if_validity_is_assumed.rs b/tests/ui/transmutability/unions/should_permit_intersecting_if_validity_is_assumed.rs new file mode 100644 index 000000000..1007fdd79 --- /dev/null +++ b/tests/ui/transmutability/unions/should_permit_intersecting_if_validity_is_assumed.rs @@ -0,0 +1,38 @@ +// check-pass +//! If validity is assumed, there need only be one matching bit-pattern between +//! the source and destination types. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +#[derive(Clone, Copy)] #[repr(u8)] enum Ox00 { V = 0x00 } +#[derive(Clone, Copy)] #[repr(u8)] enum Ox7F { V = 0x7F } +#[derive(Clone, Copy)] #[repr(u8)] enum OxFF { V = 0xFF } + +fn test() { + #[repr(C)] + union A { + a: Ox00, + b: Ox7F, + } + + #[repr(C)] + union B { + a: Ox7F, + b: OxFF, + } + + assert::is_maybe_transmutable::(); + assert::is_maybe_transmutable::(); +} diff --git a/tests/ui/transmutability/unions/should_reject_contraction.rs b/tests/ui/transmutability/unions/should_reject_contraction.rs new file mode 100644 index 000000000..a24dfccd3 --- /dev/null +++ b/tests/ui/transmutability/unions/should_reject_contraction.rs @@ -0,0 +1,36 @@ +//! Validity may not be contracted, unless validity is assumed. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +#[derive(Clone, Copy)] #[repr(u8)] enum Ox00 { V = 0x00 } +#[derive(Clone, Copy)] #[repr(u8)] enum Ox01 { V = 0x01 } +#[derive(Clone, Copy)] #[repr(u8)] enum OxFF { V = 0xFF } + +fn test() { + #[repr(C)] + union Subset { + a: Ox00, + b: OxFF, + } + + #[repr(C)] + union Superset { + a: Ox00, + b: OxFF, + c: Ox01, + } + + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted +} diff --git a/tests/ui/transmutability/unions/should_reject_contraction.stderr b/tests/ui/transmutability/unions/should_reject_contraction.stderr new file mode 100644 index 000000000..41f0cedc3 --- /dev/null +++ b/tests/ui/transmutability/unions/should_reject_contraction.stderr @@ -0,0 +1,19 @@ +error[E0277]: `Superset` cannot be safely transmuted into `Subset` in the defining scope of `assert::Context`. + --> $DIR/should_reject_contraction.rs:35:41 + | +LL | assert::is_transmutable::(); + | ^^^^^^ `Superset` cannot be safely transmuted into `Subset` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `Subset` +note: required by a bound in `is_transmutable` + --> $DIR/should_reject_contraction.rs:13:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/unions/should_reject_disjoint.rs b/tests/ui/transmutability/unions/should_reject_disjoint.rs new file mode 100644 index 000000000..43aaa6905 --- /dev/null +++ b/tests/ui/transmutability/unions/should_reject_disjoint.rs @@ -0,0 +1,35 @@ +//! Validity must be satisfiable, even if validity is assumed. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_maybe_transmutable() + where + Dst: BikeshedIntrinsicFrom + {} +} + +#[derive(Clone, Copy)] #[repr(u8)] enum Ox00 { V = 0x00 } +#[derive(Clone, Copy)] #[repr(u8)] enum Ox01 { V = 0x01 } +#[derive(Clone, Copy)] #[repr(u8)] enum OxFF { V = 0xFF } + +fn test() { + #[repr(C)] + union A { + a: Ox00, + b: OxFF, + } + + #[repr(C)] + union B { + c: Ox01, + } + + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::(); //~ ERROR cannot be safely transmuted +} diff --git a/tests/ui/transmutability/unions/should_reject_disjoint.stderr b/tests/ui/transmutability/unions/should_reject_disjoint.stderr new file mode 100644 index 000000000..4323f9740 --- /dev/null +++ b/tests/ui/transmutability/unions/should_reject_disjoint.stderr @@ -0,0 +1,35 @@ +error[E0277]: `A` cannot be safely transmuted into `B` in the defining scope of `assert::Context`. + --> $DIR/should_reject_disjoint.rs:33:40 + | +LL | assert::is_maybe_transmutable::(); + | ^ `A` cannot be safely transmuted into `B` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `B` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_reject_disjoint.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`. + --> $DIR/should_reject_disjoint.rs:34:40 + | +LL | assert::is_maybe_transmutable::(); + | ^ `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `A` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_reject_disjoint.rs:13:14 + | +LL | pub fn is_maybe_transmutable() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/unions/should_reject_intersecting.rs b/tests/ui/transmutability/unions/should_reject_intersecting.rs new file mode 100644 index 000000000..9cd4233ee --- /dev/null +++ b/tests/ui/transmutability/unions/should_reject_intersecting.rs @@ -0,0 +1,38 @@ +//! ALL valid bit patterns of the source must be valid bit patterns of the +//! destination type, unless validity is assumed. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + pub struct Context; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + // validity is NOT assumed --------------^^^^^^^^^^^^^^^^^^ + {} +} + +#[derive(Clone, Copy)] #[repr(u8)] enum Ox00 { V = 0x00 } +#[derive(Clone, Copy)] #[repr(u8)] enum Ox7F { V = 0x7F } +#[derive(Clone, Copy)] #[repr(u8)] enum OxFF { V = 0xFF } + +fn test() { + #[repr(C)] + union A { + a: Ox00, + b: Ox7F, + } + + #[repr(C)] + union B { + a: Ox7F, + b: OxFF, + } + + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted +} diff --git a/tests/ui/transmutability/unions/should_reject_intersecting.stderr b/tests/ui/transmutability/unions/should_reject_intersecting.stderr new file mode 100644 index 000000000..e009888ae --- /dev/null +++ b/tests/ui/transmutability/unions/should_reject_intersecting.stderr @@ -0,0 +1,35 @@ +error[E0277]: `A` cannot be safely transmuted into `B` in the defining scope of `assert::Context`. + --> $DIR/should_reject_intersecting.rs:36:34 + | +LL | assert::is_transmutable::(); + | ^ `A` cannot be safely transmuted into `B` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `B` +note: required by a bound in `is_transmutable` + --> $DIR/should_reject_intersecting.rs:14:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`. + --> $DIR/should_reject_intersecting.rs:37:34 + | +LL | assert::is_transmutable::(); + | ^ `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `A` +note: required by a bound in `is_transmutable` + --> $DIR/should_reject_intersecting.rs:14:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_field.rs b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_field.rs new file mode 100644 index 000000000..8a41669c6 --- /dev/null +++ b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_field.rs @@ -0,0 +1,38 @@ +// check-pass +//! If visibility is assumed, a transmutation should be accepted even if the +//! destination type contains a private field. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + // safety IS assumed --------------------^^^^^^^^^^^^^^^^^^ + {} +} + +mod src { + #[repr(C)] pub(self) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(self) field: Zst, + } +} + +mod dst { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Dst { + pub(self) field: Zst, // <- private field + } +} + +fn test() { + struct Context; + assert::is_transmutable::(); +} diff --git a/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_variant.rs b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_variant.rs new file mode 100644 index 000000000..dd57b877d --- /dev/null +++ b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_variant.rs @@ -0,0 +1,39 @@ +// check-pass +//! If visibility is assumed, a transmutation should be accepted even if the +//! destination type contains a private variant. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + // safety IS assumed --------------------^^^^^^^^^^^^^^^^^^ + {} +} + +mod src { + #[repr(C)] pub(self) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(self) field: Zst, + } +} + +mod dst { + #[derive(Copy, Clone)] + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) union Dst { + pub(self) field: Zst, // <- private variant + } +} + +fn test() { + struct Context; + assert::is_transmutable::(); +} diff --git a/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_tricky_unreachable_field.rs b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_tricky_unreachable_field.rs new file mode 100644 index 000000000..ebce8ce87 --- /dev/null +++ b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_tricky_unreachable_field.rs @@ -0,0 +1,46 @@ +// check-pass +//! Unless visibility is assumed, a transmutation should be rejected if the +//! destination type contains an unreachable field (e.g., a public field with a +//! private type). (This rule is distinct from type privacy, which still may +//! forbid naming such types.) +//! +//! This test exercises a tricky-to-implement instance of this principle: the +//! "pub-in-priv trick". In the below example, the type `dst::private::Zst` is +//! unreachable from `Context`. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + // safety IS assumed --------------------^^^^^^^^^^^^^^^^^^ + {} +} + +mod src { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(in super) field: Zst, + } +} + +mod dst { + mod private { + #[repr(C)] pub struct Zst; // <- unreachable type + } + + #[repr(C)] pub(in super) struct Dst { + pub(in super) field: private::Zst, + } +} + +fn test() { + struct Context; + assert::is_transmutable::(); +} diff --git a/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs new file mode 100644 index 000000000..546fcbaa3 --- /dev/null +++ b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs @@ -0,0 +1,39 @@ +//! If visibility is assumed, a transmutation should be accepted even if the +//! destination type contains an unreachable field (e.g., a public field with a +//! private type). (This rule is distinct from type privacy, which still may +//! forbid naming such types.) + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + // safety IS assumed --------------------^^^^^^^^^^^^^^^^^^ + {} +} + +mod src { + #[repr(C)] pub(self) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(self) field: Zst, + } +} + +mod dst { + #[repr(C)] pub(self) struct Zst; // <- unreachable type + + #[repr(C)] pub(in super) struct Dst { + pub(in super) field: Zst, //~ ERROR private type + } +} + +fn test() { + struct Context; + assert::is_transmutable::(); +} diff --git a/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.stderr b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.stderr new file mode 100644 index 000000000..be83b7ce3 --- /dev/null +++ b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.stderr @@ -0,0 +1,12 @@ +error[E0446]: private type `dst::Zst` in public interface + --> $DIR/should_accept_if_dst_has_unreachable_field.rs:32:9 + | +LL | #[repr(C)] pub(self) struct Zst; // <- unreachable type + | -------------------- `dst::Zst` declared as private +... +LL | pub(in super) field: Zst, + | ^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0446`. diff --git a/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.rs b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.rs new file mode 100644 index 000000000..b9b74d183 --- /dev/null +++ b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.rs @@ -0,0 +1,40 @@ +//! If visibility is assumed, a transmutation should be accepted even if the +//! destination type contains an unreachable field (e.g., a public field with a +//! private type). (This rule is distinct from type privacy, which still may +//! forbid naming such types.) + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom + // safety IS assumed --------------------^^^^^^^^^^^^^^^^^^ + {} +} + +mod src { + #[repr(C)] pub(self) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(self) field: Zst, + } +} + +mod dst { + #[repr(C)] pub(in super) struct Zst; + + // unreachable type + #[repr(C)] pub(self) struct Dst { + pub(in super) field: Zst, + } +} + +fn test() { + struct Context; + assert::is_transmutable::(); //~ ERROR `Dst` is private +} diff --git a/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.stderr b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.stderr new file mode 100644 index 000000000..827df05de --- /dev/null +++ b/tests/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.stderr @@ -0,0 +1,15 @@ +error[E0603]: struct `Dst` is private + --> $DIR/should_accept_if_dst_has_unreachable_ty.rs:39:46 + | +LL | assert::is_transmutable::(); + | ^^^ private struct + | +note: the struct `Dst` is defined here + --> $DIR/should_accept_if_dst_has_unreachable_ty.rs:32:16 + | +LL | #[repr(C)] pub(self) struct Dst { + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0603`. diff --git a/tests/ui/transmutability/visibility/should_accept_if_src_has_private_field.rs b/tests/ui/transmutability/visibility/should_accept_if_src_has_private_field.rs new file mode 100644 index 000000000..5a0df09d4 --- /dev/null +++ b/tests/ui/transmutability/visibility/should_accept_if_src_has_private_field.rs @@ -0,0 +1,37 @@ +// check-pass +//! The presence of a private field 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() + where + Dst: BikeshedIntrinsicFrom // safety is NOT assumed + {} +} + +mod src { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(self) field: Zst, // <- private field + } +} + +mod dst { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Dst { + pub(in super) field: Zst, + } +} + +fn test() { + struct Context; + assert::is_transmutable::(); +} diff --git a/tests/ui/transmutability/visibility/should_accept_if_src_has_private_variant.rs b/tests/ui/transmutability/visibility/should_accept_if_src_has_private_variant.rs new file mode 100644 index 000000000..0f69630cc --- /dev/null +++ b/tests/ui/transmutability/visibility/should_accept_if_src_has_private_variant.rs @@ -0,0 +1,38 @@ +// check-pass +//! The presence of a private variant 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() + where + Dst: BikeshedIntrinsicFrom // safety is NOT assumed + {} +} + +mod src { + #[derive(Copy, Clone)] + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) union Src { + pub(self) field: Zst, // <- private variant + } +} + +mod dst { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Dst { + pub(in super) field: Zst, + } +} + +fn test() { + struct Context; + assert::is_transmutable::(); +} diff --git a/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs b/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs new file mode 100644 index 000000000..9c8345a8e --- /dev/null +++ b/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs @@ -0,0 +1,37 @@ +//! The presence of an unreachable field in the source type (e.g., a public +//! field with a private type does not affect transmutability. (This rule is +//! distinct from type privacy, which still may forbid naming such types.) + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom // safety is NOT assumed + {} +} + +mod src { + #[repr(C)] pub(self) struct Zst; // <- unreachable type + + #[repr(C)] pub(in super) struct Src { + pub(in super) field: Zst, //~ ERROR private type + } +} + +mod dst { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Dst { + pub(in super) field: Zst, + } +} + +fn test() { + struct Context; + assert::is_transmutable::(); +} diff --git a/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr b/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr new file mode 100644 index 000000000..39b73302e --- /dev/null +++ b/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr @@ -0,0 +1,12 @@ +error[E0446]: private type `src::Zst` in public interface + --> $DIR/should_accept_if_src_has_unreachable_field.rs:22:9 + | +LL | #[repr(C)] pub(self) struct Zst; // <- unreachable type + | -------------------- `src::Zst` declared as private +... +LL | pub(in super) field: Zst, + | ^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0446`. diff --git a/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.rs b/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.rs new file mode 100644 index 000000000..acf9f2302 --- /dev/null +++ b/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.rs @@ -0,0 +1,38 @@ +//! The presence of an unreachable source type (i.e., the source type is +//! private) does not affect transmutability. (This rule is distinct from type +//! privacy, which still may forbid naming such types.) + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom // safety is NOT assumed + {} +} + +mod src { + #[repr(C)] pub(in super) struct Zst; + + // unreachable type + #[repr(C)] pub(self) struct Src { + pub(in super) field: Zst, + } +} + +mod dst { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Dst { + pub(in super) field: Zst, + } +} + +fn test() { + struct Context; + assert::is_transmutable::(); //~ ERROR `Src` is private +} diff --git a/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.stderr b/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.stderr new file mode 100644 index 000000000..76dc7f340 --- /dev/null +++ b/tests/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.stderr @@ -0,0 +1,15 @@ +error[E0603]: struct `Src` is private + --> $DIR/should_accept_if_src_has_unreachable_ty.rs:37:36 + | +LL | assert::is_transmutable::(); + | ^^^ private struct + | +note: the struct `Src` is defined here + --> $DIR/should_accept_if_src_has_unreachable_ty.rs:22:16 + | +LL | #[repr(C)] pub(self) struct Src { + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0603`. diff --git a/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_field.rs b/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_field.rs new file mode 100644 index 000000000..e8c3fbc9a --- /dev/null +++ b/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_field.rs @@ -0,0 +1,36 @@ +//! Unless visibility is assumed, a transmutation should be rejected if the +//! destination type contains a private field. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom // safety is NOT assumed + {} +} + +mod src { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(in super) field: Zst, + } +} + +mod dst { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Dst { + pub(self) field: Zst, // <- private field + } +} + +fn test() { + struct Context; + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted +} diff --git a/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr b/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr new file mode 100644 index 000000000..d5d6d431b --- /dev/null +++ b/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr @@ -0,0 +1,19 @@ +error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`. + --> $DIR/should_reject_if_dst_has_private_field.rs:35:41 + | +LL | assert::is_transmutable::(); + | ^^^^^^^^ `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `Dst` +note: required by a bound in `is_transmutable` + --> $DIR/should_reject_if_dst_has_private_field.rs:13:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom // safety is NOT assumed + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.rs b/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.rs new file mode 100644 index 000000000..47bca27ab --- /dev/null +++ b/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.rs @@ -0,0 +1,37 @@ +//! Unless visibility is assumed, a transmutation should be rejected if the +//! destination type contains a private variant. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom // safety is NOT assumed + {} +} + +mod src { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(in super) field: Zst, + } +} + +mod dst { + #[derive(Copy, Clone)] + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) union Dst { + pub(self) field: Zst, // <- private variant + } +} + +fn test() { + struct Context; + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted +} diff --git a/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr b/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr new file mode 100644 index 000000000..a1ca2ced5 --- /dev/null +++ b/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr @@ -0,0 +1,19 @@ +error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`. + --> $DIR/should_reject_if_dst_has_private_variant.rs:36:41 + | +LL | assert::is_transmutable::(); + | ^^^^^^^^ `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `Dst` +note: required by a bound in `is_transmutable` + --> $DIR/should_reject_if_dst_has_private_variant.rs:13:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom // safety is NOT assumed + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/visibility/should_reject_if_dst_has_tricky_unreachable_field.rs b/tests/ui/transmutability/visibility/should_reject_if_dst_has_tricky_unreachable_field.rs new file mode 100644 index 000000000..662c32af1 --- /dev/null +++ b/tests/ui/transmutability/visibility/should_reject_if_dst_has_tricky_unreachable_field.rs @@ -0,0 +1,51 @@ +// check-pass +//! NOTE: This test documents a known-bug in the implementation of the +//! transmutability trait. Once fixed, the above "check-pass" header should be +//! removed, and an "ERROR cannot be safely transmuted" annotation should be added at the end +//! of the line starting with `assert::is_transmutable`. +//! +//! Unless visibility is assumed, a transmutation should be rejected if the +//! destination type contains an unreachable field (e.g., a public field with a +//! private type). (This rule is distinct from type privacy, which still may +//! forbid naming such types.) +//! +//! This test exercises a tricky-to-implement instance of this principle: the +//! "pub-in-priv trick". In the below example, the type `dst::private::Zst` is +//! unreachable from `Context`. Consequently, the transmute from `Src` to `Dst` +//! SHOULD be rejected. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom // safety is NOT assumed + {} +} + +mod src { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(in super) field: Zst, + } +} + +mod dst { + mod private { + #[repr(C)] pub struct Zst; // <- unreachable type + } + + #[repr(C)] pub(in super) struct Dst { + pub(in super) field: private::Zst, + } +} + +fn test() { + struct Context; + assert::is_transmutable::(); +} diff --git a/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.rs b/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.rs new file mode 100644 index 000000000..d7e21676f --- /dev/null +++ b/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.rs @@ -0,0 +1,38 @@ +//! Unless visibility is assumed, a transmutation should be rejected if the +//! destination type contains an unreachable field (e.g., a public field with a +//! private type). (This rule is distinct from type privacy, which still may +//! forbid naming such types.) + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom // safety is NOT assumed + {} +} + +mod src { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(in super) field: Zst, + } +} + +mod dst { + #[repr(C)] pub(self) struct Zst; // <- unreachable type + + #[repr(C)] pub(in super) struct Dst { + pub(in super) field: Zst, + } +} + +fn test() { + struct Context; + assert::is_transmutable::(); //~ ERROR cannot be safely transmuted +} diff --git a/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr b/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr new file mode 100644 index 000000000..4e648664d --- /dev/null +++ b/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr @@ -0,0 +1,19 @@ +error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`. + --> $DIR/should_reject_if_dst_has_unreachable_field.rs:37:41 + | +LL | assert::is_transmutable::(); + | ^^^^^^^^ `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `Dst` +note: required by a bound in `is_transmutable` + --> $DIR/should_reject_if_dst_has_unreachable_field.rs:15:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom // safety is NOT assumed + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.rs b/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.rs new file mode 100644 index 000000000..c7b59f15b --- /dev/null +++ b/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.rs @@ -0,0 +1,41 @@ +//! Unless visibility is assumed, a transmutation should be rejected if the +//! destination type contains an unreachable field (e.g., a public field with a +//! private type). (This rule is distinct from type privacy, which still may +//! forbid naming such types.) + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom // safety is NOT assumed + {} +} + +mod src { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(in super) field: Zst, + } +} + +mod dst { + #[repr(C)] pub(in super) struct Zst; + + // unreachable type + #[repr(C)] pub(self) struct Dst { + pub(in super) field: Zst, + } +} + +fn test() { + struct Context; + assert::is_transmutable::(); + //~^ ERROR `Dst` is private + //~| ERROR cannot be safely transmuted +} diff --git a/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr b/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr new file mode 100644 index 000000000..bd72d64cc --- /dev/null +++ b/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr @@ -0,0 +1,32 @@ +error[E0603]: struct `Dst` is private + --> $DIR/should_reject_if_dst_has_unreachable_ty.rs:38:46 + | +LL | assert::is_transmutable::(); + | ^^^ private struct + | +note: the struct `Dst` is defined here + --> $DIR/should_reject_if_dst_has_unreachable_ty.rs:31:16 + | +LL | #[repr(C)] pub(self) struct Dst { + | ^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`. + --> $DIR/should_reject_if_dst_has_unreachable_ty.rs:38:41 + | +LL | assert::is_transmutable::(); + | ^^^^^^^^ `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` is not implemented for `Dst` +note: required by a bound in `is_transmutable` + --> $DIR/should_reject_if_dst_has_unreachable_ty.rs:15:14 + | +LL | pub fn is_transmutable() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom // safety is NOT assumed + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0603. +For more information about an error, try `rustc --explain E0277`. -- cgit v1.2.3