Skip to main content

rustc_middle/ty/
offload_meta.rs

1use bitflags::bitflags;
2use rustc_abi::{BackendRepr, TyAbiInterface};
3use rustc_span::sym;
4use rustc_target::callconv::ArgAbi;
5
6use crate::ty::{self, PseudoCanonicalInput, Ty, TyCtxt, TypingEnv};
7
8#[derive(#[automatically_derived]impl ::core::fmt::Debug for OffloadMetadata {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "OffloadMetadata payload_size mode", &self.payload_size,
            &&self.mode)
    }
}Debug, #[automatically_derived]impl ::core::marker::Copy for OffloadMetadata { }Copy, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
    for OffloadMetadata {
}
#[automatically_derived]impl ::core::clone::Clone for OffloadMetadata {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<OffloadSize>;
        let _: ::core::clone::AssertParamIsClone<MappingFlags>;
        *self
    }
}Clone)]
9pub struct OffloadMetadata {
10    pub payload_size: OffloadSize,
11    pub mode: MappingFlags,
12}
13
14#[derive(#[automatically_derived]impl ::core::fmt::Debug for OffloadSize {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::Static(__self_0) =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "Static", &__self_0),
            Self::Slice { element_size: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "Slice element_size", &__self_0),
        }
    }
}Debug, #[automatically_derived]impl ::core::marker::Copy for OffloadSize { }Copy, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
    for OffloadSize {
}
#[automatically_derived]impl ::core::clone::Clone for OffloadSize {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<u64>;
        *self
    }
}Clone)]
15pub enum OffloadSize {
16    Static(u64),
17    Slice { element_size: u64 },
18}
19
20#[doc = r" Mirrors `OpenMPOffloadMappingFlags` from Clang/OpenMP."]
#[repr(transparent)]
pub struct MappingFlags(<MappingFlags as
    ::bitflags::__private::PublicFlags>::Internal);
#[automatically_derived]impl ::core::fmt::Debug for MappingFlags {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f, "MappingFlags",
            &&self.0)
    }
}
#[automatically_derived]impl ::core::marker::Copy for MappingFlags { }
#[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
    for MappingFlags {
}
#[automatically_derived]impl ::core::clone::Clone for MappingFlags {
    #[inline]
    fn clone(&self) -> Self {
        let _:
                ::core::clone::AssertParamIsClone<<MappingFlags as
                ::bitflags::__private::PublicFlags>::Internal>;
        *self
    }
}
#[automatically_derived]impl ::core::marker::StructuralPartialEq for
    MappingFlags {
}
#[automatically_derived]impl ::core::cmp::PartialEq for MappingFlags {
    #[inline]
    fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}
#[automatically_derived]impl ::core::cmp::Eq for MappingFlags {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _:
                ::core::cmp::AssertParamIsEq<<MappingFlags as
                ::bitflags::__private::PublicFlags>::Internal>;
    }
}
impl MappingFlags {
    #[doc = r" No flags."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const NONE: Self = Self::from_bits_retain(0x0);
    #[doc =
    r" Allocate memory on the device and move data from host to device."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const TO: Self = Self::from_bits_retain(0x01);
    #[doc =
    r" Allocate memory on the device and move data from device to host."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const FROM: Self = Self::from_bits_retain(0x02);
    #[doc =
    r" Always perform the requested mapping action, even if already mapped."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const ALWAYS: Self = Self::from_bits_retain(0x04);
    #[doc =
    r" Delete the element from the device environment, ignoring ref count."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const DELETE: Self = Self::from_bits_retain(0x08);
    #[doc = r" The element being mapped is a pointer-pointee pair."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const PTR_AND_OBJ: Self = Self::from_bits_retain(0x10);
    #[doc =
    r" The base address should be passed to the target kernel as argument."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const TARGET_PARAM: Self = Self::from_bits_retain(0x20);
    #[doc = r" The runtime must return the device pointer."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const RETURN_PARAM: Self = Self::from_bits_retain(0x40);
    #[doc = r" The reference being passed is a pointer to private data."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const PRIVATE: Self = Self::from_bits_retain(0x80);
    #[doc = r" Pass the element by value."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const LITERAL: Self = Self::from_bits_retain(0x100);
    #[doc = r" Implicit map (generated by compiler, not explicit in code)."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const IMPLICIT: Self = Self::from_bits_retain(0x200);
    #[doc = r" Hint to allocate memory close to the target device."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const CLOSE: Self = Self::from_bits_retain(0x400);
    #[doc = r" Reserved (0x800 in OpenMP for XLC compatibility)."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const RESERVED: Self = Self::from_bits_retain(0x800);
    #[doc = r" Require that the data is already allocated on the device."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const PRESENT: Self = Self::from_bits_retain(0x1000);
    #[doc =
    r" Increment/decrement a separate ref counter (OpenACC compatibility)."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const OMPX_HOLD: Self = Self::from_bits_retain(0x2000);
    #[doc = r" Used for non-contiguous list items in target update."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const NON_CONTIG: Self = Self::from_bits_retain(0x100000000000);
    #[doc = r" 16 MSBs indicate membership in a struct."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const MEMBER_OF: Self = Self::from_bits_retain(0xffff000000000000);
}
impl ::bitflags::Flags for MappingFlags {
    const FLAGS: &'static [::bitflags::Flag<MappingFlags>] =
        &[{

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("NONE", MappingFlags::NONE)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("TO", MappingFlags::TO)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("FROM", MappingFlags::FROM)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("ALWAYS", MappingFlags::ALWAYS)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("DELETE", MappingFlags::DELETE)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("PTR_AND_OBJ",
                            MappingFlags::PTR_AND_OBJ)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("TARGET_PARAM",
                            MappingFlags::TARGET_PARAM)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("RETURN_PARAM",
                            MappingFlags::RETURN_PARAM)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("PRIVATE", MappingFlags::PRIVATE)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("LITERAL", MappingFlags::LITERAL)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("IMPLICIT", MappingFlags::IMPLICIT)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("CLOSE", MappingFlags::CLOSE)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("RESERVED", MappingFlags::RESERVED)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("PRESENT", MappingFlags::PRESENT)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("OMPX_HOLD", MappingFlags::OMPX_HOLD)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("NON_CONTIG",
                            MappingFlags::NON_CONTIG)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("MEMBER_OF", MappingFlags::MEMBER_OF)
                    }];
    type Bits = u64;
    fn bits(&self) -> u64 { MappingFlags::bits(self) }
    fn from_bits_retain(bits: u64) -> MappingFlags {
        MappingFlags::from_bits_retain(bits)
    }
}
#[allow(dead_code, deprecated, unused_doc_comments, unused_attributes,
unused_mut, unused_imports, non_upper_case_globals, clippy ::
assign_op_pattern, clippy :: indexing_slicing, clippy :: same_name_method,
clippy :: iter_without_into_iter,)]
const _: () =
    {
        #[repr(transparent)]
        pub struct InternalBitFlags(u64);
        #[automatically_derived]
        #[doc(hidden)]
        unsafe impl ::core::clone::TrivialClone for InternalBitFlags { }
        #[automatically_derived]
        impl ::core::clone::Clone for InternalBitFlags {
            #[inline]
            fn clone(&self) -> Self {
                let _: ::core::clone::AssertParamIsClone<u64>;
                *self
            }
        }
        #[automatically_derived]
        impl ::core::marker::Copy for InternalBitFlags { }
        #[automatically_derived]
        impl ::core::marker::StructuralPartialEq for InternalBitFlags { }
        #[automatically_derived]
        impl ::core::cmp::PartialEq for InternalBitFlags {
            #[inline]
            fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
        }
        #[automatically_derived]
        impl ::core::cmp::Eq for InternalBitFlags {
            #[inline]
            #[doc(hidden)]
            #[coverage(off)]
            fn assert_fields_are_eq(&self) {
                let _: ::core::cmp::AssertParamIsEq<u64>;
            }
        }
        #[automatically_derived]
        impl ::core::cmp::PartialOrd for InternalBitFlags {
            #[inline]
            fn partial_cmp(&self, other: &Self)
                -> ::core::option::Option<::core::cmp::Ordering> {
                ::core::option::Option::Some(::core::cmp::Ord::cmp(self,
                        other))
            }
        }
        #[automatically_derived]
        impl ::core::cmp::Ord for InternalBitFlags {
            #[inline]
            fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
                ::core::cmp::Ord::cmp(&self.0, &other.0)
            }
        }
        #[automatically_derived]
        impl ::core::hash::Hash for InternalBitFlags {
            #[inline]
            fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
                ::core::hash::Hash::hash(&self.0, state)
            }
        }
        impl ::bitflags::__private::PublicFlags for MappingFlags {
            type Primitive = u64;
            type Internal = InternalBitFlags;
        }
        impl ::bitflags::__private::core::default::Default for
            InternalBitFlags {
            #[inline]
            fn default() -> Self { InternalBitFlags::empty() }
        }
        impl ::bitflags::__private::core::fmt::Debug for InternalBitFlags {
            fn fmt(&self,
                f: &mut ::bitflags::__private::core::fmt::Formatter<'_>)
                -> ::bitflags::__private::core::fmt::Result {
                if self.is_empty() {
                    f.write_fmt(format_args!("{0:#x}",
                            <u64 as ::bitflags::Bits>::EMPTY))
                } else {
                    ::bitflags::__private::core::fmt::Display::fmt(self, f)
                }
            }
        }
        impl ::bitflags::__private::core::fmt::Display for InternalBitFlags {
            fn fmt(&self,
                f: &mut ::bitflags::__private::core::fmt::Formatter<'_>)
                -> ::bitflags::__private::core::fmt::Result {
                ::bitflags::parser::to_writer(&MappingFlags(*self), f)
            }
        }
        impl ::bitflags::__private::core::str::FromStr for InternalBitFlags {
            type Err = ::bitflags::parser::ParseError;
            fn from_str(s: &str)
                ->
                    ::bitflags::__private::core::result::Result<Self,
                    Self::Err> {
                ::bitflags::parser::from_str::<MappingFlags>(s).map(|flags|
                        flags.0)
            }
        }
        impl ::bitflags::__private::core::convert::AsRef<u64> for
            InternalBitFlags {
            fn as_ref(&self) -> &u64 { &self.0 }
        }
        impl ::bitflags::__private::core::convert::From<u64> for
            InternalBitFlags {
            fn from(bits: u64) -> Self { Self::from_bits_retain(bits) }
        }
        #[allow(dead_code, deprecated, unused_attributes)]
        impl InternalBitFlags {
            /// Get a flags value with all bits unset.
            #[inline]
            pub const fn empty() -> Self {
                Self(<u64 as ::bitflags::Bits>::EMPTY)
            }
            /// Get a flags value with all known bits set.
            #[inline]
            pub const fn all() -> Self {
                let mut truncated = <u64 as ::bitflags::Bits>::EMPTY;
                let mut i = 0;
                {
                    {
                        let flag =
                            <MappingFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <MappingFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <MappingFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <MappingFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <MappingFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <MappingFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <MappingFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <MappingFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <MappingFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <MappingFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <MappingFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <MappingFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <MappingFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <MappingFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <MappingFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <MappingFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <MappingFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                let _ = i;
                Self(truncated)
            }
            /// Get the underlying bits value.
            ///
            /// The returned value is exactly the bits set in this flags value.
            #[inline]
            pub const fn bits(&self) -> u64 { self.0 }
            /// Convert from a bits value.
            ///
            /// This method will return `None` if any unknown bits are set.
            #[inline]
            pub const fn from_bits(bits: u64)
                -> ::bitflags::__private::core::option::Option<Self> {
                let truncated = Self::from_bits_truncate(bits).0;
                if truncated == bits {
                    ::bitflags::__private::core::option::Option::Some(Self(bits))
                } else { ::bitflags::__private::core::option::Option::None }
            }
            /// Convert from a bits value, unsetting any unknown bits.
            #[inline]
            pub const fn from_bits_truncate(bits: u64) -> Self {
                Self(bits & Self::all().0)
            }
            /// Convert from a bits value exactly.
            #[inline]
            pub const fn from_bits_retain(bits: u64) -> Self { Self(bits) }
            /// Get a flags value with the bits of a flag with the given name set.
            ///
            /// This method will return `None` if `name` is empty or doesn't
            /// correspond to any named flag.
            #[inline]
            pub fn from_name(name: &str)
                -> ::bitflags::__private::core::option::Option<Self> {
                {
                    if name == "NONE" {
                        return ::bitflags::__private::core::option::Option::Some(Self(MappingFlags::NONE.bits()));
                    }
                };
                ;
                {
                    if name == "TO" {
                        return ::bitflags::__private::core::option::Option::Some(Self(MappingFlags::TO.bits()));
                    }
                };
                ;
                {
                    if name == "FROM" {
                        return ::bitflags::__private::core::option::Option::Some(Self(MappingFlags::FROM.bits()));
                    }
                };
                ;
                {
                    if name == "ALWAYS" {
                        return ::bitflags::__private::core::option::Option::Some(Self(MappingFlags::ALWAYS.bits()));
                    }
                };
                ;
                {
                    if name == "DELETE" {
                        return ::bitflags::__private::core::option::Option::Some(Self(MappingFlags::DELETE.bits()));
                    }
                };
                ;
                {
                    if name == "PTR_AND_OBJ" {
                        return ::bitflags::__private::core::option::Option::Some(Self(MappingFlags::PTR_AND_OBJ.bits()));
                    }
                };
                ;
                {
                    if name == "TARGET_PARAM" {
                        return ::bitflags::__private::core::option::Option::Some(Self(MappingFlags::TARGET_PARAM.bits()));
                    }
                };
                ;
                {
                    if name == "RETURN_PARAM" {
                        return ::bitflags::__private::core::option::Option::Some(Self(MappingFlags::RETURN_PARAM.bits()));
                    }
                };
                ;
                {
                    if name == "PRIVATE" {
                        return ::bitflags::__private::core::option::Option::Some(Self(MappingFlags::PRIVATE.bits()));
                    }
                };
                ;
                {
                    if name == "LITERAL" {
                        return ::bitflags::__private::core::option::Option::Some(Self(MappingFlags::LITERAL.bits()));
                    }
                };
                ;
                {
                    if name == "IMPLICIT" {
                        return ::bitflags::__private::core::option::Option::Some(Self(MappingFlags::IMPLICIT.bits()));
                    }
                };
                ;
                {
                    if name == "CLOSE" {
                        return ::bitflags::__private::core::option::Option::Some(Self(MappingFlags::CLOSE.bits()));
                    }
                };
                ;
                {
                    if name == "RESERVED" {
                        return ::bitflags::__private::core::option::Option::Some(Self(MappingFlags::RESERVED.bits()));
                    }
                };
                ;
                {
                    if name == "PRESENT" {
                        return ::bitflags::__private::core::option::Option::Some(Self(MappingFlags::PRESENT.bits()));
                    }
                };
                ;
                {
                    if name == "OMPX_HOLD" {
                        return ::bitflags::__private::core::option::Option::Some(Self(MappingFlags::OMPX_HOLD.bits()));
                    }
                };
                ;
                {
                    if name == "NON_CONTIG" {
                        return ::bitflags::__private::core::option::Option::Some(Self(MappingFlags::NON_CONTIG.bits()));
                    }
                };
                ;
                {
                    if name == "MEMBER_OF" {
                        return ::bitflags::__private::core::option::Option::Some(Self(MappingFlags::MEMBER_OF.bits()));
                    }
                };
                ;
                let _ = name;
                ::bitflags::__private::core::option::Option::None
            }
            /// Whether all bits in this flags value are unset.
            #[inline]
            pub const fn is_empty(&self) -> bool {
                self.0 == <u64 as ::bitflags::Bits>::EMPTY
            }
            /// Whether all known bits in this flags value are set.
            #[inline]
            pub const fn is_all(&self) -> bool {
                Self::all().0 | self.0 == self.0
            }
            /// Whether any set bits in a source flags value are also set in a target flags value.
            #[inline]
            pub const fn intersects(&self, other: Self) -> bool {
                self.0 & other.0 != <u64 as ::bitflags::Bits>::EMPTY
            }
            /// Whether all set bits in a source flags value are also set in a target flags value.
            #[inline]
            pub const fn contains(&self, other: Self) -> bool {
                self.0 & other.0 == other.0
            }
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            pub fn insert(&mut self, other: Self) {
                *self = Self(self.0).union(other);
            }
            /// The intersection of a source flags value with the complement of a target flags
            /// value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `remove` won't truncate `other`, but the `!` operator will.
            #[inline]
            pub fn remove(&mut self, other: Self) {
                *self = Self(self.0).difference(other);
            }
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            pub fn toggle(&mut self, other: Self) {
                *self = Self(self.0).symmetric_difference(other);
            }
            /// Call `insert` when `value` is `true` or `remove` when `value` is `false`.
            #[inline]
            pub fn set(&mut self, other: Self, value: bool) {
                if value { self.insert(other); } else { self.remove(other); }
            }
            /// The bitwise and (`&`) of the bits in two flags values.
            #[inline]
            #[must_use]
            pub const fn intersection(self, other: Self) -> Self {
                Self(self.0 & other.0)
            }
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            #[must_use]
            pub const fn union(self, other: Self) -> Self {
                Self(self.0 | other.0)
            }
            /// The intersection of a source flags value with the complement of a target flags
            /// value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            #[must_use]
            pub const fn difference(self, other: Self) -> Self {
                Self(self.0 & !other.0)
            }
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            #[must_use]
            pub const fn symmetric_difference(self, other: Self) -> Self {
                Self(self.0 ^ other.0)
            }
            /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
            #[inline]
            #[must_use]
            pub const fn complement(self) -> Self {
                Self::from_bits_truncate(!self.0)
            }
        }
        impl ::bitflags::__private::core::fmt::Binary for InternalBitFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::Binary::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::Octal for InternalBitFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::Octal::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::LowerHex for InternalBitFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::LowerHex::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::UpperHex for InternalBitFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::UpperHex::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::ops::BitOr for InternalBitFlags {
            type Output = Self;
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            fn bitor(self, other: InternalBitFlags) -> Self {
                self.union(other)
            }
        }
        impl ::bitflags::__private::core::ops::BitOrAssign for
            InternalBitFlags {
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            fn bitor_assign(&mut self, other: Self) { self.insert(other); }
        }
        impl ::bitflags::__private::core::ops::BitXor for InternalBitFlags {
            type Output = Self;
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            fn bitxor(self, other: Self) -> Self {
                self.symmetric_difference(other)
            }
        }
        impl ::bitflags::__private::core::ops::BitXorAssign for
            InternalBitFlags {
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            fn bitxor_assign(&mut self, other: Self) { self.toggle(other); }
        }
        impl ::bitflags::__private::core::ops::BitAnd for InternalBitFlags {
            type Output = Self;
            /// The bitwise and (`&`) of the bits in two flags values.
            #[inline]
            fn bitand(self, other: Self) -> Self { self.intersection(other) }
        }
        impl ::bitflags::__private::core::ops::BitAndAssign for
            InternalBitFlags {
            /// The bitwise and (`&`) of the bits in two flags values.
            #[inline]
            fn bitand_assign(&mut self, other: Self) {
                *self =
                    Self::from_bits_retain(self.bits()).intersection(other);
            }
        }
        impl ::bitflags::__private::core::ops::Sub for InternalBitFlags {
            type Output = Self;
            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            fn sub(self, other: Self) -> Self { self.difference(other) }
        }
        impl ::bitflags::__private::core::ops::SubAssign for InternalBitFlags
            {
            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            fn sub_assign(&mut self, other: Self) { self.remove(other); }
        }
        impl ::bitflags::__private::core::ops::Not for InternalBitFlags {
            type Output = Self;
            /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
            #[inline]
            fn not(self) -> Self { self.complement() }
        }
        impl ::bitflags::__private::core::iter::Extend<InternalBitFlags> for
            InternalBitFlags {
            /// The bitwise or (`|`) of the bits in each flags value.
            fn extend<T: ::bitflags::__private::core::iter::IntoIterator<Item
                = Self>>(&mut self, iterator: T) {
                for item in iterator { self.insert(item) }
            }
        }
        impl ::bitflags::__private::core::iter::FromIterator<InternalBitFlags>
            for InternalBitFlags {
            /// The bitwise or (`|`) of the bits in each flags value.
            fn from_iter<T: ::bitflags::__private::core::iter::IntoIterator<Item
                = Self>>(iterator: T) -> Self {
                use ::bitflags::__private::core::iter::Extend;
                let mut result = Self::empty();
                result.extend(iterator);
                result
            }
        }
        impl InternalBitFlags {
            /// Yield a set of contained flags values.
            ///
            /// Each yielded flags value will correspond to a defined named flag. Any unknown bits
            /// will be yielded together as a final flags value.
            #[inline]
            pub const fn iter(&self) -> ::bitflags::iter::Iter<MappingFlags> {
                ::bitflags::iter::Iter::__private_const_new(<MappingFlags as
                        ::bitflags::Flags>::FLAGS,
                    MappingFlags::from_bits_retain(self.bits()),
                    MappingFlags::from_bits_retain(self.bits()))
            }
            /// Yield a set of contained named flags values.
            ///
            /// This method is like [`iter`](#method.iter), except only yields bits in contained named flags.
            /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded.
            #[inline]
            pub const fn iter_names(&self)
                -> ::bitflags::iter::IterNames<MappingFlags> {
                ::bitflags::iter::IterNames::__private_const_new(<MappingFlags
                        as ::bitflags::Flags>::FLAGS,
                    MappingFlags::from_bits_retain(self.bits()),
                    MappingFlags::from_bits_retain(self.bits()))
            }
        }
        impl ::bitflags::__private::core::iter::IntoIterator for
            InternalBitFlags {
            type Item = MappingFlags;
            type IntoIter = ::bitflags::iter::Iter<MappingFlags>;
            fn into_iter(self) -> Self::IntoIter { self.iter() }
        }
        impl InternalBitFlags {
            /// Returns a mutable reference to the raw value of the flags currently stored.
            #[inline]
            pub fn bits_mut(&mut self) -> &mut u64 { &mut self.0 }
        }
        #[allow(dead_code, deprecated, unused_attributes)]
        impl MappingFlags {
            /// Get a flags value with all bits unset.
            #[inline]
            pub const fn empty() -> Self { Self(InternalBitFlags::empty()) }
            /// Get a flags value with all known bits set.
            #[inline]
            pub const fn all() -> Self { Self(InternalBitFlags::all()) }
            /// Get the underlying bits value.
            ///
            /// The returned value is exactly the bits set in this flags value.
            #[inline]
            pub const fn bits(&self) -> u64 { self.0.bits() }
            /// Convert from a bits value.
            ///
            /// This method will return `None` if any unknown bits are set.
            #[inline]
            pub const fn from_bits(bits: u64)
                -> ::bitflags::__private::core::option::Option<Self> {
                match InternalBitFlags::from_bits(bits) {
                    ::bitflags::__private::core::option::Option::Some(bits) =>
                        ::bitflags::__private::core::option::Option::Some(Self(bits)),
                    ::bitflags::__private::core::option::Option::None =>
                        ::bitflags::__private::core::option::Option::None,
                }
            }
            /// Convert from a bits value, unsetting any unknown bits.
            #[inline]
            pub const fn from_bits_truncate(bits: u64) -> Self {
                Self(InternalBitFlags::from_bits_truncate(bits))
            }
            /// Convert from a bits value exactly.
            #[inline]
            pub const fn from_bits_retain(bits: u64) -> Self {
                Self(InternalBitFlags::from_bits_retain(bits))
            }
            /// Get a flags value with the bits of a flag with the given name set.
            ///
            /// This method will return `None` if `name` is empty or doesn't
            /// correspond to any named flag.
            #[inline]
            pub fn from_name(name: &str)
                -> ::bitflags::__private::core::option::Option<Self> {
                match InternalBitFlags::from_name(name) {
                    ::bitflags::__private::core::option::Option::Some(bits) =>
                        ::bitflags::__private::core::option::Option::Some(Self(bits)),
                    ::bitflags::__private::core::option::Option::None =>
                        ::bitflags::__private::core::option::Option::None,
                }
            }
            /// Whether all bits in this flags value are unset.
            #[inline]
            pub const fn is_empty(&self) -> bool { self.0.is_empty() }
            /// Whether all known bits in this flags value are set.
            #[inline]
            pub const fn is_all(&self) -> bool { self.0.is_all() }
            /// Whether any set bits in a source flags value are also set in a target flags value.
            #[inline]
            pub const fn intersects(&self, other: Self) -> bool {
                self.0.intersects(other.0)
            }
            /// Whether all set bits in a source flags value are also set in a target flags value.
            #[inline]
            pub const fn contains(&self, other: Self) -> bool {
                self.0.contains(other.0)
            }
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            pub fn insert(&mut self, other: Self) { self.0.insert(other.0) }
            /// The intersection of a source flags value with the complement of a target flags
            /// value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `remove` won't truncate `other`, but the `!` operator will.
            #[inline]
            pub fn remove(&mut self, other: Self) { self.0.remove(other.0) }
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            pub fn toggle(&mut self, other: Self) { self.0.toggle(other.0) }
            /// Call `insert` when `value` is `true` or `remove` when `value` is `false`.
            #[inline]
            pub fn set(&mut self, other: Self, value: bool) {
                self.0.set(other.0, value)
            }
            /// The bitwise and (`&`) of the bits in two flags values.
            #[inline]
            #[must_use]
            pub const fn intersection(self, other: Self) -> Self {
                Self(self.0.intersection(other.0))
            }
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            #[must_use]
            pub const fn union(self, other: Self) -> Self {
                Self(self.0.union(other.0))
            }
            /// The intersection of a source flags value with the complement of a target flags
            /// value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            #[must_use]
            pub const fn difference(self, other: Self) -> Self {
                Self(self.0.difference(other.0))
            }
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            #[must_use]
            pub const fn symmetric_difference(self, other: Self) -> Self {
                Self(self.0.symmetric_difference(other.0))
            }
            /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
            #[inline]
            #[must_use]
            pub const fn complement(self) -> Self {
                Self(self.0.complement())
            }
        }
        impl ::bitflags::__private::core::fmt::Binary for MappingFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::Binary::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::Octal for MappingFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::Octal::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::LowerHex for MappingFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::LowerHex::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::UpperHex for MappingFlags {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::UpperHex::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::ops::BitOr for MappingFlags {
            type Output = Self;
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            fn bitor(self, other: MappingFlags) -> Self { self.union(other) }
        }
        impl ::bitflags::__private::core::ops::BitOrAssign for MappingFlags {
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            fn bitor_assign(&mut self, other: Self) { self.insert(other); }
        }
        impl ::bitflags::__private::core::ops::BitXor for MappingFlags {
            type Output = Self;
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            fn bitxor(self, other: Self) -> Self {
                self.symmetric_difference(other)
            }
        }
        impl ::bitflags::__private::core::ops::BitXorAssign for MappingFlags {
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            fn bitxor_assign(&mut self, other: Self) { self.toggle(other); }
        }
        impl ::bitflags::__private::core::ops::BitAnd for MappingFlags {
            type Output = Self;
            /// The bitwise and (`&`) of the bits in two flags values.
            #[inline]
            fn bitand(self, other: Self) -> Self { self.intersection(other) }
        }
        impl ::bitflags::__private::core::ops::BitAndAssign for MappingFlags {
            /// The bitwise and (`&`) of the bits in two flags values.
            #[inline]
            fn bitand_assign(&mut self, other: Self) {
                *self =
                    Self::from_bits_retain(self.bits()).intersection(other);
            }
        }
        impl ::bitflags::__private::core::ops::Sub for MappingFlags {
            type Output = Self;
            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            fn sub(self, other: Self) -> Self { self.difference(other) }
        }
        impl ::bitflags::__private::core::ops::SubAssign for MappingFlags {
            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            fn sub_assign(&mut self, other: Self) { self.remove(other); }
        }
        impl ::bitflags::__private::core::ops::Not for MappingFlags {
            type Output = Self;
            /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
            #[inline]
            fn not(self) -> Self { self.complement() }
        }
        impl ::bitflags::__private::core::iter::Extend<MappingFlags> for
            MappingFlags {
            /// The bitwise or (`|`) of the bits in each flags value.
            fn extend<T: ::bitflags::__private::core::iter::IntoIterator<Item
                = Self>>(&mut self, iterator: T) {
                for item in iterator { self.insert(item) }
            }
        }
        impl ::bitflags::__private::core::iter::FromIterator<MappingFlags> for
            MappingFlags {
            /// The bitwise or (`|`) of the bits in each flags value.
            fn from_iter<T: ::bitflags::__private::core::iter::IntoIterator<Item
                = Self>>(iterator: T) -> Self {
                use ::bitflags::__private::core::iter::Extend;
                let mut result = Self::empty();
                result.extend(iterator);
                result
            }
        }
        impl MappingFlags {
            /// Yield a set of contained flags values.
            ///
            /// Each yielded flags value will correspond to a defined named flag. Any unknown bits
            /// will be yielded together as a final flags value.
            #[inline]
            pub const fn iter(&self) -> ::bitflags::iter::Iter<MappingFlags> {
                ::bitflags::iter::Iter::__private_const_new(<MappingFlags as
                        ::bitflags::Flags>::FLAGS,
                    MappingFlags::from_bits_retain(self.bits()),
                    MappingFlags::from_bits_retain(self.bits()))
            }
            /// Yield a set of contained named flags values.
            ///
            /// This method is like [`iter`](#method.iter), except only yields bits in contained named flags.
            /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded.
            #[inline]
            pub const fn iter_names(&self)
                -> ::bitflags::iter::IterNames<MappingFlags> {
                ::bitflags::iter::IterNames::__private_const_new(<MappingFlags
                        as ::bitflags::Flags>::FLAGS,
                    MappingFlags::from_bits_retain(self.bits()),
                    MappingFlags::from_bits_retain(self.bits()))
            }
        }
        impl ::bitflags::__private::core::iter::IntoIterator for MappingFlags
            {
            type Item = MappingFlags;
            type IntoIter = ::bitflags::iter::Iter<MappingFlags>;
            fn into_iter(self) -> Self::IntoIter { self.iter() }
        }
    };bitflags! {
21    /// Mirrors `OpenMPOffloadMappingFlags` from Clang/OpenMP.
22    #[derive(Debug, Copy, Clone, PartialEq, Eq)]
23    #[repr(transparent)]
24    pub struct MappingFlags: u64 {
25        /// No flags.
26        const NONE           = 0x0;
27        /// Allocate memory on the device and move data from host to device.
28        const TO             = 0x01;
29        /// Allocate memory on the device and move data from device to host.
30        const FROM           = 0x02;
31        /// Always perform the requested mapping action, even if already mapped.
32        const ALWAYS         = 0x04;
33        /// Delete the element from the device environment, ignoring ref count.
34        const DELETE         = 0x08;
35        /// The element being mapped is a pointer-pointee pair.
36        const PTR_AND_OBJ    = 0x10;
37        /// The base address should be passed to the target kernel as argument.
38        const TARGET_PARAM   = 0x20;
39        /// The runtime must return the device pointer.
40        const RETURN_PARAM   = 0x40;
41        /// The reference being passed is a pointer to private data.
42        const PRIVATE        = 0x80;
43        /// Pass the element by value.
44        const LITERAL        = 0x100;
45        /// Implicit map (generated by compiler, not explicit in code).
46        const IMPLICIT       = 0x200;
47        /// Hint to allocate memory close to the target device.
48        const CLOSE          = 0x400;
49        /// Reserved (0x800 in OpenMP for XLC compatibility).
50        const RESERVED       = 0x800;
51        /// Require that the data is already allocated on the device.
52        const PRESENT        = 0x1000;
53        /// Increment/decrement a separate ref counter (OpenACC compatibility).
54        const OMPX_HOLD      = 0x2000;
55        /// Used for non-contiguous list items in target update.
56        const NON_CONTIG     = 0x100000000000;
57        /// 16 MSBs indicate membership in a struct.
58        const MEMBER_OF      = 0xffff000000000000;
59    }
60}
61
62impl OffloadMetadata {
63    pub fn from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self {
64        OffloadMetadata {
65            payload_size: get_payload_size(tcx, ty),
66            mode: MappingFlags::from_ty(tcx, ty),
67        }
68    }
69
70    pub fn handle_abi<'tcx, C>(
71        cx: &C,
72        tcx: TyCtxt<'tcx>,
73        ty: Ty<'tcx>,
74        arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
75    ) -> Vec<(Self, Ty<'tcx>)>
76    where
77        Ty<'tcx>: TyAbiInterface<'tcx, C>,
78    {
79        if let Some(elem_ty) = region_element_ty(tcx, ty) {
80            let ptr = OffloadMetadata::from_ty(tcx, Ty::new_slice(tcx, elem_ty));
81            let len = OffloadMetadata::from_ty(tcx, tcx.types.usize);
82            // `Region` is a `{ ptr, len }` pair, but field order is not guaranteed.
83            return arg_abi
84                .layout
85                .fields
86                .index_by_increasing_offset()
87                .filter(|&i| arg_abi.layout.field(cx, i).size.bytes() != 0)
88                .map(|i| {
89                    if arg_abi.layout.field(cx, i).ty == tcx.types.usize {
90                        (len, tcx.types.usize)
91                    } else {
92                        (ptr, Ty::new_mut_ptr(tcx, elem_ty))
93                    }
94                })
95                .collect();
96        }
97
98        match arg_abi.layout.backend_repr {
99            BackendRepr::ScalarPair { a: _, b: _, b_offset: _ } => (0..2)
100                .map(|i| {
101                    let ty = arg_abi.layout.field(cx, i).ty;
102                    (OffloadMetadata::from_ty(tcx, ty), ty)
103                })
104                .collect(),
105            _ => ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [(OffloadMetadata::from_ty(tcx, ty), ty)]))vec![(OffloadMetadata::from_ty(tcx, ty), ty)],
106        }
107    }
108}
109
110pub fn is_region_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
111    #[allow(non_exhaustive_omitted_patterns)] match ty.kind() {
    ty::Adt(def, _) if
        Some(def.did()) == tcx.get_diagnostic_item(sym::offload_region) =>
        true,
    _ => false,
}matches!(
112        ty.kind(),
113        ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::offload_region)
114    )
115}
116
117fn region_element_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
118    if is_region_ty(tcx, ty) {
119        let ty::Adt(_, args) = ty.kind() else { ::core::panicking::unreachable_default_msg()unreachable!() };
120        Some(args.type_at(1))
121    } else {
122        None
123    }
124}
125
126// FIXME(Sa4dUs): implement a solid logic to determine the payload size
127fn get_payload_size<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> OffloadSize {
128    match ty.kind() {
129        ty::Slice(elem_ty) => {
130            let layout = tcx.layout_of(PseudoCanonicalInput {
131                typing_env: TypingEnv::fully_monomorphized(),
132                value: *elem_ty,
133            });
134            OffloadSize::Slice { element_size: layout.unwrap().size.bytes() }
135        }
136        ty::RawPtr(inner, _) | ty::Ref(_, inner, _) => get_payload_size(tcx, *inner),
137        _ => OffloadSize::Static(
138            tcx.layout_of(PseudoCanonicalInput {
139                typing_env: TypingEnv::fully_monomorphized(),
140                value: ty,
141            })
142            .unwrap()
143            .size
144            .bytes(),
145        ),
146    }
147}
148
149impl MappingFlags {
150    fn from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self {
151        use rustc_ast::Mutability::*;
152
153        match ty.kind() {
154            ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) => {
155                MappingFlags::LITERAL | MappingFlags::IMPLICIT
156            }
157
158            // FIXME: This should not treat aliases this way.
159            ty::Adt(_, _) | ty::Tuple(_) | ty::Array(_, _) | ty::Alias(_, _) | ty::Param(_) => {
160                MappingFlags::TO
161            }
162
163            ty::RawPtr(_, Not) | ty::Ref(_, _, Not) => MappingFlags::TO,
164
165            ty::RawPtr(_, Mut) | ty::Ref(_, _, Mut) => MappingFlags::TO | MappingFlags::FROM,
166
167            ty::Slice(_) | ty::Str | ty::Dynamic(_, _) => MappingFlags::TO | MappingFlags::FROM,
168
169            ty::Foreign(_) | ty::Pat(_, _) | ty::UnsafeBinder(_) => {
170                MappingFlags::TO | MappingFlags::FROM
171            }
172
173            ty::FnDef(_, _)
174            | ty::FnPtr(_, _)
175            | ty::Closure(_, _)
176            | ty::CoroutineClosure(_, _)
177            | ty::Coroutine(_, _)
178            | ty::CoroutineWitness(_, _)
179            | ty::Never
180            | ty::Bound(_, _)
181            | ty::Placeholder(_)
182            | ty::Infer(_)
183            | ty::Error(_) => {
184                tcx.dcx()
185                    .span_err(rustc_span::DUMMY_SP, ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("type `{0:?}` cannot be offloaded",
                ty))
    })format!("type `{ty:?}` cannot be offloaded"));
186                MappingFlags::empty()
187            }
188        }
189    }
190}