Skip to main content

rustc_middle/middle/
codegen_fn_attrs.rs

1use std::borrow::Cow;
2
3use rustc_abi::Align;
4use rustc_attr_ir::{
5    InlineAttr, InstructionSetAttr, InstrumentFnAttr, Linkage, OptimizeAttr, RtsanSetting,
6};
7use rustc_hir::def_id::DefId;
8use rustc_macros::{StableHash, TyDecodable, TyEncodable};
9use rustc_span::Symbol;
10use rustc_target::spec::SanitizerSet;
11
12use crate::mono::Visibility;
13use crate::ty::{InstanceKind, ShimKind, TyCtxt};
14
15impl<'tcx> TyCtxt<'tcx> {
16    pub fn codegen_instance_attrs(
17        self,
18        instance_kind: InstanceKind<'_>,
19    ) -> Cow<'tcx, CodegenFnAttrs> {
20        // NOTE: we try to not clone the `CodegenFnAttrs` when that is not needed.
21        // The `to_mut` method used below clones the inner value.
22        let mut attrs = Cow::Borrowed(self.codegen_fn_attrs(instance_kind.def_id()));
23
24        // Drop the `#[naked]` attribute on non-item `InstanceKind`s, like the shims that
25        // are generated for indirect function calls.
26        if !#[allow(non_exhaustive_omitted_patterns)] match instance_kind {
    InstanceKind::Item(_) => true,
    _ => false,
}matches!(instance_kind, InstanceKind::Item(_)) {
27            if attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
28                attrs.to_mut().flags.remove(CodegenFnAttrFlags::NAKED);
29            }
30        }
31
32        // A shim created by `#[track_caller]` should not inherit any attributes
33        // that modify the symbol name. Failing to remove these attributes from
34        // the shim leads to errors like `symbol `foo` is already defined`.
35        //
36        // A `ClosureOnceShim` with the track_caller attribute does not have a symbol,
37        // and therefore can be skipped here.
38        if let InstanceKind::Shim(ShimKind::Reify(_, _)) = instance_kind
39            && attrs.flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
40        {
41            if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) {
42                attrs.to_mut().flags.remove(CodegenFnAttrFlags::NO_MANGLE);
43            }
44
45            if attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
46                attrs.to_mut().flags.remove(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL);
47            }
48
49            if attrs.flags.contains(CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM) {
50                attrs.to_mut().flags.remove(CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM);
51            }
52
53            if attrs.symbol_name.is_some() {
54                attrs.to_mut().symbol_name = None;
55            }
56        }
57
58        // Ensure closure shims have the optimization properties of their closure applied to them.
59        if let InstanceKind::Shim(ShimKind::ClosureOnce {
60            call_once: _,
61            closure,
62            track_caller: _,
63        }) = instance_kind
64        {
65            let closure_attrs = self.codegen_fn_attrs(closure);
66            attrs.to_mut().optimize = closure_attrs.optimize;
67        }
68
69        attrs
70    }
71}
72
73#[derive(#[automatically_derived]
impl ::core::clone::Clone for CodegenFnAttrs {
    #[inline]
    fn clone(&self) -> CodegenFnAttrs {
        CodegenFnAttrs {
            flags: ::core::clone::Clone::clone(&self.flags),
            inline: ::core::clone::Clone::clone(&self.inline),
            optimize: ::core::clone::Clone::clone(&self.optimize),
            symbol_name: ::core::clone::Clone::clone(&self.symbol_name),
            foreign_item_symbol_aliases: ::core::clone::Clone::clone(&self.foreign_item_symbol_aliases),
            link_ordinal: ::core::clone::Clone::clone(&self.link_ordinal),
            target_features: ::core::clone::Clone::clone(&self.target_features),
            safe_target_features: ::core::clone::Clone::clone(&self.safe_target_features),
            linkage: ::core::clone::Clone::clone(&self.linkage),
            import_linkage: ::core::clone::Clone::clone(&self.import_linkage),
            link_section: ::core::clone::Clone::clone(&self.link_section),
            sanitizers: ::core::clone::Clone::clone(&self.sanitizers),
            instruction_set: ::core::clone::Clone::clone(&self.instruction_set),
            alignment: ::core::clone::Clone::clone(&self.alignment),
            patchable_function_entry: ::core::clone::Clone::clone(&self.patchable_function_entry),
            objc_class: ::core::clone::Clone::clone(&self.objc_class),
            objc_selector: ::core::clone::Clone::clone(&self.objc_selector),
            instrument_fn: ::core::clone::Clone::clone(&self.instrument_fn),
        }
    }
}Clone, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for CodegenFnAttrs {
            fn encode(&self, __encoder: &mut __E) {
                let CodegenFnAttrs {
                        flags: ref __binding_0,
                        inline: ref __binding_1,
                        optimize: ref __binding_2,
                        symbol_name: ref __binding_3,
                        foreign_item_symbol_aliases: ref __binding_4,
                        link_ordinal: ref __binding_5,
                        target_features: ref __binding_6,
                        safe_target_features: ref __binding_7,
                        linkage: ref __binding_8,
                        import_linkage: ref __binding_9,
                        link_section: ref __binding_10,
                        sanitizers: ref __binding_11,
                        instruction_set: ref __binding_12,
                        alignment: ref __binding_13,
                        patchable_function_entry: ref __binding_14,
                        objc_class: ref __binding_15,
                        objc_selector: ref __binding_16,
                        instrument_fn: ref __binding_17 } = *self;
                ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_3,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_4,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_5,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_6,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_7,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_8,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_9,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_10,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_11,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_12,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_13,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_14,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_15,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_16,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_17,
                    __encoder);
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for CodegenFnAttrs {
            fn decode(__decoder: &mut __D) -> Self {
                CodegenFnAttrs {
                    flags: ::rustc_serialize::Decodable::decode(__decoder),
                    inline: ::rustc_serialize::Decodable::decode(__decoder),
                    optimize: ::rustc_serialize::Decodable::decode(__decoder),
                    symbol_name: ::rustc_serialize::Decodable::decode(__decoder),
                    foreign_item_symbol_aliases: ::rustc_serialize::Decodable::decode(__decoder),
                    link_ordinal: ::rustc_serialize::Decodable::decode(__decoder),
                    target_features: ::rustc_serialize::Decodable::decode(__decoder),
                    safe_target_features: ::rustc_serialize::Decodable::decode(__decoder),
                    linkage: ::rustc_serialize::Decodable::decode(__decoder),
                    import_linkage: ::rustc_serialize::Decodable::decode(__decoder),
                    link_section: ::rustc_serialize::Decodable::decode(__decoder),
                    sanitizers: ::rustc_serialize::Decodable::decode(__decoder),
                    instruction_set: ::rustc_serialize::Decodable::decode(__decoder),
                    alignment: ::rustc_serialize::Decodable::decode(__decoder),
                    patchable_function_entry: ::rustc_serialize::Decodable::decode(__decoder),
                    objc_class: ::rustc_serialize::Decodable::decode(__decoder),
                    objc_selector: ::rustc_serialize::Decodable::decode(__decoder),
                    instrument_fn: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };TyDecodable, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for
            CodegenFnAttrs {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    CodegenFnAttrs {
                        flags: ref __binding_0,
                        inline: ref __binding_1,
                        optimize: ref __binding_2,
                        symbol_name: ref __binding_3,
                        foreign_item_symbol_aliases: ref __binding_4,
                        link_ordinal: ref __binding_5,
                        target_features: ref __binding_6,
                        safe_target_features: ref __binding_7,
                        linkage: ref __binding_8,
                        import_linkage: ref __binding_9,
                        link_section: ref __binding_10,
                        sanitizers: ref __binding_11,
                        instruction_set: ref __binding_12,
                        alignment: ref __binding_13,
                        patchable_function_entry: ref __binding_14,
                        objc_class: ref __binding_15,
                        objc_selector: ref __binding_16,
                        instrument_fn: ref __binding_17 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                        { __binding_4.stable_hash(__hcx, __hasher); }
                        { __binding_5.stable_hash(__hcx, __hasher); }
                        { __binding_6.stable_hash(__hcx, __hasher); }
                        { __binding_7.stable_hash(__hcx, __hasher); }
                        { __binding_8.stable_hash(__hcx, __hasher); }
                        { __binding_9.stable_hash(__hcx, __hasher); }
                        { __binding_10.stable_hash(__hcx, __hasher); }
                        { __binding_11.stable_hash(__hcx, __hasher); }
                        { __binding_12.stable_hash(__hcx, __hasher); }
                        { __binding_13.stable_hash(__hcx, __hasher); }
                        { __binding_14.stable_hash(__hcx, __hasher); }
                        { __binding_15.stable_hash(__hcx, __hasher); }
                        { __binding_16.stable_hash(__hcx, __hasher); }
                        { __binding_17.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, #[automatically_derived]
impl ::core::fmt::Debug for CodegenFnAttrs {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["flags", "inline", "optimize", "symbol_name",
                        "foreign_item_symbol_aliases", "link_ordinal",
                        "target_features", "safe_target_features", "linkage",
                        "import_linkage", "link_section", "sanitizers",
                        "instruction_set", "alignment", "patchable_function_entry",
                        "objc_class", "objc_selector", "instrument_fn"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.flags, &self.inline, &self.optimize, &self.symbol_name,
                        &self.foreign_item_symbol_aliases, &self.link_ordinal,
                        &self.target_features, &self.safe_target_features,
                        &self.linkage, &self.import_linkage, &self.link_section,
                        &self.sanitizers, &self.instruction_set, &self.alignment,
                        &self.patchable_function_entry, &self.objc_class,
                        &self.objc_selector, &&self.instrument_fn];
        ::core::fmt::Formatter::debug_struct_fields_finish(f,
            "CodegenFnAttrs", names, values)
    }
}Debug)]
74pub struct CodegenFnAttrs {
75    pub flags: CodegenFnAttrFlags,
76    /// Parsed representation of the `#[inline]` attribute
77    pub inline: InlineAttr,
78    /// Parsed representation of the `#[optimize]` attribute
79    pub optimize: OptimizeAttr,
80    /// The name this function will be imported/exported under. This can be set
81    /// using the `#[export_name = "..."]` or `#[link_name = "..."]` attribute
82    /// depending on if this is a function definition or foreign function.
83    pub symbol_name: Option<Symbol>,
84    /// Defids of foreign items somewhere that this function should "satisfy".
85    /// i.e., if a foreign function has some symbol foo,
86    /// generate this function under its real name,
87    /// but *also* under the same name as this foreign function so that the foreign function has an implementation.
88    // FIXME: make "SymbolName<'tcx>"
89    pub foreign_item_symbol_aliases: Vec<(DefId, Linkage, Visibility)>,
90    /// The `#[link_ordinal = "..."]` attribute, indicating an ordinal an
91    /// imported function has in the dynamic library. Note that this must not
92    /// be set when `link_name` is set. This is for foreign items with the
93    /// "raw-dylib" kind.
94    pub link_ordinal: Option<u16>,
95    /// The `#[target_feature(enable = "...")]` attribute and the enabled
96    /// features (only enabled features are supported right now).
97    /// Implied target features have already been applied.
98    pub target_features: Vec<TargetFeature>,
99    /// Whether the function was declared safe, but has target features
100    pub safe_target_features: bool,
101    /// The `#[linkage = "..."]` attribute on Rust-defined items and the value we found.
102    pub linkage: Option<Linkage>,
103    /// The `#[linkage = "..."]` attribute on foreign items and the value we found.
104    pub import_linkage: Option<Linkage>,
105    /// The `#[link_section = "..."]` attribute, or what executable section this
106    /// should be placed in.
107    pub link_section: Option<Symbol>,
108    /// The `#[sanitize(xyz = "off")]` attribute. Indicates the settings for each
109    /// sanitizer for this function.
110    pub sanitizers: SanitizerFnAttrs,
111    /// The `#[instruction_set(set)]` attribute. Indicates if the generated code should
112    /// be generated against a specific instruction set. Only usable on architectures which allow
113    /// switching between multiple instruction sets.
114    pub instruction_set: Option<InstructionSetAttr>,
115    /// The `#[align(...)]` attribute. Determines the alignment of the function body.
116    // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
117    pub alignment: Option<Align>,
118    /// The `#[patchable_function_entry(...)]` attribute. Indicates how many nops should be around
119    /// the function entry, or override default section to record entry location.
120    pub patchable_function_entry: Option<PatchableFunctionEntry>,
121    /// The `#[rustc_objc_class = "..."]` attribute.
122    pub objc_class: Option<Symbol>,
123    /// The `#[rustc_objc_selector = "..."]` attribute.
124    pub objc_selector: Option<Symbol>,
125    /// The `#[instrument_fn]` attribute.
126    pub instrument_fn: Option<InstrumentFnAttr>,
127}
128
129#[derive(#[automatically_derived]
impl ::core::marker::Copy for TargetFeatureKind { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for TargetFeatureKind { }
#[automatically_derived]
impl ::core::clone::Clone for TargetFeatureKind {
    #[inline]
    fn clone(&self) -> TargetFeatureKind { *self }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for TargetFeatureKind {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                TargetFeatureKind::Implied => "Implied",
                TargetFeatureKind::Enabled => "Enabled",
                TargetFeatureKind::Forced => "Forced",
            })
    }
}Debug, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for TargetFeatureKind {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        TargetFeatureKind::Implied => { 0usize }
                        TargetFeatureKind::Enabled => { 1usize }
                        TargetFeatureKind::Forced => { 2usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for TargetFeatureKind {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { TargetFeatureKind::Implied }
                    1usize => { TargetFeatureKind::Enabled }
                    2usize => { TargetFeatureKind::Forced }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `TargetFeatureKind`, expected 0..3, actual {0}",
                                n));
                    }
                }
            }
        }
    };TyDecodable, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for
            TargetFeatureKind {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    TargetFeatureKind::Implied => {}
                    TargetFeatureKind::Enabled => {}
                    TargetFeatureKind::Forced => {}
                }
            }
        }
    };StableHash, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for TargetFeatureKind { }
#[automatically_derived]
impl ::core::cmp::PartialEq for TargetFeatureKind {
    #[inline]
    fn eq(&self, other: &TargetFeatureKind) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for TargetFeatureKind {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq)]
130pub enum TargetFeatureKind {
131    /// The feature is implied by another feature, rather than explicitly added by the
132    /// `#[target_feature]` attribute
133    Implied,
134    /// The feature is added by the regular `target_feature` attribute.
135    Enabled,
136    /// The feature is added by the unsafe `force_target_feature` attribute.
137    Forced,
138}
139
140#[derive(#[automatically_derived]
impl ::core::marker::Copy for TargetFeature { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for TargetFeature { }
#[automatically_derived]
impl ::core::clone::Clone for TargetFeature {
    #[inline]
    fn clone(&self) -> TargetFeature {
        let _: ::core::clone::AssertParamIsClone<Symbol>;
        let _: ::core::clone::AssertParamIsClone<TargetFeatureKind>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for TargetFeature {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "TargetFeature",
            "name", &self.name, "kind", &&self.kind)
    }
}Debug, #[automatically_derived]
impl ::core::cmp::Eq for TargetFeature {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Symbol>;
        let _: ::core::cmp::AssertParamIsEq<TargetFeatureKind>;
    }
}Eq, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for TargetFeature { }
#[automatically_derived]
impl ::core::cmp::PartialEq for TargetFeature {
    #[inline]
    fn eq(&self, other: &TargetFeature) -> bool {
        self.name == other.name && self.kind == other.kind
    }
}PartialEq, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for TargetFeature {
            fn encode(&self, __encoder: &mut __E) {
                let TargetFeature {
                        name: ref __binding_0, kind: ref __binding_1 } = *self;
                ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                    __encoder);
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for TargetFeature {
            fn decode(__decoder: &mut __D) -> Self {
                TargetFeature {
                    name: ::rustc_serialize::Decodable::decode(__decoder),
                    kind: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };TyDecodable, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for
            TargetFeature {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    TargetFeature { name: ref __binding_0, kind: ref __binding_1
                        } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
141pub struct TargetFeature {
142    /// The name of the target feature (e.g. "avx")
143    pub name: Symbol,
144    /// The way this feature was enabled.
145    pub kind: TargetFeatureKind,
146}
147
148#[derive(#[automatically_derived]
impl ::core::marker::Copy for PatchableFunctionEntry { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for PatchableFunctionEntry { }
#[automatically_derived]
impl ::core::clone::Clone for PatchableFunctionEntry {
    #[inline]
    fn clone(&self) -> PatchableFunctionEntry {
        let _: ::core::clone::AssertParamIsClone<Option<u8>>;
        let _: ::core::clone::AssertParamIsClone<Option<u8>>;
        let _: ::core::clone::AssertParamIsClone<Option<Symbol>>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for PatchableFunctionEntry {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "PatchableFunctionEntry", "prefix", &self.prefix, "entry",
            &self.entry, "section", &&self.section)
    }
}Debug, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for PatchableFunctionEntry {
            fn encode(&self, __encoder: &mut __E) {
                let PatchableFunctionEntry {
                        prefix: ref __binding_0,
                        entry: ref __binding_1,
                        section: ref __binding_2 } = *self;
                ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                    __encoder);
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for PatchableFunctionEntry {
            fn decode(__decoder: &mut __D) -> Self {
                PatchableFunctionEntry {
                    prefix: ::rustc_serialize::Decodable::decode(__decoder),
                    entry: ::rustc_serialize::Decodable::decode(__decoder),
                    section: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };TyDecodable, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for
            PatchableFunctionEntry {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    PatchableFunctionEntry {
                        prefix: ref __binding_0,
                        entry: ref __binding_1,
                        section: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
149pub struct PatchableFunctionEntry {
150    /// Nops to prepend to the function
151    prefix: Option<u8>,
152    /// Nops after entry, but before body
153    entry: Option<u8>,
154    /// Optional, specific section to record entry location in
155    section: Option<Symbol>,
156}
157
158impl PatchableFunctionEntry {
159    pub fn from_prefix_entry_and_section(
160        prefix: Option<u8>,
161        entry: Option<u8>,
162        section: Option<Symbol>,
163    ) -> Self {
164        Self { prefix, entry, section }
165    }
166    pub fn from_prefix_and_entry(prefix: u8, entry: u8) -> Self {
167        Self { prefix: Some(prefix), entry: Some(entry), section: None }
168    }
169    pub fn prefix(&self) -> Option<u8> {
170        self.prefix
171    }
172    pub fn entry(&self) -> Option<u8> {
173        self.entry
174    }
175    pub fn section(&self) -> Option<Symbol> {
176        self.section
177    }
178}
179
180#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for CodegenFnAttrFlags { }
#[automatically_derived]
impl ::core::clone::Clone for CodegenFnAttrFlags {
    #[inline]
    fn clone(&self) -> CodegenFnAttrFlags {
        let _: ::core::clone::AssertParamIsClone<u32>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CodegenFnAttrFlags { }Copy, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for CodegenFnAttrFlags { }
#[automatically_derived]
impl ::core::cmp::PartialEq for CodegenFnAttrFlags {
    #[inline]
    fn eq(&self, other: &CodegenFnAttrFlags) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for CodegenFnAttrFlags {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<u32>;
    }
}Eq, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for CodegenFnAttrFlags {
            fn encode(&self, __encoder: &mut __E) {
                let CodegenFnAttrFlags(ref __binding_0) = *self;
                ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                    __encoder);
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for CodegenFnAttrFlags {
            fn decode(__decoder: &mut __D) -> Self {
                CodegenFnAttrFlags(::rustc_serialize::Decodable::decode(__decoder))
            }
        }
    };TyDecodable, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for
            CodegenFnAttrFlags {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    CodegenFnAttrFlags(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
181pub struct CodegenFnAttrFlags(u32);
182impl CodegenFnAttrFlags {
    #[doc =
    r" `#[cold]`: a hint to LLVM that this function, when called, is never on"]
    #[doc = r" the hot path."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const COLD: Self = Self::from_bits_retain(1 << 0);
    #[doc =
    r" `#[rustc_nounwind]`: An indicator that function will never unwind."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const NEVER_UNWIND: Self = Self::from_bits_retain(1 << 1);
    #[doc =
    r" `#[naked]`: an indicator to LLVM that no function prologue/epilogue"]
    #[doc = r" should be generated."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const NAKED: Self = Self::from_bits_retain(1 << 2);
    #[doc =
    r" `#[no_mangle]`: an indicator that the function's name should be the same"]
    #[doc = r" as its symbol."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const NO_MANGLE: Self = Self::from_bits_retain(1 << 3);
    #[doc =
    r" `#[rustc_std_internal_symbol]`: an indicator that this symbol is a"]
    #[doc =
    r#" "weird symbol" for the standard library in that it has slightly"#]
    #[doc = r" different linkage, visibility, and reachability rules."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const RUSTC_STD_INTERNAL_SYMBOL: Self =
        Self::from_bits_retain(1 << 4);
    #[doc =
    r" `#[thread_local]`: indicates a static is actually a thread local"]
    #[doc = r" piece of memory"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const THREAD_LOCAL: Self = Self::from_bits_retain(1 << 5);
    #[doc =
    r" `#[used(compiler)]`: indicates that LLVM can't eliminate this function (but the"]
    #[doc = r" linker can!)."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const USED_COMPILER: Self = Self::from_bits_retain(1 << 6);
    #[doc = r" `#[used(linker)]`:"]
    #[doc =
    r" indicates that neither LLVM nor the linker will eliminate this function."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const USED_LINKER: Self = Self::from_bits_retain(1 << 7);
    #[doc = r" `#[track_caller]`: allow access to the caller location"]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const TRACK_CALLER: Self = Self::from_bits_retain(1 << 8);
    #[doc =
    r" #[ffi_pure]: applies clang's `pure` attribute to a foreign function"]
    #[doc = r" declaration."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const FFI_PURE: Self = Self::from_bits_retain(1 << 9);
    #[doc =
    r" #[ffi_const]: applies clang's `const` attribute to a foreign function"]
    #[doc = r" declaration."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const FFI_CONST: Self = Self::from_bits_retain(1 << 10);
    #[doc =
    r" `#[rustc_allocator]`: a hint to LLVM that the pointer returned from this"]
    #[doc =
    r" function is never null and the function has no side effects other than allocating."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const ALLOCATOR: Self = Self::from_bits_retain(1 << 11);
    #[doc =
    r" `#[rustc_deallocator]`: a hint to LLVM that the function only deallocates memory."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const DEALLOCATOR: Self = Self::from_bits_retain(1 << 12);
    #[doc =
    r" `#[rustc_reallocator]`: a hint to LLVM that the function only reallocates memory."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const REALLOCATOR: Self = Self::from_bits_retain(1 << 13);
    #[doc =
    r" `#[rustc_allocator_zeroed]`: a hint to LLVM that the function only allocates zeroed memory."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const ALLOCATOR_ZEROED: Self = Self::from_bits_retain(1 << 14);
    #[doc =
    r" `#[no_builtins]`: indicates that disable implicit builtin knowledge of functions for the function."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const NO_BUILTINS: Self = Self::from_bits_retain(1 << 15);
    #[doc =
    r" Marks foreign items, to make `contains_extern_indicator` cheaper."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const FOREIGN_ITEM: Self = Self::from_bits_retain(1 << 16);
    #[doc =
    r" `#[rustc_offload_kernel]`: indicates that this is an offload kernel, an extra ptr arg will be added."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const OFFLOAD_KERNEL: Self = Self::from_bits_retain(1 << 17);
    #[doc =
    r" Externally implementable item symbols act a little like `RUSTC_STD_INTERNAL_SYMBOL`."]
    #[doc =
    r" When a crate declares an EII and dependencies expect the symbol to exist,"]
    #[doc =
    r" they will refer to this symbol name before a definition is given."]
    #[doc =
    r" As such, we must make sure these symbols really do exist in the final binary/library."]
    #[doc =
    r" This flag is put on both the implementations of EIIs and the foreign item they implement."]
    #[allow(deprecated, non_upper_case_globals,)]
    pub const EXTERNALLY_IMPLEMENTABLE_ITEM: Self =
        Self::from_bits_retain(1 << 18);
}
impl ::bitflags::Flags for CodegenFnAttrFlags {
    const FLAGS: &'static [::bitflags::Flag<CodegenFnAttrFlags>] =
        &[{

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("EXTERNALLY_IMPLEMENTABLE_ITEM",
                            CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM)
                    }];
    type Bits = u32;
    fn bits(&self) -> u32 { CodegenFnAttrFlags::bits(self) }
    fn from_bits_retain(bits: u32) -> CodegenFnAttrFlags {
        CodegenFnAttrFlags::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 :: iter_without_into_iter,)]
const _: () =
    {
        #[allow(dead_code, deprecated, unused_attributes)]
        impl CodegenFnAttrFlags {
            /// Get a flags value with all bits unset.
            #[inline]
            pub const fn empty() -> Self {
                Self(<u32 as ::bitflags::Bits>::EMPTY)
            }
            /// Get a flags value with all known bits set.
            #[inline]
            pub const fn all() -> Self {
                let mut truncated = <u32 as ::bitflags::Bits>::EMPTY;
                let mut i = 0;
                {
                    {
                        let flag =
                            <CodegenFnAttrFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <CodegenFnAttrFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <CodegenFnAttrFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <CodegenFnAttrFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <CodegenFnAttrFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <CodegenFnAttrFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <CodegenFnAttrFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <CodegenFnAttrFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <CodegenFnAttrFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <CodegenFnAttrFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <CodegenFnAttrFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <CodegenFnAttrFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <CodegenFnAttrFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <CodegenFnAttrFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <CodegenFnAttrFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <CodegenFnAttrFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <CodegenFnAttrFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <CodegenFnAttrFlags as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <CodegenFnAttrFlags 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) -> u32 { 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: u32)
                -> ::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: u32) -> Self {
                Self(bits & Self::all().0)
            }
            /// Convert from a bits value exactly.
            #[inline]
            pub const fn from_bits_retain(bits: u32) -> 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 == "COLD" {
                        return ::bitflags::__private::core::option::Option::Some(Self(CodegenFnAttrFlags::COLD.bits()));
                    }
                };
                ;
                {
                    if name == "NEVER_UNWIND" {
                        return ::bitflags::__private::core::option::Option::Some(Self(CodegenFnAttrFlags::NEVER_UNWIND.bits()));
                    }
                };
                ;
                {
                    if name == "NAKED" {
                        return ::bitflags::__private::core::option::Option::Some(Self(CodegenFnAttrFlags::NAKED.bits()));
                    }
                };
                ;
                {
                    if name == "NO_MANGLE" {
                        return ::bitflags::__private::core::option::Option::Some(Self(CodegenFnAttrFlags::NO_MANGLE.bits()));
                    }
                };
                ;
                {
                    if name == "RUSTC_STD_INTERNAL_SYMBOL" {
                        return ::bitflags::__private::core::option::Option::Some(Self(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL.bits()));
                    }
                };
                ;
                {
                    if name == "THREAD_LOCAL" {
                        return ::bitflags::__private::core::option::Option::Some(Self(CodegenFnAttrFlags::THREAD_LOCAL.bits()));
                    }
                };
                ;
                {
                    if name == "USED_COMPILER" {
                        return ::bitflags::__private::core::option::Option::Some(Self(CodegenFnAttrFlags::USED_COMPILER.bits()));
                    }
                };
                ;
                {
                    if name == "USED_LINKER" {
                        return ::bitflags::__private::core::option::Option::Some(Self(CodegenFnAttrFlags::USED_LINKER.bits()));
                    }
                };
                ;
                {
                    if name == "TRACK_CALLER" {
                        return ::bitflags::__private::core::option::Option::Some(Self(CodegenFnAttrFlags::TRACK_CALLER.bits()));
                    }
                };
                ;
                {
                    if name == "FFI_PURE" {
                        return ::bitflags::__private::core::option::Option::Some(Self(CodegenFnAttrFlags::FFI_PURE.bits()));
                    }
                };
                ;
                {
                    if name == "FFI_CONST" {
                        return ::bitflags::__private::core::option::Option::Some(Self(CodegenFnAttrFlags::FFI_CONST.bits()));
                    }
                };
                ;
                {
                    if name == "ALLOCATOR" {
                        return ::bitflags::__private::core::option::Option::Some(Self(CodegenFnAttrFlags::ALLOCATOR.bits()));
                    }
                };
                ;
                {
                    if name == "DEALLOCATOR" {
                        return ::bitflags::__private::core::option::Option::Some(Self(CodegenFnAttrFlags::DEALLOCATOR.bits()));
                    }
                };
                ;
                {
                    if name == "REALLOCATOR" {
                        return ::bitflags::__private::core::option::Option::Some(Self(CodegenFnAttrFlags::REALLOCATOR.bits()));
                    }
                };
                ;
                {
                    if name == "ALLOCATOR_ZEROED" {
                        return ::bitflags::__private::core::option::Option::Some(Self(CodegenFnAttrFlags::ALLOCATOR_ZEROED.bits()));
                    }
                };
                ;
                {
                    if name == "NO_BUILTINS" {
                        return ::bitflags::__private::core::option::Option::Some(Self(CodegenFnAttrFlags::NO_BUILTINS.bits()));
                    }
                };
                ;
                {
                    if name == "FOREIGN_ITEM" {
                        return ::bitflags::__private::core::option::Option::Some(Self(CodegenFnAttrFlags::FOREIGN_ITEM.bits()));
                    }
                };
                ;
                {
                    if name == "OFFLOAD_KERNEL" {
                        return ::bitflags::__private::core::option::Option::Some(Self(CodegenFnAttrFlags::OFFLOAD_KERNEL.bits()));
                    }
                };
                ;
                {
                    if name == "EXTERNALLY_IMPLEMENTABLE_ITEM" {
                        return ::bitflags::__private::core::option::Option::Some(Self(CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM.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 == <u32 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 != <u32 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 CodegenFnAttrFlags {
            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 CodegenFnAttrFlags {
            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 CodegenFnAttrFlags
            {
            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 CodegenFnAttrFlags
            {
            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 CodegenFnAttrFlags {
            type Output = Self;
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            fn bitor(self, other: CodegenFnAttrFlags) -> Self {
                self.union(other)
            }
        }
        impl ::bitflags::__private::core::ops::BitOrAssign for
            CodegenFnAttrFlags {
            /// 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 CodegenFnAttrFlags {
            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
            CodegenFnAttrFlags {
            /// 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 CodegenFnAttrFlags {
            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
            CodegenFnAttrFlags {
            /// 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 CodegenFnAttrFlags {
            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
            CodegenFnAttrFlags {
            /// 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 CodegenFnAttrFlags {
            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<CodegenFnAttrFlags> for
            CodegenFnAttrFlags {
            /// 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<CodegenFnAttrFlags>
            for CodegenFnAttrFlags {
            /// 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 CodegenFnAttrFlags {
            /// 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<CodegenFnAttrFlags> {
                ::bitflags::iter::Iter::__private_const_new(<CodegenFnAttrFlags
                        as ::bitflags::Flags>::FLAGS,
                    CodegenFnAttrFlags::from_bits_retain(self.bits()),
                    CodegenFnAttrFlags::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<CodegenFnAttrFlags> {
                ::bitflags::iter::IterNames::__private_const_new(<CodegenFnAttrFlags
                        as ::bitflags::Flags>::FLAGS,
                    CodegenFnAttrFlags::from_bits_retain(self.bits()),
                    CodegenFnAttrFlags::from_bits_retain(self.bits()))
            }
        }
        impl ::bitflags::__private::core::iter::IntoIterator for
            CodegenFnAttrFlags {
            type Item = CodegenFnAttrFlags;
            type IntoIter = ::bitflags::iter::Iter<CodegenFnAttrFlags>;
            fn into_iter(self) -> Self::IntoIter { self.iter() }
        }
    };bitflags::bitflags! {
183    impl CodegenFnAttrFlags: u32 {
184        /// `#[cold]`: a hint to LLVM that this function, when called, is never on
185        /// the hot path.
186        const COLD                      = 1 << 0;
187        /// `#[rustc_nounwind]`: An indicator that function will never unwind.
188        const NEVER_UNWIND              = 1 << 1;
189        /// `#[naked]`: an indicator to LLVM that no function prologue/epilogue
190        /// should be generated.
191        const NAKED                     = 1 << 2;
192        /// `#[no_mangle]`: an indicator that the function's name should be the same
193        /// as its symbol.
194        const NO_MANGLE                 = 1 << 3;
195        /// `#[rustc_std_internal_symbol]`: an indicator that this symbol is a
196        /// "weird symbol" for the standard library in that it has slightly
197        /// different linkage, visibility, and reachability rules.
198        const RUSTC_STD_INTERNAL_SYMBOL = 1 << 4;
199        /// `#[thread_local]`: indicates a static is actually a thread local
200        /// piece of memory
201        const THREAD_LOCAL              = 1 << 5;
202        /// `#[used(compiler)]`: indicates that LLVM can't eliminate this function (but the
203        /// linker can!).
204        const USED_COMPILER             = 1 << 6;
205        /// `#[used(linker)]`:
206        /// indicates that neither LLVM nor the linker will eliminate this function.
207        const USED_LINKER               = 1 << 7;
208        /// `#[track_caller]`: allow access to the caller location
209        const TRACK_CALLER              = 1 << 8;
210        /// #[ffi_pure]: applies clang's `pure` attribute to a foreign function
211        /// declaration.
212        const FFI_PURE                  = 1 << 9;
213        /// #[ffi_const]: applies clang's `const` attribute to a foreign function
214        /// declaration.
215        const FFI_CONST                 = 1 << 10;
216        /// `#[rustc_allocator]`: a hint to LLVM that the pointer returned from this
217        /// function is never null and the function has no side effects other than allocating.
218        const ALLOCATOR                 = 1 << 11;
219        /// `#[rustc_deallocator]`: a hint to LLVM that the function only deallocates memory.
220        const DEALLOCATOR               = 1 << 12;
221        /// `#[rustc_reallocator]`: a hint to LLVM that the function only reallocates memory.
222        const REALLOCATOR               = 1 << 13;
223        /// `#[rustc_allocator_zeroed]`: a hint to LLVM that the function only allocates zeroed memory.
224        const ALLOCATOR_ZEROED          = 1 << 14;
225        /// `#[no_builtins]`: indicates that disable implicit builtin knowledge of functions for the function.
226        const NO_BUILTINS               = 1 << 15;
227        /// Marks foreign items, to make `contains_extern_indicator` cheaper.
228        const FOREIGN_ITEM              = 1 << 16;
229        /// `#[rustc_offload_kernel]`: indicates that this is an offload kernel, an extra ptr arg will be added.
230        const OFFLOAD_KERNEL = 1 << 17;
231        /// Externally implementable item symbols act a little like `RUSTC_STD_INTERNAL_SYMBOL`.
232        /// When a crate declares an EII and dependencies expect the symbol to exist,
233        /// they will refer to this symbol name before a definition is given.
234        /// As such, we must make sure these symbols really do exist in the final binary/library.
235        /// This flag is put on both the implementations of EIIs and the foreign item they implement.
236        const EXTERNALLY_IMPLEMENTABLE_ITEM = 1 << 18;
237    }
238}
239impl ::std::fmt::Debug for CodegenFnAttrFlags {
    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        ::bitflags::parser::to_writer(self, f)
    }
}rustc_data_structures::external_bitflags_debug! { CodegenFnAttrFlags }
240
241impl CodegenFnAttrs {
242    pub const EMPTY: &'static Self = &Self::new();
243
244    pub const fn new() -> CodegenFnAttrs {
245        CodegenFnAttrs {
246            flags: CodegenFnAttrFlags::empty(),
247            inline: InlineAttr::None,
248            optimize: OptimizeAttr::Default,
249            symbol_name: None,
250            link_ordinal: None,
251            target_features: ::alloc::vec::Vec::new()vec![],
252            foreign_item_symbol_aliases: ::alloc::vec::Vec::new()vec![],
253            safe_target_features: false,
254            linkage: None,
255            import_linkage: None,
256            link_section: None,
257            sanitizers: SanitizerFnAttrs::default(),
258            instruction_set: None,
259            alignment: None,
260            patchable_function_entry: None,
261            objc_class: None,
262            objc_selector: None,
263            instrument_fn: None,
264        }
265    }
266
267    /// Returns `true` if it looks like this symbol needs to be exported, for example:
268    ///
269    /// * `#[no_mangle]` is present
270    /// * `#[export_name(...)]` is present
271    /// * `#[linkage]` is present
272    ///
273    /// Keep this in sync with the logic for the unused_attributes for `#[inline]` lint.
274    pub fn contains_extern_indicator(&self) -> bool {
275        if self.flags.contains(CodegenFnAttrFlags::FOREIGN_ITEM) {
276            return false;
277        }
278
279        self.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
280            || self.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
281            // note: for these we do also set a symbol name so technically also handled by the
282            // condition below. However, I think that regardless these should be treated as extern.
283            || self.flags.contains(CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM)
284            // `#[rustc_offload_kernel]`: this item is an externally-launched kernel entry point.
285            || self.flags.contains(CodegenFnAttrFlags::OFFLOAD_KERNEL)
286            || self.symbol_name.is_some()
287            || match self.linkage {
288                // These are private, so make sure we don't try to consider
289                // them external.
290                None | Some(Linkage::Internal) => false,
291                Some(_) => true,
292            }
293    }
294}
295
296#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for SanitizerFnAttrs { }
#[automatically_derived]
impl ::core::clone::Clone for SanitizerFnAttrs {
    #[inline]
    fn clone(&self) -> SanitizerFnAttrs {
        let _: ::core::clone::AssertParamIsClone<SanitizerSet>;
        let _: ::core::clone::AssertParamIsClone<RtsanSetting>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for SanitizerFnAttrs { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for SanitizerFnAttrs {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "SanitizerFnAttrs", "disabled", &self.disabled, "rtsan_setting",
            &&self.rtsan_setting)
    }
}Debug, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for
            SanitizerFnAttrs {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    SanitizerFnAttrs {
                        disabled: ref __binding_0, rtsan_setting: ref __binding_1 }
                        => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, const _: () =
    {
        impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
            ::rustc_serialize::Encodable<__E> for SanitizerFnAttrs {
            fn encode(&self, __encoder: &mut __E) {
                let SanitizerFnAttrs {
                        disabled: ref __binding_0, rtsan_setting: ref __binding_1
                        } = *self;
                ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                    __encoder);
            }
        }
    };TyEncodable, const _: () =
    {
        impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
            ::rustc_serialize::Decodable<__D> for SanitizerFnAttrs {
            fn decode(__decoder: &mut __D) -> Self {
                SanitizerFnAttrs {
                    disabled: ::rustc_serialize::Decodable::decode(__decoder),
                    rtsan_setting: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };TyDecodable, #[automatically_derived]
impl ::core::cmp::Eq for SanitizerFnAttrs {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<SanitizerSet>;
        let _: ::core::cmp::AssertParamIsEq<RtsanSetting>;
    }
}Eq, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for SanitizerFnAttrs { }
#[automatically_derived]
impl ::core::cmp::PartialEq for SanitizerFnAttrs {
    #[inline]
    fn eq(&self, other: &SanitizerFnAttrs) -> bool {
        self.disabled == other.disabled &&
            self.rtsan_setting == other.rtsan_setting
    }
}PartialEq)]
297pub struct SanitizerFnAttrs {
298    pub disabled: SanitizerSet,
299    pub rtsan_setting: RtsanSetting,
300}
301
302const impl Default for SanitizerFnAttrs {
303    fn default() -> Self {
304        Self { disabled: SanitizerSet::empty(), rtsan_setting: RtsanSetting::default() }
305    }
306}