rustc_ast/attr/
data_structures.rs

1use std::fmt;
2
3use rustc_macros::{Decodable, Encodable, HashStable_Generic};
4use rustc_span::{Span, Symbol};
5use thin_vec::ThinVec;
6
7use crate::attr::version::RustcVersion;
8
9#[derive(const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for CfgEntry {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        CfgEntry::All(ref __binding_0, ref __binding_1) => {
                            0usize
                        }
                        CfgEntry::Any(ref __binding_0, ref __binding_1) => {
                            1usize
                        }
                        CfgEntry::Not(ref __binding_0, ref __binding_1) => {
                            2usize
                        }
                        CfgEntry::Bool(ref __binding_0, ref __binding_1) => {
                            3usize
                        }
                        CfgEntry::NameValue {
                            name: ref __binding_0,
                            value: ref __binding_1,
                            span: ref __binding_2 } => {
                            4usize
                        }
                        CfgEntry::Version(ref __binding_0, ref __binding_1) => {
                            5usize
                        }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    CfgEntry::All(ref __binding_0, ref __binding_1) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                    CfgEntry::Any(ref __binding_0, ref __binding_1) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                    CfgEntry::Not(ref __binding_0, ref __binding_1) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                    CfgEntry::Bool(ref __binding_0, ref __binding_1) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                    CfgEntry::NameValue {
                        name: ref __binding_0,
                        value: ref __binding_1,
                        span: ref __binding_2 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                            __encoder);
                    }
                    CfgEntry::Version(ref __binding_0, ref __binding_1) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for CfgEntry {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        CfgEntry::All(::rustc_serialize::Decodable::decode(__decoder),
                            ::rustc_serialize::Decodable::decode(__decoder))
                    }
                    1usize => {
                        CfgEntry::Any(::rustc_serialize::Decodable::decode(__decoder),
                            ::rustc_serialize::Decodable::decode(__decoder))
                    }
                    2usize => {
                        CfgEntry::Not(::rustc_serialize::Decodable::decode(__decoder),
                            ::rustc_serialize::Decodable::decode(__decoder))
                    }
                    3usize => {
                        CfgEntry::Bool(::rustc_serialize::Decodable::decode(__decoder),
                            ::rustc_serialize::Decodable::decode(__decoder))
                    }
                    4usize => {
                        CfgEntry::NameValue {
                            name: ::rustc_serialize::Decodable::decode(__decoder),
                            value: ::rustc_serialize::Decodable::decode(__decoder),
                            span: ::rustc_serialize::Decodable::decode(__decoder),
                        }
                    }
                    5usize => {
                        CfgEntry::Version(::rustc_serialize::Decodable::decode(__decoder),
                            ::rustc_serialize::Decodable::decode(__decoder))
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `CfgEntry`, expected 0..6, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable, #[automatically_derived]
impl ::core::clone::Clone for CfgEntry {
    #[inline]
    fn clone(&self) -> CfgEntry {
        match self {
            CfgEntry::All(__self_0, __self_1) =>
                CfgEntry::All(::core::clone::Clone::clone(__self_0),
                    ::core::clone::Clone::clone(__self_1)),
            CfgEntry::Any(__self_0, __self_1) =>
                CfgEntry::Any(::core::clone::Clone::clone(__self_0),
                    ::core::clone::Clone::clone(__self_1)),
            CfgEntry::Not(__self_0, __self_1) =>
                CfgEntry::Not(::core::clone::Clone::clone(__self_0),
                    ::core::clone::Clone::clone(__self_1)),
            CfgEntry::Bool(__self_0, __self_1) =>
                CfgEntry::Bool(::core::clone::Clone::clone(__self_0),
                    ::core::clone::Clone::clone(__self_1)),
            CfgEntry::NameValue {
                name: __self_0, value: __self_1, span: __self_2 } =>
                CfgEntry::NameValue {
                    name: ::core::clone::Clone::clone(__self_0),
                    value: ::core::clone::Clone::clone(__self_1),
                    span: ::core::clone::Clone::clone(__self_2),
                },
            CfgEntry::Version(__self_0, __self_1) =>
                CfgEntry::Version(::core::clone::Clone::clone(__self_0),
                    ::core::clone::Clone::clone(__self_1)),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for CfgEntry {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            CfgEntry::All(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f, "All",
                    __self_0, &__self_1),
            CfgEntry::Any(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f, "Any",
                    __self_0, &__self_1),
            CfgEntry::Not(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f, "Not",
                    __self_0, &__self_1),
            CfgEntry::Bool(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f, "Bool",
                    __self_0, &__self_1),
            CfgEntry::NameValue {
                name: __self_0, value: __self_1, span: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "NameValue", "name", __self_0, "value", __self_1, "span",
                    &__self_2),
            CfgEntry::Version(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f,
                    "Version", __self_0, &__self_1),
        }
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for CfgEntry {
    #[inline]
    fn eq(&self, other: &CfgEntry) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (CfgEntry::All(__self_0, __self_1),
                    CfgEntry::All(__arg1_0, __arg1_1)) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                (CfgEntry::Any(__self_0, __self_1),
                    CfgEntry::Any(__arg1_0, __arg1_1)) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                (CfgEntry::Not(__self_0, __self_1),
                    CfgEntry::Not(__arg1_0, __arg1_1)) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                (CfgEntry::Bool(__self_0, __self_1),
                    CfgEntry::Bool(__arg1_0, __arg1_1)) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                (CfgEntry::NameValue {
                    name: __self_0, value: __self_1, span: __self_2 },
                    CfgEntry::NameValue {
                    name: __arg1_0, value: __arg1_1, span: __arg1_2 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1 &&
                        __self_2 == __arg1_2,
                (CfgEntry::Version(__self_0, __self_1),
                    CfgEntry::Version(__arg1_0, __arg1_1)) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for CfgEntry {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) -> () {
        let _: ::core::cmp::AssertParamIsEq<ThinVec<CfgEntry>>;
        let _: ::core::cmp::AssertParamIsEq<Span>;
        let _: ::core::cmp::AssertParamIsEq<ThinVec<CfgEntry>>;
        let _: ::core::cmp::AssertParamIsEq<Box<CfgEntry>>;
        let _: ::core::cmp::AssertParamIsEq<bool>;
        let _: ::core::cmp::AssertParamIsEq<Symbol>;
        let _: ::core::cmp::AssertParamIsEq<Option<Symbol>>;
        let _: ::core::cmp::AssertParamIsEq<Option<RustcVersion>>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for CfgEntry {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            CfgEntry::All(__self_0, __self_1) => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state)
            }
            CfgEntry::Any(__self_0, __self_1) => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state)
            }
            CfgEntry::Not(__self_0, __self_1) => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state)
            }
            CfgEntry::Bool(__self_0, __self_1) => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state)
            }
            CfgEntry::NameValue {
                name: __self_0, value: __self_1, span: __self_2 } => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state);
                ::core::hash::Hash::hash(__self_2, state)
            }
            CfgEntry::Version(__self_0, __self_1) => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state)
            }
        }
    }
}Hash, const _: () =
    {
        impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            for CfgEntry where __CTX: crate::HashStableContext {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                ::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
                match *self {
                    CfgEntry::All(ref __binding_0, ref __binding_1) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    CfgEntry::Any(ref __binding_0, ref __binding_1) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    CfgEntry::Not(ref __binding_0, ref __binding_1) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    CfgEntry::Bool(ref __binding_0, ref __binding_1) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    CfgEntry::NameValue {
                        name: ref __binding_0,
                        value: ref __binding_1,
                        span: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                    CfgEntry::Version(ref __binding_0, ref __binding_1) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_Generic)]
10pub enum CfgEntry {
11    All(ThinVec<CfgEntry>, Span),
12    Any(ThinVec<CfgEntry>, Span),
13    Not(Box<CfgEntry>, Span),
14    Bool(bool, Span),
15    NameValue { name: Symbol, value: Option<Symbol>, span: Span },
16    Version(Option<RustcVersion>, Span),
17}
18
19impl CfgEntry {
20    pub fn lower_spans(&mut self, lower_span: impl Copy + Fn(Span) -> Span) {
21        match self {
22            CfgEntry::All(subs, span) | CfgEntry::Any(subs, span) => {
23                *span = lower_span(*span);
24                subs.iter_mut().for_each(|sub| sub.lower_spans(lower_span));
25            }
26            CfgEntry::Not(sub, span) => {
27                *span = lower_span(*span);
28                sub.lower_spans(lower_span);
29            }
30            CfgEntry::Bool(_, span)
31            | CfgEntry::NameValue { span, .. }
32            | CfgEntry::Version(_, span) => {
33                *span = lower_span(*span);
34            }
35        }
36    }
37
38    pub fn span(&self) -> Span {
39        let (Self::All(_, span)
40        | Self::Any(_, span)
41        | Self::Not(_, span)
42        | Self::Bool(_, span)
43        | Self::NameValue { span, .. }
44        | Self::Version(_, span)) = self;
45        *span
46    }
47
48    /// Same as `PartialEq` but doesn't check spans and ignore order of cfgs.
49    pub fn is_equivalent_to(&self, other: &Self) -> bool {
50        match (self, other) {
51            (Self::All(a, _), Self::All(b, _)) | (Self::Any(a, _), Self::Any(b, _)) => {
52                a.len() == b.len() && a.iter().all(|a| b.iter().any(|b| a.is_equivalent_to(b)))
53            }
54            (Self::Not(a, _), Self::Not(b, _)) => a.is_equivalent_to(b),
55            (Self::Bool(a, _), Self::Bool(b, _)) => a == b,
56            (
57                Self::NameValue { name: name1, value: value1, .. },
58                Self::NameValue { name: name2, value: value2, .. },
59            ) => name1 == name2 && value1 == value2,
60            (Self::Version(a, _), Self::Version(b, _)) => a == b,
61            _ => false,
62        }
63    }
64}
65
66impl fmt::Display for CfgEntry {
67    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68        fn write_entries(
69            name: &str,
70            entries: &[CfgEntry],
71            f: &mut fmt::Formatter<'_>,
72        ) -> fmt::Result {
73            f.write_fmt(format_args!("{0}(", name))write!(f, "{name}(")?;
74            for (nb, entry) in entries.iter().enumerate() {
75                if nb != 0 {
76                    f.write_str(", ")?;
77                }
78                entry.fmt(f)?;
79            }
80            f.write_str(")")
81        }
82        match self {
83            Self::All(entries, _) => write_entries("all", entries, f),
84            Self::Any(entries, _) => write_entries("any", entries, f),
85            Self::Not(entry, _) => f.write_fmt(format_args!("not({0})", entry))write!(f, "not({entry})"),
86            Self::Bool(value, _) => f.write_fmt(format_args!("{0}", value))write!(f, "{value}"),
87            Self::NameValue { name, value, .. } => {
88                match value {
89                    // We use `as_str` and debug display to have characters escaped and `"`
90                    // characters surrounding the string.
91                    Some(value) => f.write_fmt(format_args!("{1} = {0:?}", value.as_str(), name))write!(f, "{name} = {:?}", value.as_str()),
92                    None => f.write_fmt(format_args!("{0}", name))write!(f, "{name}"),
93                }
94            }
95            Self::Version(version, _) => match version {
96                Some(version) => f.write_fmt(format_args!("{0}", version))write!(f, "{version}"),
97                None => Ok(()),
98            },
99        }
100    }
101}