1use std::borrow::Cow;
23use rustc_abi::Align;
4use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, Linkage, OptimizeAttr, RtsanSetting};
5use rustc_hir::def_id::DefId;
6use rustc_macros::{StableHash, TyDecodable, TyEncodable};
7use rustc_span::Symbol;
8use rustc_target::spec::SanitizerSet;
910use crate::mono::Visibility;
11use crate::ty::{InstanceKind, TyCtxt};
1213impl<'tcx> TyCtxt<'tcx> {
14pub fn codegen_instance_attrs(
15self,
16 instance_kind: InstanceKind<'_>,
17 ) -> Cow<'tcx, CodegenFnAttrs> {
18// NOTE: we try to not clone the `CodegenFnAttrs` when that is not needed.
19 // The `to_mut` method used below clones the inner value.
20let mut attrs = Cow::Borrowed(self.codegen_fn_attrs(instance_kind.def_id()));
2122// Drop the `#[naked]` attribute on non-item `InstanceKind`s, like the shims that
23 // are generated for indirect function calls.
24if !#[allow(non_exhaustive_omitted_patterns)] match instance_kind {
InstanceKind::Item(_) => true,
_ => false,
}matches!(instance_kind, InstanceKind::Item(_)) {
25if attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
26attrs.to_mut().flags.remove(CodegenFnAttrFlags::NAKED);
27 }
28 }
2930// A shim created by `#[track_caller]` should not inherit any attributes
31 // that modify the symbol name. Failing to remove these attributes from
32 // the shim leads to errors like `symbol `foo` is already defined`.
33 //
34 // A `ClosureOnceShim` with the track_caller attribute does not have a symbol,
35 // and therefore can be skipped here.
36if let InstanceKind::ReifyShim(_, _) = instance_kind37 && attrs.flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
38 {
39if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) {
40attrs.to_mut().flags.remove(CodegenFnAttrFlags::NO_MANGLE);
41 }
4243if attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
44attrs.to_mut().flags.remove(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL);
45 }
4647if attrs.flags.contains(CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM) {
48attrs.to_mut().flags.remove(CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM);
49 }
5051if attrs.symbol_name.is_some() {
52attrs.to_mut().symbol_name = None;
53 }
54 }
5556// Ensure closure shims have the optimization properties of their closure applied to them.
57if let InstanceKind::ClosureOnceShim { call_once: _, closure, track_caller: _ } =
58instance_kind59 {
60let closure_attrs = self.codegen_fn_attrs(closure);
61attrs.to_mut().optimize = closure_attrs.optimize;
62 }
6364attrs65 }
66}
6768#[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),
}
}
}Clone, const _: () =
{
impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
::rustc_serialize::Encodable<__E> for CodegenFnAttrs {
fn encode(&self, __encoder: &mut __E) {
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 } => {
::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);
}
}
}
}
};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),
}
}
}
};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 } => {
{ __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); }
}
}
}
}
};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"];
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];
::core::fmt::Formatter::debug_struct_fields_finish(f,
"CodegenFnAttrs", names, values)
}
}Debug)]
69pub struct CodegenFnAttrs {
70pub flags: CodegenFnAttrFlags,
71/// Parsed representation of the `#[inline]` attribute
72pub inline: InlineAttr,
73/// Parsed representation of the `#[optimize]` attribute
74pub optimize: OptimizeAttr,
75/// The name this function will be imported/exported under. This can be set
76 /// using the `#[export_name = "..."]` or `#[link_name = "..."]` attribute
77 /// depending on if this is a function definition or foreign function.
78pub symbol_name: Option<Symbol>,
79/// Defids of foreign items somewhere that this function should "satisfy".
80 /// i.e., if a foreign function has some symbol foo,
81 /// generate this function under its real name,
82 /// but *also* under the same name as this foreign function so that the foreign function has an implementation.
83// FIXME: make "SymbolName<'tcx>"
84pub foreign_item_symbol_aliases: Vec<(DefId, Linkage, Visibility)>,
85/// The `#[link_ordinal = "..."]` attribute, indicating an ordinal an
86 /// imported function has in the dynamic library. Note that this must not
87 /// be set when `link_name` is set. This is for foreign items with the
88 /// "raw-dylib" kind.
89pub link_ordinal: Option<u16>,
90/// The `#[target_feature(enable = "...")]` attribute and the enabled
91 /// features (only enabled features are supported right now).
92 /// Implied target features have already been applied.
93pub target_features: Vec<TargetFeature>,
94/// Whether the function was declared safe, but has target features
95pub safe_target_features: bool,
96/// The `#[linkage = "..."]` attribute on Rust-defined items and the value we found.
97pub linkage: Option<Linkage>,
98/// The `#[linkage = "..."]` attribute on foreign items and the value we found.
99pub import_linkage: Option<Linkage>,
100/// The `#[link_section = "..."]` attribute, or what executable section this
101 /// should be placed in.
102pub link_section: Option<Symbol>,
103/// The `#[sanitize(xyz = "off")]` attribute. Indicates the settings for each
104 /// sanitizer for this function.
105pub sanitizers: SanitizerFnAttrs,
106/// The `#[instruction_set(set)]` attribute. Indicates if the generated code should
107 /// be generated against a specific instruction set. Only usable on architectures which allow
108 /// switching between multiple instruction sets.
109pub instruction_set: Option<InstructionSetAttr>,
110/// The `#[align(...)]` attribute. Determines the alignment of the function body.
111// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
112pub alignment: Option<Align>,
113/// The `#[patchable_function_entry(...)]` attribute. Indicates how many nops should be around
114 /// the function entry.
115pub patchable_function_entry: Option<PatchableFunctionEntry>,
116/// The `#[rustc_objc_class = "..."]` attribute.
117pub objc_class: Option<Symbol>,
118/// The `#[rustc_objc_selector = "..."]` attribute.
119pub objc_selector: Option<Symbol>,
120}
121122#[derive(#[automatically_derived]
impl ::core::marker::Copy for TargetFeatureKind { }Copy, #[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);
match *self {
TargetFeatureKind::Implied => {}
TargetFeatureKind::Enabled => {}
TargetFeatureKind::Forced => {}
}
}
}
};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::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)]
123pub enum TargetFeatureKind {
124/// The feature is implied by another feature, rather than explicitly added by the
125 /// `#[target_feature]` attribute
126Implied,
127/// The feature is added by the regular `target_feature` attribute.
128Enabled,
129/// The feature is added by the unsafe `force_target_feature` attribute.
130Forced,
131}
132133#[derive(#[automatically_derived]
impl ::core::marker::Copy for TargetFeature { }Copy, #[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::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) {
match *self {
TargetFeature { name: ref __binding_0, kind: ref __binding_1
} => {
::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)]
134pub struct TargetFeature {
135/// The name of the target feature (e.g. "avx")
136pub name: Symbol,
137/// The way this feature was enabled.
138pub kind: TargetFeatureKind,
139}
140141#[derive(#[automatically_derived]
impl ::core::marker::Copy for PatchableFunctionEntry { }Copy, #[automatically_derived]
impl ::core::clone::Clone for PatchableFunctionEntry {
#[inline]
fn clone(&self) -> PatchableFunctionEntry {
let _: ::core::clone::AssertParamIsClone<u8>;
*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_field2_finish(f,
"PatchableFunctionEntry", "prefix", &self.prefix, "entry",
&&self.entry)
}
}Debug, const _: () =
{
impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
::rustc_serialize::Encodable<__E> for PatchableFunctionEntry {
fn encode(&self, __encoder: &mut __E) {
match *self {
PatchableFunctionEntry {
prefix: ref __binding_0, entry: ref __binding_1 } => {
::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 PatchableFunctionEntry {
fn decode(__decoder: &mut __D) -> Self {
PatchableFunctionEntry {
prefix: ::rustc_serialize::Decodable::decode(__decoder),
entry: ::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 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash)]
142pub struct PatchableFunctionEntry {
143/// Nops to prepend to the function
144prefix: u8,
145/// Nops after entry, but before body
146entry: u8,
147}
148149impl PatchableFunctionEntry {
150pub fn from_config(config: rustc_session::config::PatchableFunctionEntry) -> Self {
151Self { prefix: config.prefix(), entry: config.entry() }
152 }
153pub fn from_prefix_and_entry(prefix: u8, entry: u8) -> Self {
154Self { prefix, entry }
155 }
156pub fn prefix(&self) -> u8 {
157self.prefix
158 }
159pub fn entry(&self) -> u8 {
160self.entry
161 }
162}
163164#[derive(#[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::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) {
match *self {
CodegenFnAttrFlags(ref __binding_0) => {
::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)]
165pub struct CodegenFnAttrFlags(u32);
166impl 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! {
167impl CodegenFnAttrFlags: u32 {
168/// `#[cold]`: a hint to LLVM that this function, when called, is never on
169 /// the hot path.
170const COLD = 1 << 0;
171/// `#[rustc_nounwind]`: An indicator that function will never unwind.
172const NEVER_UNWIND = 1 << 1;
173/// `#[naked]`: an indicator to LLVM that no function prologue/epilogue
174 /// should be generated.
175const NAKED = 1 << 2;
176/// `#[no_mangle]`: an indicator that the function's name should be the same
177 /// as its symbol.
178const NO_MANGLE = 1 << 3;
179/// `#[rustc_std_internal_symbol]`: an indicator that this symbol is a
180 /// "weird symbol" for the standard library in that it has slightly
181 /// different linkage, visibility, and reachability rules.
182const RUSTC_STD_INTERNAL_SYMBOL = 1 << 4;
183/// `#[thread_local]`: indicates a static is actually a thread local
184 /// piece of memory
185const THREAD_LOCAL = 1 << 5;
186/// `#[used(compiler)]`: indicates that LLVM can't eliminate this function (but the
187 /// linker can!).
188const USED_COMPILER = 1 << 6;
189/// `#[used(linker)]`:
190 /// indicates that neither LLVM nor the linker will eliminate this function.
191const USED_LINKER = 1 << 7;
192/// `#[track_caller]`: allow access to the caller location
193const TRACK_CALLER = 1 << 8;
194/// #[ffi_pure]: applies clang's `pure` attribute to a foreign function
195 /// declaration.
196const FFI_PURE = 1 << 9;
197/// #[ffi_const]: applies clang's `const` attribute to a foreign function
198 /// declaration.
199const FFI_CONST = 1 << 10;
200/// `#[rustc_allocator]`: a hint to LLVM that the pointer returned from this
201 /// function is never null and the function has no side effects other than allocating.
202const ALLOCATOR = 1 << 11;
203/// `#[rustc_deallocator]`: a hint to LLVM that the function only deallocates memory.
204const DEALLOCATOR = 1 << 12;
205/// `#[rustc_reallocator]`: a hint to LLVM that the function only reallocates memory.
206const REALLOCATOR = 1 << 13;
207/// `#[rustc_allocator_zeroed]`: a hint to LLVM that the function only allocates zeroed memory.
208const ALLOCATOR_ZEROED = 1 << 14;
209/// `#[no_builtins]`: indicates that disable implicit builtin knowledge of functions for the function.
210const NO_BUILTINS = 1 << 15;
211/// Marks foreign items, to make `contains_extern_indicator` cheaper.
212const FOREIGN_ITEM = 1 << 16;
213/// `#[rustc_offload_kernel]`: indicates that this is an offload kernel, an extra ptr arg will be added.
214const OFFLOAD_KERNEL = 1 << 17;
215/// Externally implementable item symbols act a little like `RUSTC_STD_INTERNAL_SYMBOL`.
216 /// When a crate declares an EII and dependencies expect the symbol to exist,
217 /// they will refer to this symbol name before a definition is given.
218 /// As such, we must make sure these symbols really do exist in the final binary/library.
219 /// This flag is put on both the implementations of EIIs and the foreign item they implement.
220const EXTERNALLY_IMPLEMENTABLE_ITEM = 1 << 18;
221 }
222}223impl ::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 }224225impl CodegenFnAttrs {
226pub const EMPTY: &'static Self = &Self::new();
227228pub const fn new() -> CodegenFnAttrs {
229CodegenFnAttrs {
230 flags: CodegenFnAttrFlags::empty(),
231 inline: InlineAttr::None,
232 optimize: OptimizeAttr::Default,
233 symbol_name: None,
234 link_ordinal: None,
235 target_features: ::alloc::vec::Vec::new()vec![],
236 foreign_item_symbol_aliases: ::alloc::vec::Vec::new()vec![],
237 safe_target_features: false,
238 linkage: None,
239 import_linkage: None,
240 link_section: None,
241 sanitizers: SanitizerFnAttrs::default(),
242 instruction_set: None,
243 alignment: None,
244 patchable_function_entry: None,
245 objc_class: None,
246 objc_selector: None,
247 }
248 }
249250/// Returns `true` if it looks like this symbol needs to be exported, for example:
251 ///
252 /// * `#[no_mangle]` is present
253 /// * `#[export_name(...)]` is present
254 /// * `#[linkage]` is present
255 ///
256 /// Keep this in sync with the logic for the unused_attributes for `#[inline]` lint.
257pub fn contains_extern_indicator(&self) -> bool {
258if self.flags.contains(CodegenFnAttrFlags::FOREIGN_ITEM) {
259return false;
260 }
261262self.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
263 || self.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
264// note: for these we do also set a symbol name so technically also handled by the
265 // condition below. However, I think that regardless these should be treated as extern.
266|| self.flags.contains(CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM)
267 || self.symbol_name.is_some()
268 || match self.linkage {
269// These are private, so make sure we don't try to consider
270 // them external.
271None | Some(Linkage::Internal) => false,
272Some(_) => true,
273 }
274 }
275}
276277#[derive(#[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) {
match *self {
SanitizerFnAttrs {
disabled: ref __binding_0, rtsan_setting: ref __binding_1 }
=> {
::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::cmp::PartialEq for SanitizerFnAttrs {
#[inline]
fn eq(&self, other: &SanitizerFnAttrs) -> bool {
self.disabled == other.disabled &&
self.rtsan_setting == other.rtsan_setting
}
}PartialEq)]
278pub struct SanitizerFnAttrs {
279pub disabled: SanitizerSet,
280pub rtsan_setting: RtsanSetting,
281}
282283const impl Defaultfor SanitizerFnAttrs {
284fn default() -> Self {
285Self { disabled: SanitizerSet::empty(), rtsan_setting: RtsanSetting::default() }
286 }
287}