1 #![feature(alloc_layout_extra, control_flow_enum, decl_macro, iterator_try_reduce, never_type)]
2 #![allow(dead_code, unused_variables)]
3 #![deny(rustc::untranslatable_diagnostic)]
4 #![deny(rustc::diagnostic_outside_of_impl)]
9 #[cfg(feature = "rustc")]
10 pub(crate) use rustc_data_structures::fx::{FxHashMap as Map, FxHashSet as Set};
12 #[cfg(not(feature = "rustc"))]
13 pub(crate) use std::collections::{HashMap as Map, HashSet as Set};
15 pub(crate) mod layout;
16 pub(crate) mod maybe_transmutable;
26 /// The type encodes answers to the question: "Are these types transmutable?"
27 #[derive(Debug, Hash, Eq, PartialEq, PartialOrd, Ord, Clone)]
32 /// `Src` is transmutable into `Dst`.
35 /// `Src` is NOT transmutable into `Dst`.
38 /// `Src` is transmutable into `Dst`, if `src` is transmutable into `dst`.
39 IfTransmutable { src: R, dst: R },
41 /// `Src` is transmutable into `Dst`, if all of the enclosed requirements are met.
42 IfAll(Vec<Answer<R>>),
44 /// `Src` is transmutable into `Dst` if any of the enclosed requirements are met.
45 IfAny(Vec<Answer<R>>),
48 /// Answers: Why wasn't the source type transmutable into the destination type?
49 #[derive(Debug, Hash, Eq, PartialEq, PartialOrd, Ord, Clone)]
51 /// The layout of the source type is unspecified.
53 /// The layout of the destination type is unspecified.
55 /// The layout of the destination type is bit-incompatible with the source type.
57 /// There aren't any public constructors for `Dst`.
59 /// `Dst` is larger than `Src`, and the excess bytes were not exclusively uninitialized.
63 #[cfg(feature = "rustc")]
65 use rustc_infer::infer::InferCtxt;
66 use rustc_macros::{TypeFoldable, TypeVisitable};
67 use rustc_middle::traits::ObligationCause;
68 use rustc_middle::ty::Binder;
69 use rustc_middle::ty::Ty;
71 /// The source and destination types of a transmutation.
72 #[derive(TypeFoldable, TypeVisitable, Debug, Clone, Copy)]
73 pub struct Types<'tcx> {
76 /// The destination type.
80 pub struct TransmuteTypeEnv<'cx, 'tcx> {
81 infcx: &'cx InferCtxt<'cx, 'tcx>,
84 impl<'cx, 'tcx> TransmuteTypeEnv<'cx, 'tcx> {
85 pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>) -> Self {
90 pub fn is_transmutable(
92 cause: ObligationCause<'tcx>,
93 src_and_dst: Binder<'tcx, Types<'tcx>>,
95 assume: crate::Assume,
96 ) -> crate::Answer<crate::layout::rustc::Ref<'tcx>> {
97 let src = src_and_dst.map_bound(|types| types.src).skip_binder();
98 let dst = src_and_dst.map_bound(|types| types.dst).skip_binder();
99 crate::maybe_transmutable::MaybeTransmutableQuery::new(
111 #[cfg(feature = "rustc")]