Skip to main content

rustc_type_ir/
transmute.rs

1/// The result of a transmutability query under the supplied `Assume` options.
2#[derive(#[automatically_derived]
impl<R: ::core::fmt::Debug, T: ::core::fmt::Debug> ::core::fmt::Debug for
    Answer<R, T> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::Yes => ::core::fmt::Formatter::write_str(f, "Yes"),
            Self::No(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "No",
                    &__self_0),
            Self::If(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "If",
                    &__self_0),
        }
    }
}Debug, #[automatically_derived]
impl<R: ::core::hash::Hash, T: ::core::hash::Hash> ::core::hash::Hash for
    Answer<R, T> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&::core::intrinsics::discriminant_value(self),
            state);
        match self {
            Self::No(__self_0) => ::core::hash::Hash::hash(__self_0, state),
            Self::If(__self_0) => ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash, #[automatically_derived]
impl<R: ::core::cmp::Eq, T: ::core::cmp::Eq> ::core::cmp::Eq for Answer<R, T>
    {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Reason<T>>;
        let _: ::core::cmp::AssertParamIsEq<Condition<R, T>>;
    }
}Eq, #[automatically_derived]
impl<R: ::core::cmp::PartialEq, T: ::core::cmp::PartialEq>
    ::core::marker::StructuralPartialEq for Answer<R, T> {
}
#[automatically_derived]
impl<R: ::core::cmp::PartialEq, T: ::core::cmp::PartialEq>
    ::core::cmp::PartialEq for Answer<R, T> {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        ::core::intrinsics::discriminant_value(self) ==
                ::core::intrinsics::discriminant_value(other) &&
            match (self, other) {
                (Self::No(__self_0), Self::No(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::If(__self_0), Self::If(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl<R: ::core::clone::Clone, T: ::core::clone::Clone> ::core::clone::Clone
    for Answer<R, T> {
    #[inline]
    fn clone(&self) -> Self {
        match self {
            Self::Yes => Answer::Yes,
            Self::No(__self_0) =>
                Answer::No(::core::clone::Clone::clone(__self_0)),
            Self::If(__self_0) =>
                Answer::If(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone)]
3pub enum Answer<R, T> {
4    /// The analysis requires no further conditions.
5    Yes,
6    /// The analysis could not establish transmutability.
7    No(Reason<T>),
8    /// Transmutability depends on conditions that the trait solver must discharge.
9    If(Condition<R, T>),
10}
11
12/// A condition which must hold for safe transmutation to be possible.
13#[derive(#[automatically_derived]
impl<R: ::core::fmt::Debug, T: ::core::fmt::Debug> ::core::fmt::Debug for
    Condition<R, T> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::Transmutable { src: __self_0, dst: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "Transmutable", "src", __self_0, "dst", &__self_1),
            Self::Outlives { long: __self_0, short: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "Outlives", "long", __self_0, "short", &__self_1),
            Self::Immutable { ty: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "Immutable", "ty", &__self_0),
            Self::IfAll(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "IfAll",
                    &__self_0),
            Self::IfAny(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "IfAny",
                    &__self_0),
        }
    }
}Debug, #[automatically_derived]
impl<R: ::core::hash::Hash, T: ::core::hash::Hash> ::core::hash::Hash for
    Condition<R, T> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&::core::intrinsics::discriminant_value(self),
            state);
        match self {
            Self::Transmutable { src: __self_0, dst: __self_1 } => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state)
            }
            Self::Outlives { long: __self_0, short: __self_1 } => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state)
            }
            Self::Immutable { ty: __self_0 } =>
                ::core::hash::Hash::hash(__self_0, state),
            Self::IfAll(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            Self::IfAny(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
        }
    }
}Hash, #[automatically_derived]
impl<R: ::core::cmp::Eq, T: ::core::cmp::Eq> ::core::cmp::Eq for
    Condition<R, T> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<T>;
        let _: ::core::cmp::AssertParamIsEq<R>;
        let _: ::core::cmp::AssertParamIsEq<Vec<Condition<R, T>>>;
        let _: ::core::cmp::AssertParamIsEq<Vec<Condition<R, T>>>;
    }
}Eq, #[automatically_derived]
impl<R: ::core::cmp::PartialEq, T: ::core::cmp::PartialEq>
    ::core::marker::StructuralPartialEq for Condition<R, T> {
}
#[automatically_derived]
impl<R: ::core::cmp::PartialEq, T: ::core::cmp::PartialEq>
    ::core::cmp::PartialEq for Condition<R, T> {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        ::core::intrinsics::discriminant_value(self) ==
                ::core::intrinsics::discriminant_value(other) &&
            match (self, other) {
                (Self::Transmutable { src: __self_0, dst: __self_1 },
                    Self::Transmutable { src: __arg1_0, dst: __arg1_1 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                (Self::Outlives { long: __self_0, short: __self_1 },
                    Self::Outlives { long: __arg1_0, short: __arg1_1 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                (Self::Immutable { ty: __self_0 }, Self::Immutable {
                    ty: __arg1_0 }) => __self_0 == __arg1_0,
                (Self::IfAll(__self_0), Self::IfAll(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::IfAny(__self_0), Self::IfAny(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]
impl<R: ::core::clone::Clone, T: ::core::clone::Clone> ::core::clone::Clone
    for Condition<R, T> {
    #[inline]
    fn clone(&self) -> Self {
        match self {
            Self::Transmutable { src: __self_0, dst: __self_1 } =>
                Condition::Transmutable {
                    src: ::core::clone::Clone::clone(__self_0),
                    dst: ::core::clone::Clone::clone(__self_1),
                },
            Self::Outlives { long: __self_0, short: __self_1 } =>
                Condition::Outlives {
                    long: ::core::clone::Clone::clone(__self_0),
                    short: ::core::clone::Clone::clone(__self_1),
                },
            Self::Immutable { ty: __self_0 } =>
                Condition::Immutable {
                    ty: ::core::clone::Clone::clone(__self_0),
                },
            Self::IfAll(__self_0) =>
                Condition::IfAll(::core::clone::Clone::clone(__self_0)),
            Self::IfAny(__self_0) =>
                Condition::IfAny(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone)]
14pub enum Condition<R, T> {
15    /// `Src` is transmutable into `Dst`, if `src` is transmutable into `dst`.
16    Transmutable { src: T, dst: T },
17
18    /// The region `long` must outlive `short`.
19    Outlives { long: R, short: R },
20
21    /// The type `ty` must satisfy `Freeze`.
22    Immutable { ty: T },
23
24    /// `Src` is transmutable into `Dst`, if all of the enclosed requirements are met.
25    IfAll(Vec<Condition<R, T>>),
26
27    /// `Src` is transmutable into `Dst` if any of the enclosed requirements are met.
28    IfAny(Vec<Condition<R, T>>),
29}
30
31/// Answers "why wasn't the source type transmutable into the destination type?"
32#[derive(#[automatically_derived]
impl<T: ::core::fmt::Debug> ::core::fmt::Debug for Reason<T> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::SrcIsNotYetSupported =>
                ::core::fmt::Formatter::write_str(f, "SrcIsNotYetSupported"),
            Self::DstIsNotYetSupported =>
                ::core::fmt::Formatter::write_str(f, "DstIsNotYetSupported"),
            Self::DstIsBitIncompatible =>
                ::core::fmt::Formatter::write_str(f, "DstIsBitIncompatible"),
            Self::DstUninhabited =>
                ::core::fmt::Formatter::write_str(f, "DstUninhabited"),
            Self::DstMayHaveSafetyInvariants =>
                ::core::fmt::Formatter::write_str(f,
                    "DstMayHaveSafetyInvariants"),
            Self::DstIsTooBig =>
                ::core::fmt::Formatter::write_str(f, "DstIsTooBig"),
            Self::DstRefIsTooBig {
                src: __self_0,
                src_size: __self_1,
                dst: __self_2,
                dst_size: __self_3 } =>
                ::core::fmt::Formatter::debug_struct_field4_finish(f,
                    "DstRefIsTooBig", "src", __self_0, "src_size", __self_1,
                    "dst", __self_2, "dst_size", &__self_3),
            Self::DstHasStricterAlignment {
                src_min_align: __self_0, dst_min_align: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "DstHasStricterAlignment", "src_min_align", __self_0,
                    "dst_min_align", &__self_1),
            Self::DstIsMoreUnique =>
                ::core::fmt::Formatter::write_str(f, "DstIsMoreUnique"),
            Self::TypeError =>
                ::core::fmt::Formatter::write_str(f, "TypeError"),
            Self::SrcLayoutUnknown =>
                ::core::fmt::Formatter::write_str(f, "SrcLayoutUnknown"),
            Self::DstLayoutUnknown =>
                ::core::fmt::Formatter::write_str(f, "DstLayoutUnknown"),
            Self::SrcSizeOverflow =>
                ::core::fmt::Formatter::write_str(f, "SrcSizeOverflow"),
            Self::DstSizeOverflow =>
                ::core::fmt::Formatter::write_str(f, "DstSizeOverflow"),
        }
    }
}Debug, #[automatically_derived]
impl<T: ::core::hash::Hash> ::core::hash::Hash for Reason<T> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&::core::intrinsics::discriminant_value(self),
            state);
        match self {
            Self::DstRefIsTooBig {
                src: __self_0,
                src_size: __self_1,
                dst: __self_2,
                dst_size: __self_3 } => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state);
                ::core::hash::Hash::hash(__self_2, state);
                ::core::hash::Hash::hash(__self_3, state)
            }
            Self::DstHasStricterAlignment {
                src_min_align: __self_0, dst_min_align: __self_1 } => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state)
            }
            _ => {}
        }
    }
}Hash, #[automatically_derived]
impl<T: ::core::cmp::Eq> ::core::cmp::Eq for Reason<T> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<T>;
        let _: ::core::cmp::AssertParamIsEq<usize>;
    }
}Eq, #[automatically_derived]
impl<T: ::core::cmp::PartialEq> ::core::marker::StructuralPartialEq for
    Reason<T> {
}
#[automatically_derived]
impl<T: ::core::cmp::PartialEq> ::core::cmp::PartialEq for Reason<T> {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        ::core::intrinsics::discriminant_value(self) ==
                ::core::intrinsics::discriminant_value(other) &&
            match (self, other) {
                (Self::DstRefIsTooBig {
                    src: __self_0,
                    src_size: __self_1,
                    dst: __self_2,
                    dst_size: __self_3 }, Self::DstRefIsTooBig {
                    src: __arg1_0,
                    src_size: __arg1_1,
                    dst: __arg1_2,
                    dst_size: __arg1_3 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1 &&
                            __self_2 == __arg1_2 && __self_3 == __arg1_3,
                (Self::DstHasStricterAlignment {
                    src_min_align: __self_0, dst_min_align: __self_1 },
                    Self::DstHasStricterAlignment {
                    src_min_align: __arg1_0, dst_min_align: __arg1_1 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl<T: ::core::cmp::PartialOrd> ::core::cmp::PartialOrd for Reason<T> {
    #[inline]
    fn partial_cmp(&self, other: &Self)
        -> ::core::option::Option<::core::cmp::Ordering> {
        match (self, other) {
            (Self::DstRefIsTooBig {
                src: __self_0,
                src_size: __self_1,
                dst: __self_2,
                dst_size: __self_3 }, Self::DstRefIsTooBig {
                src: __arg1_0,
                src_size: __arg1_1,
                dst: __arg1_2,
                dst_size: __arg1_3 }) =>
                match ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0)
                    {
                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                        =>
                        match ::core::cmp::PartialOrd::partial_cmp(__self_1,
                                __arg1_1) {
                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                =>
                                match ::core::cmp::PartialOrd::partial_cmp(__self_2,
                                        __arg1_2) {
                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                        => ::core::cmp::PartialOrd::partial_cmp(__self_3, __arg1_3),
                                    cmp => cmp,
                                },
                            cmp => cmp,
                        },
                    cmp => cmp,
                },
            (Self::DstHasStricterAlignment {
                src_min_align: __self_0, dst_min_align: __self_1 },
                Self::DstHasStricterAlignment {
                src_min_align: __arg1_0, dst_min_align: __arg1_1 }) =>
                match ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0)
                    {
                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                        => ::core::cmp::PartialOrd::partial_cmp(__self_1, __arg1_1),
                    cmp => cmp,
                },
            _ =>
                ::core::cmp::PartialOrd::partial_cmp(&::core::intrinsics::discriminant_value(self),
                    &::core::intrinsics::discriminant_value(other)),
        }
    }
}PartialOrd, #[automatically_derived]
impl<T: ::core::cmp::Ord> ::core::cmp::Ord for Reason<T> {
    #[inline]
    fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
        match (self, other) {
            (Self::DstRefIsTooBig {
                src: __self_0,
                src_size: __self_1,
                dst: __self_2,
                dst_size: __self_3 }, Self::DstRefIsTooBig {
                src: __arg1_0,
                src_size: __arg1_1,
                dst: __arg1_2,
                dst_size: __arg1_3 }) =>
                match ::core::cmp::Ord::cmp(__self_0, __arg1_0) {
                    ::core::cmp::Ordering::Equal =>
                        match ::core::cmp::Ord::cmp(__self_1, __arg1_1) {
                            ::core::cmp::Ordering::Equal =>
                                match ::core::cmp::Ord::cmp(__self_2, __arg1_2) {
                                    ::core::cmp::Ordering::Equal =>
                                        ::core::cmp::Ord::cmp(__self_3, __arg1_3),
                                    cmp => cmp,
                                },
                            cmp => cmp,
                        },
                    cmp => cmp,
                },
            (Self::DstHasStricterAlignment {
                src_min_align: __self_0, dst_min_align: __self_1 },
                Self::DstHasStricterAlignment {
                src_min_align: __arg1_0, dst_min_align: __arg1_1 }) =>
                match ::core::cmp::Ord::cmp(__self_0, __arg1_0) {
                    ::core::cmp::Ordering::Equal =>
                        ::core::cmp::Ord::cmp(__self_1, __arg1_1),
                    cmp => cmp,
                },
            _ =>
                ::core::cmp::Ord::cmp(&::core::intrinsics::discriminant_value(self),
                    &::core::intrinsics::discriminant_value(other)),
        }
    }
}Ord, #[automatically_derived]
impl<T: ::core::clone::Clone> ::core::clone::Clone for Reason<T> {
    #[inline]
    fn clone(&self) -> Self {
        match self {
            Self::SrcIsNotYetSupported => Reason::SrcIsNotYetSupported,
            Self::DstIsNotYetSupported => Reason::DstIsNotYetSupported,
            Self::DstIsBitIncompatible => Reason::DstIsBitIncompatible,
            Self::DstUninhabited => Reason::DstUninhabited,
            Self::DstMayHaveSafetyInvariants =>
                Reason::DstMayHaveSafetyInvariants,
            Self::DstIsTooBig => Reason::DstIsTooBig,
            Self::DstRefIsTooBig {
                src: __self_0,
                src_size: __self_1,
                dst: __self_2,
                dst_size: __self_3 } =>
                Reason::DstRefIsTooBig {
                    src: ::core::clone::Clone::clone(__self_0),
                    src_size: ::core::clone::Clone::clone(__self_1),
                    dst: ::core::clone::Clone::clone(__self_2),
                    dst_size: ::core::clone::Clone::clone(__self_3),
                },
            Self::DstHasStricterAlignment {
                src_min_align: __self_0, dst_min_align: __self_1 } =>
                Reason::DstHasStricterAlignment {
                    src_min_align: ::core::clone::Clone::clone(__self_0),
                    dst_min_align: ::core::clone::Clone::clone(__self_1),
                },
            Self::DstIsMoreUnique => Reason::DstIsMoreUnique,
            Self::TypeError => Reason::TypeError,
            Self::SrcLayoutUnknown => Reason::SrcLayoutUnknown,
            Self::DstLayoutUnknown => Reason::DstLayoutUnknown,
            Self::SrcSizeOverflow => Reason::SrcSizeOverflow,
            Self::DstSizeOverflow => Reason::DstSizeOverflow,
        }
    }
}Clone)]
33pub enum Reason<T> {
34    /// The layout of the source type is not yet supported.
35    SrcIsNotYetSupported,
36    /// The layout of the destination type is not yet supported.
37    DstIsNotYetSupported,
38    /// The layout of the destination type is bit-incompatible with the source type.
39    DstIsBitIncompatible,
40    /// The destination type is uninhabited.
41    DstUninhabited,
42    /// The destination type may carry safety invariants.
43    DstMayHaveSafetyInvariants,
44    /// `Dst` is larger than `Src`, and the excess bytes were not exclusively uninitialized.
45    DstIsTooBig,
46    /// The destination referent is larger than the source referent.
47    DstRefIsTooBig {
48        /// The referent of the source type.
49        src: T,
50        /// The size of the source type's referent.
51        src_size: usize,
52        /// The too-large referent of the destination type.
53        dst: T,
54        /// The size of the destination type's referent.
55        dst_size: usize,
56    },
57    /// The destination referent requires stricter alignment than the source referent.
58    DstHasStricterAlignment { src_min_align: usize, dst_min_align: usize },
59    /// Can't go from shared pointer to unique pointer
60    DstIsMoreUnique,
61    /// Encountered a type error
62    TypeError,
63    /// The layout of src is unknown
64    SrcLayoutUnknown,
65    /// The layout of dst is unknown
66    DstLayoutUnknown,
67    /// The size of src is overflow
68    SrcSizeOverflow,
69    /// The size of dst is overflow
70    DstSizeOverflow,
71}
72
73impl<R, T> Answer<R, T> {
74    /// Requires both answers, combining their conditions into a conjunction.
75    pub fn and(self, rhs: Answer<R, T>) -> Answer<R, T> {
76        let lhs = self;
77        match (lhs, rhs) {
78            // Prefer a specific reason over generic bit incompatibility;
79            // otherwise, retain the left-hand reason.
80            (Answer::No(Reason::DstIsBitIncompatible), Answer::No(reason))
81            | (Answer::No(reason), Answer::No(_))
82            // If either is an error, return it
83            | (Answer::No(reason), _) | (_, Answer::No(reason)) => Answer::No(reason),
84            // If only one side has a condition, pass it along
85            (Answer::Yes, other) | (other, Answer::Yes) => other,
86            // If both sides have IfAll conditions, merge them
87            (Answer::If(Condition::IfAll(mut lhs)), Answer::If(Condition::IfAll(ref mut rhs))) => {
88                lhs.append(rhs);
89                Answer::If(Condition::IfAll(lhs))
90            }
91            // If only one side is an IfAll, add the other Condition to it
92            (Answer::If(cond), Answer::If(Condition::IfAll(mut conds)))
93            | (Answer::If(Condition::IfAll(mut conds)), Answer::If(cond)) => {
94                conds.push(cond);
95                Answer::If(Condition::IfAll(conds))
96            }
97            // Otherwise, both lhs and rhs conditions can be combined in a parent IfAll
98            (Answer::If(lhs), Answer::If(rhs)) => Answer::If(Condition::IfAll(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [lhs, rhs]))vec![lhs, rhs])),
99        }
100    }
101
102    /// Combines alternative answers and collects their conditions in an `IfAny`.
103    ///
104    /// Currently, combining `Yes` with `If` retains the condition. This differs
105    /// from Boolean disjunction, where unconditional success would suffice.
106    pub fn or(self, rhs: Answer<R, T>) -> Answer<R, T> {
107        let lhs = self;
108        match (lhs, rhs) {
109            // Prefer a specific reason over generic bit incompatibility;
110            // otherwise, retain the left-hand reason.
111            (Answer::No(Reason::DstIsBitIncompatible), Answer::No(reason))
112            | (Answer::No(reason), Answer::No(_)) => Answer::No(reason),
113            // Otherwise, errors can be ignored for the rest of the pattern matching
114            (Answer::No(_), other) | (other, Answer::No(_)) => other.or(Answer::Yes),
115            // If only one side has a condition, pass it along
116            (Answer::Yes, other) | (other, Answer::Yes) => other,
117            // If both sides have IfAny conditions, merge them
118            (Answer::If(Condition::IfAny(mut lhs)), Answer::If(Condition::IfAny(ref mut rhs))) => {
119                lhs.append(rhs);
120                Answer::If(Condition::IfAny(lhs))
121            }
122            // If only one side is an IfAny, add the other Condition to it
123            (Answer::If(cond), Answer::If(Condition::IfAny(mut conds)))
124            | (Answer::If(Condition::IfAny(mut conds)), Answer::If(cond)) => {
125                conds.push(cond);
126                Answer::If(Condition::IfAny(conds))
127            }
128            // Otherwise, both lhs and rhs conditions can be combined in a parent IfAny
129            (Answer::If(lhs), Answer::If(rhs)) => Answer::If(Condition::IfAny(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [lhs, rhs]))vec![lhs, rhs])),
130        }
131    }
132}