9 #![allow(dead_code, unused_variables)]
10 #![deny(rustc::untranslatable_diagnostic)]
11 #![deny(rustc::diagnostic_outside_of_impl)]
16 #[cfg(feature = "rustc")]
17 pub(crate) use rustc_data_structures::fx::{FxHashMap as Map, FxHashSet as Set};
19 #[cfg(not(feature = "rustc"))]
20 pub(crate) use std::collections::{HashMap as Map, HashSet as Set};
22 pub(crate) mod layout;
23 pub(crate) mod maybe_transmutable;
33 /// The type encodes answers to the question: "Are these types transmutable?"
34 #[derive(Debug, Hash, Eq, PartialEq, PartialOrd, Ord, Clone)]
39 /// `Src` is transmutable into `Dst`.
42 /// `Src` is NOT transmutable into `Dst`.
45 /// `Src` is transmutable into `Dst`, if `src` is transmutable into `dst`.
46 IfTransmutable { src: R, dst: R },
48 /// `Src` is transmutable into `Dst`, if all of the enclosed requirements are met.
49 IfAll(Vec<Answer<R>>),
51 /// `Src` is transmutable into `Dst` if any of the enclosed requirements are met.
52 IfAny(Vec<Answer<R>>),
55 /// Answers: Why wasn't the source type transmutable into the destination type?
56 #[derive(Debug, Hash, Eq, PartialEq, PartialOrd, Ord, Clone)]
58 /// The layout of the source type is unspecified.
60 /// The layout of the destination type is unspecified.
62 /// The layout of the destination type is bit-incompatible with the source type.
64 /// There aren't any public constructors for `Dst`.
66 /// `Dst` is larger than `Src`, and the excess bytes were not exclusively uninitialized.
70 #[cfg(feature = "rustc")]
72 use rustc_infer::infer::InferCtxt;
73 use rustc_macros::{TypeFoldable, TypeVisitable};
74 use rustc_middle::traits::ObligationCause;
75 use rustc_middle::ty::Binder;
76 use rustc_middle::ty::Ty;
78 /// The source and destination types of a transmutation.
79 #[derive(TypeFoldable, TypeVisitable, Debug, Clone, Copy)]
80 pub struct Types<'tcx> {
83 /// The destination type.
87 pub struct TransmuteTypeEnv<'cx, 'tcx> {
88 infcx: &'cx InferCtxt<'cx, 'tcx>,
91 impl<'cx, 'tcx> TransmuteTypeEnv<'cx, 'tcx> {
92 pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>) -> Self {
97 pub fn is_transmutable(
99 cause: ObligationCause<'tcx>,
100 src_and_dst: Binder<'tcx, Types<'tcx>>,
102 assume: crate::Assume,
103 ) -> crate::Answer<crate::layout::rustc::Ref<'tcx>> {
104 let src = src_and_dst.map_bound(|types| types.src).skip_binder();
105 let dst = src_and_dst.map_bound(|types| types.dst).skip_binder();
106 crate::maybe_transmutable::MaybeTransmutableQuery::new(
118 #[cfg(feature = "rustc")]