Skip to main content

rustc_hir/attrs/
diagnostic.rs

1//! Contains the data structures used by the diagnostic attribute family.
2use std::fmt;
3use std::fmt::Debug;
4
5pub use rustc_ast::attr::data_structures::*;
6use rustc_macros::{Decodable, Encodable, HashStable_Generic, PrintAttribute};
7use rustc_span::{DesugaringKind, Span, Symbol, kw};
8use thin_vec::ThinVec;
9use tracing::{debug, info};
10
11use crate::attrs::PrintAttribute;
12
13#[derive(#[automatically_derived]
impl ::core::clone::Clone for Directive {
    #[inline]
    fn clone(&self) -> Directive {
        Directive {
            is_rustc_attr: ::core::clone::Clone::clone(&self.is_rustc_attr),
            condition: ::core::clone::Clone::clone(&self.condition),
            subcommands: ::core::clone::Clone::clone(&self.subcommands),
            message: ::core::clone::Clone::clone(&self.message),
            label: ::core::clone::Clone::clone(&self.label),
            notes: ::core::clone::Clone::clone(&self.notes),
            parent_label: ::core::clone::Clone::clone(&self.parent_label),
            append_const_msg: ::core::clone::Clone::clone(&self.append_const_msg),
        }
    }
}Clone, #[automatically_derived]
impl ::core::default::Default for Directive {
    #[inline]
    fn default() -> Directive {
        Directive {
            is_rustc_attr: ::core::default::Default::default(),
            condition: ::core::default::Default::default(),
            subcommands: ::core::default::Default::default(),
            message: ::core::default::Default::default(),
            label: ::core::default::Default::default(),
            notes: ::core::default::Default::default(),
            parent_label: ::core::default::Default::default(),
            append_const_msg: ::core::default::Default::default(),
        }
    }
}Default, #[automatically_derived]
impl ::core::fmt::Debug for Directive {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["is_rustc_attr", "condition", "subcommands", "message", "label",
                        "notes", "parent_label", "append_const_msg"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.is_rustc_attr, &self.condition, &self.subcommands,
                        &self.message, &self.label, &self.notes, &self.parent_label,
                        &&self.append_const_msg];
        ::core::fmt::Formatter::debug_struct_fields_finish(f, "Directive",
            names, values)
    }
}Debug, const _: () =
    {
        impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            for Directive where __CTX: crate::HashStableContext {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    Directive {
                        is_rustc_attr: ref __binding_0,
                        condition: ref __binding_1,
                        subcommands: ref __binding_2,
                        message: ref __binding_3,
                        label: ref __binding_4,
                        notes: ref __binding_5,
                        parent_label: ref __binding_6,
                        append_const_msg: ref __binding_7 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                        { __binding_3.hash_stable(__hcx, __hasher); }
                        { __binding_4.hash_stable(__hcx, __hasher); }
                        { __binding_5.hash_stable(__hcx, __hasher); }
                        { __binding_6.hash_stable(__hcx, __hasher); }
                        { __binding_7.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_Generic, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for Directive {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    Directive {
                        is_rustc_attr: ref __binding_0,
                        condition: ref __binding_1,
                        subcommands: ref __binding_2,
                        message: ref __binding_3,
                        label: ref __binding_4,
                        notes: ref __binding_5,
                        parent_label: ref __binding_6,
                        append_const_msg: ref __binding_7 } => {
                        ::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);
                    }
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for Directive {
            fn decode(__decoder: &mut __D) -> Self {
                Directive {
                    is_rustc_attr: ::rustc_serialize::Decodable::decode(__decoder),
                    condition: ::rustc_serialize::Decodable::decode(__decoder),
                    subcommands: ::rustc_serialize::Decodable::decode(__decoder),
                    message: ::rustc_serialize::Decodable::decode(__decoder),
                    label: ::rustc_serialize::Decodable::decode(__decoder),
                    notes: ::rustc_serialize::Decodable::decode(__decoder),
                    parent_label: ::rustc_serialize::Decodable::decode(__decoder),
                    append_const_msg: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable, const _: () =
    {
        #[allow(unused)]
        impl PrintAttribute for Directive {
            fn should_render(&self) -> bool { true }
            fn print_attribute(&self,
                __p: &mut rustc_ast_pretty::pp::Printer) {
                let Self {
                        is_rustc_attr,
                        condition,
                        subcommands,
                        message,
                        label,
                        notes,
                        parent_label,
                        append_const_msg } = self;
                __p.word("Directive");
                if true && !is_rustc_attr.should_render() &&
                                                !condition.should_render() && !subcommands.should_render()
                                        && !message.should_render() && !label.should_render() &&
                                !notes.should_render() && !parent_label.should_render() &&
                        !append_const_msg.should_render() {
                    return;
                }
                __p.nbsp();
                __p.word("{");
                let mut __printed_anything = false;
                if is_rustc_attr.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("is_rustc_attr");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                is_rustc_attr.print_attribute(__p);
                if condition.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("condition");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                condition.print_attribute(__p);
                if subcommands.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("subcommands");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                subcommands.print_attribute(__p);
                if message.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("message");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                message.print_attribute(__p);
                if label.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("label");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                label.print_attribute(__p);
                if notes.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("notes");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                notes.print_attribute(__p);
                if parent_label.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("parent_label");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                parent_label.print_attribute(__p);
                if append_const_msg.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("append_const_msg");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                append_const_msg.print_attribute(__p);
                __p.word("}");
            }
        }
    };PrintAttribute)]
14pub struct Directive {
15    pub is_rustc_attr: bool,
16    pub condition: Option<OnUnimplementedCondition>,
17    pub subcommands: ThinVec<Directive>,
18    pub message: Option<(Span, FormatString)>,
19    pub label: Option<(Span, FormatString)>,
20    pub notes: ThinVec<FormatString>,
21    pub parent_label: Option<FormatString>,
22    pub append_const_msg: Option<AppendConstMessage>,
23}
24
25impl Directive {
26    /// Visit all the generic arguments used in the attribute, to see whether they are actually a
27    /// generic of the item. If not then `visit` must issue a diagnostic.
28    ///
29    /// We can't check this while parsing the attribute because `rustc_attr_parsing` doesn't have
30    /// access to the item an attribute is on. Instead we later call this function in `check_attr`.
31    pub fn visit_params(&self, visit: &mut impl FnMut(Symbol, Span)) {
32        if let Some(condition) = &self.condition {
33            condition.visit_params(visit);
34        }
35
36        for subcommand in &self.subcommands {
37            subcommand.visit_params(visit);
38        }
39
40        if let Some((_, message)) = &self.message {
41            message.visit_params(visit);
42        }
43        if let Some((_, label)) = &self.label {
44            label.visit_params(visit);
45        }
46
47        for note in &self.notes {
48            note.visit_params(visit);
49        }
50
51        if let Some(parent_label) = &self.parent_label {
52            parent_label.visit_params(visit);
53        }
54    }
55
56    pub fn evaluate_directive(
57        &self,
58        trait_name: impl Debug,
59        condition_options: &ConditionOptions,
60        args: &FormatArgs,
61    ) -> OnUnimplementedNote {
62        let mut message = None;
63        let mut label = None;
64        let mut notes = Vec::new();
65        let mut parent_label = None;
66        let mut append_const_msg = None;
67        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir/src/attrs/diagnostic.rs:67",
                        "rustc_hir::attrs::diagnostic", ::tracing::Level::INFO,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir/src/attrs/diagnostic.rs"),
                        ::tracing_core::__macro_support::Option::Some(67u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir::attrs::diagnostic"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::INFO <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::INFO <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("evaluate_directive({0:?}, trait_ref={1:?}, options={2:?}, args ={3:?})",
                                                    self, trait_name, condition_options, args) as &dyn Value))])
            });
    } else { ; }
};info!(
68            "evaluate_directive({:?}, trait_ref={:?}, options={:?}, args ={:?})",
69            self, trait_name, condition_options, args
70        );
71
72        for command in self.subcommands.iter().chain(Some(self)).rev() {
73            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir/src/attrs/diagnostic.rs:73",
                        "rustc_hir::attrs::diagnostic", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir/src/attrs/diagnostic.rs"),
                        ::tracing_core::__macro_support::Option::Some(73u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir::attrs::diagnostic"),
                        ::tracing_core::field::FieldSet::new(&["command"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&command) as
                                            &dyn Value))])
            });
    } else { ; }
};debug!(?command);
74            if let Some(ref condition) = command.condition
75                && !condition.matches_predicate(condition_options)
76            {
77                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir/src/attrs/diagnostic.rs:77",
                        "rustc_hir::attrs::diagnostic", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir/src/attrs/diagnostic.rs"),
                        ::tracing_core::__macro_support::Option::Some(77u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir::attrs::diagnostic"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("evaluate_directive: skipping {0:?} due to condition",
                                                    command) as &dyn Value))])
            });
    } else { ; }
};debug!("evaluate_directive: skipping {:?} due to condition", command);
78                continue;
79            }
80            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_hir/src/attrs/diagnostic.rs:80",
                        "rustc_hir::attrs::diagnostic", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_hir/src/attrs/diagnostic.rs"),
                        ::tracing_core::__macro_support::Option::Some(80u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_hir::attrs::diagnostic"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("evaluate_directive: {0:?} succeeded",
                                                    command) as &dyn Value))])
            });
    } else { ; }
};debug!("evaluate_directive: {:?} succeeded", command);
81            if let Some(ref message_) = command.message {
82                message = Some(message_.clone());
83            }
84
85            if let Some(ref label_) = command.label {
86                label = Some(label_.clone());
87            }
88
89            notes.extend(command.notes.clone());
90
91            if let Some(ref parent_label_) = command.parent_label {
92                parent_label = Some(parent_label_.clone());
93            }
94
95            append_const_msg = command.append_const_msg;
96        }
97
98        OnUnimplementedNote {
99            label: label.map(|l| l.1.format(args)),
100            message: message.map(|m| m.1.format(args)),
101            notes: notes.into_iter().map(|n| n.format(args)).collect(),
102            parent_label: parent_label.map(|e_s| e_s.format(args)),
103            append_const_msg,
104        }
105    }
106}
107
108#[derive(#[automatically_derived]
impl ::core::default::Default for OnUnimplementedNote {
    #[inline]
    fn default() -> OnUnimplementedNote {
        OnUnimplementedNote {
            message: ::core::default::Default::default(),
            label: ::core::default::Default::default(),
            notes: ::core::default::Default::default(),
            parent_label: ::core::default::Default::default(),
            append_const_msg: ::core::default::Default::default(),
        }
    }
}Default, #[automatically_derived]
impl ::core::fmt::Debug for OnUnimplementedNote {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field5_finish(f,
            "OnUnimplementedNote", "message", &self.message, "label",
            &self.label, "notes", &self.notes, "parent_label",
            &self.parent_label, "append_const_msg", &&self.append_const_msg)
    }
}Debug)]
109pub struct OnUnimplementedNote {
110    pub message: Option<String>,
111    pub label: Option<String>,
112    pub notes: Vec<String>,
113    pub parent_label: Option<String>,
114    // If none, should fall back to a generic message
115    pub append_const_msg: Option<AppendConstMessage>,
116}
117
118/// Append a message for `[const] Trait` errors.
119#[derive(#[automatically_derived]
impl ::core::clone::Clone for AppendConstMessage {
    #[inline]
    fn clone(&self) -> AppendConstMessage {
        let _: ::core::clone::AssertParamIsClone<Symbol>;
        let _: ::core::clone::AssertParamIsClone<Span>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for AppendConstMessage { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for AppendConstMessage {
    #[inline]
    fn eq(&self, other: &AppendConstMessage) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (AppendConstMessage::Custom(__self_0, __self_1),
                    AppendConstMessage::Custom(__arg1_0, __arg1_1)) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for AppendConstMessage {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Symbol>;
        let _: ::core::cmp::AssertParamIsEq<Span>;
    }
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for AppendConstMessage {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            AppendConstMessage::Default =>
                ::core::fmt::Formatter::write_str(f, "Default"),
            AppendConstMessage::Custom(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f, "Custom",
                    __self_0, &__self_1),
        }
    }
}Debug, #[automatically_derived]
impl ::core::default::Default for AppendConstMessage {
    #[inline]
    fn default() -> AppendConstMessage { Self::Default }
}Default)]
120#[derive(const _: () =
    {
        impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            for AppendConstMessage 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 {
                    AppendConstMessage::Default => {}
                    AppendConstMessage::Custom(ref __binding_0, ref __binding_1)
                        => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_Generic, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for AppendConstMessage {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        AppendConstMessage::Default => { 0usize }
                        AppendConstMessage::Custom(ref __binding_0, ref __binding_1)
                            => {
                            1usize
                        }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    AppendConstMessage::Default => {}
                    AppendConstMessage::Custom(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 AppendConstMessage {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { AppendConstMessage::Default }
                    1usize => {
                        AppendConstMessage::Custom(::rustc_serialize::Decodable::decode(__decoder),
                            ::rustc_serialize::Decodable::decode(__decoder))
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `AppendConstMessage`, expected 0..2, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable, const _: () =
    {
        #[allow(unused)]
        impl PrintAttribute for AppendConstMessage {
            fn should_render(&self) -> bool { true }
            fn print_attribute(&self,
                __p: &mut rustc_ast_pretty::pp::Printer) {
                match self {
                    Self::Default => { __p.word("Default") }
                    Self::Custom(f0, f1) => {
                        __p.word("Custom");
                        if true && !f0.should_render() && !f1.should_render() {
                            return;
                        }
                        __p.popen();
                        let mut __printed_anything = false;
                        if f0.should_render() {
                            if __printed_anything { __p.word_space(","); }
                            __printed_anything = true;
                        }
                        f0.print_attribute(__p);
                        if f1.should_render() {
                            if __printed_anything { __p.word_space(","); }
                            __printed_anything = true;
                        }
                        f1.print_attribute(__p);
                        __p.pclose();
                    }
                }
            }
        }
    };PrintAttribute)]
121pub enum AppendConstMessage {
122    #[default]
123    Default,
124    Custom(Symbol, Span),
125}
126
127/// Like [std::fmt::Arguments] this is a string that has been parsed into "pieces",
128/// either as string pieces or dynamic arguments.
129#[derive(#[automatically_derived]
impl ::core::clone::Clone for FormatString {
    #[inline]
    fn clone(&self) -> FormatString {
        FormatString {
            input: ::core::clone::Clone::clone(&self.input),
            span: ::core::clone::Clone::clone(&self.span),
            pieces: ::core::clone::Clone::clone(&self.pieces),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for FormatString {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "FormatString",
            "input", &self.input, "span", &self.span, "pieces", &&self.pieces)
    }
}Debug, const _: () =
    {
        impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            for FormatString where __CTX: crate::HashStableContext {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    FormatString {
                        input: ref __binding_0,
                        span: ref __binding_1,
                        pieces: ref __binding_2 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                        { __binding_2.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_Generic, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for FormatString {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    FormatString {
                        input: ref __binding_0,
                        span: ref __binding_1,
                        pieces: 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);
                    }
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for FormatString {
            fn decode(__decoder: &mut __D) -> Self {
                FormatString {
                    input: ::rustc_serialize::Decodable::decode(__decoder),
                    span: ::rustc_serialize::Decodable::decode(__decoder),
                    pieces: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable, const _: () =
    {
        #[allow(unused)]
        impl PrintAttribute for FormatString {
            fn should_render(&self) -> bool { true }
            fn print_attribute(&self,
                __p: &mut rustc_ast_pretty::pp::Printer) {
                let Self { input, span, pieces } = self;
                __p.word("FormatString");
                if true && !input.should_render() && !span.should_render() &&
                        !pieces.should_render() {
                    return;
                }
                __p.nbsp();
                __p.word("{");
                let mut __printed_anything = false;
                if input.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("input");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                input.print_attribute(__p);
                if span.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("span");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                span.print_attribute(__p);
                if pieces.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("pieces");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                pieces.print_attribute(__p);
                __p.word("}");
            }
        }
    };PrintAttribute)]
130pub struct FormatString {
131    pub input: Symbol,
132    pub span: Span,
133    pub pieces: ThinVec<Piece>,
134}
135impl FormatString {
136    pub fn format(&self, args: &FormatArgs) -> String {
137        let mut ret = String::new();
138        for piece in &self.pieces {
139            match piece {
140                Piece::Lit(s) | Piece::Arg(FormatArg::AsIs(s)) => ret.push_str(s.as_str()),
141
142                // `A` if we have `trait Trait<A> {}` and `note = "i'm the actual type of {A}"`
143                Piece::Arg(FormatArg::GenericParam { generic_param, .. }) => {
144                    match args.generic_args.iter().find(|(p, _)| p == generic_param) {
145                        Some((_, val)) => ret.push_str(val.as_str()),
146
147                        None => {
148                            // Apparently this was not actually a generic parameter, so lets write
149                            // what the user wrote.
150                            let _ = fmt::write(&mut ret, format_args!("{{{0}}}", generic_param)format_args!("{{{generic_param}}}"));
151                        }
152                    }
153                }
154                // `{Self}`
155                Piece::Arg(FormatArg::SelfUpper) => {
156                    let slf = match args.generic_args.iter().find(|(p, _)| *p == kw::SelfUpper) {
157                        Some((_, val)) => val.to_string(),
158                        None => "Self".to_string(),
159                    };
160                    ret.push_str(&slf);
161                }
162
163                // It's only `rustc_onunimplemented` from here
164                Piece::Arg(FormatArg::This) => ret.push_str(&args.this),
165                Piece::Arg(FormatArg::Trait) => {
166                    let _ = fmt::write(&mut ret, format_args!("{0}", &args.trait_sugared)format_args!("{}", &args.trait_sugared));
167                }
168                Piece::Arg(FormatArg::ItemContext) => ret.push_str(args.item_context),
169            }
170        }
171        ret
172    }
173
174    fn visit_params(&self, visit: &mut impl FnMut(Symbol, Span)) {
175        for piece in &self.pieces {
176            if let Piece::Arg(FormatArg::GenericParam { generic_param, span }) = piece {
177                visit(*generic_param, *span);
178            }
179        }
180    }
181}
182
183/// Arguments to fill a [FormatString] with.
184///
185/// For example, given a
186/// ```rust,ignore (just an example)
187///
188/// #[rustc_on_unimplemented(
189///     on(all(from_desugaring = "QuestionMark"),
190///         message = "the `?` operator can only be used in {ItemContext} \
191///                     that returns `Result` or `Option` \
192///                     (or another type that implements `{FromResidual}`)",
193///         label = "cannot use the `?` operator in {ItemContext} that returns `{Self}`",
194///         parent_label = "this function should return `Result` or `Option` to accept `?`"
195///     ),
196/// )]
197/// pub trait FromResidual<R = <Self as Try>::Residual> {
198///    ...
199/// }
200///
201/// async fn an_async_function() -> u32 {
202///     let x: Option<u32> = None;
203///     x?; //~ ERROR the `?` operator
204///     22
205/// }
206///  ```
207/// it will look like this:
208///
209/// ```rust,ignore (just an example)
210/// FormatArgs {
211///     this: "FromResidual",
212///     trait_sugared: "FromResidual<Option<Infallible>>",
213///     item_context: "an async function",
214///     generic_args: [("Self", "u32"), ("R", "Option<Infallible>")],
215/// }
216/// ```
217#[derive(#[automatically_derived]
impl ::core::fmt::Debug for FormatArgs {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field4_finish(f, "FormatArgs",
            "this", &self.this, "trait_sugared", &self.trait_sugared,
            "item_context", &self.item_context, "generic_args",
            &&self.generic_args)
    }
}Debug)]
218pub struct FormatArgs {
219    pub this: String,
220    pub trait_sugared: String,
221    pub item_context: &'static str,
222    pub generic_args: Vec<(Symbol, String)>,
223}
224
225#[derive(#[automatically_derived]
impl ::core::clone::Clone for Piece {
    #[inline]
    fn clone(&self) -> Piece {
        match self {
            Piece::Lit(__self_0) =>
                Piece::Lit(::core::clone::Clone::clone(__self_0)),
            Piece::Arg(__self_0) =>
                Piece::Arg(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for Piece {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Piece::Lit(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Lit",
                    &__self_0),
            Piece::Arg(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Arg",
                    &__self_0),
        }
    }
}Debug, const _: () =
    {
        impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            for Piece 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 {
                    Piece::Lit(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    Piece::Arg(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_Generic, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for Piece {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        Piece::Lit(ref __binding_0) => { 0usize }
                        Piece::Arg(ref __binding_0) => { 1usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    Piece::Lit(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    Piece::Arg(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for Piece {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        Piece::Lit(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    1usize => {
                        Piece::Arg(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `Piece`, expected 0..2, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable, const _: () =
    {
        #[allow(unused)]
        impl PrintAttribute for Piece {
            fn should_render(&self) -> bool { true }
            fn print_attribute(&self,
                __p: &mut rustc_ast_pretty::pp::Printer) {
                match self {
                    Self::Lit(f0) => {
                        __p.word("Lit");
                        if true && !f0.should_render() { return; }
                        __p.popen();
                        let mut __printed_anything = false;
                        if f0.should_render() {
                            if __printed_anything { __p.word_space(","); }
                            __printed_anything = true;
                        }
                        f0.print_attribute(__p);
                        __p.pclose();
                    }
                    Self::Arg(f0) => {
                        __p.word("Arg");
                        if true && !f0.should_render() { return; }
                        __p.popen();
                        let mut __printed_anything = false;
                        if f0.should_render() {
                            if __printed_anything { __p.word_space(","); }
                            __printed_anything = true;
                        }
                        f0.print_attribute(__p);
                        __p.pclose();
                    }
                }
            }
        }
    };PrintAttribute)]
226pub enum Piece {
227    Lit(Symbol),
228    Arg(FormatArg),
229}
230
231#[derive(#[automatically_derived]
impl ::core::clone::Clone for FormatArg {
    #[inline]
    fn clone(&self) -> FormatArg {
        match self {
            FormatArg::GenericParam { generic_param: __self_0, span: __self_1
                } =>
                FormatArg::GenericParam {
                    generic_param: ::core::clone::Clone::clone(__self_0),
                    span: ::core::clone::Clone::clone(__self_1),
                },
            FormatArg::SelfUpper => FormatArg::SelfUpper,
            FormatArg::This => FormatArg::This,
            FormatArg::Trait => FormatArg::Trait,
            FormatArg::ItemContext => FormatArg::ItemContext,
            FormatArg::AsIs(__self_0) =>
                FormatArg::AsIs(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for FormatArg {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            FormatArg::GenericParam { generic_param: __self_0, span: __self_1
                } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "GenericParam", "generic_param", __self_0, "span",
                    &__self_1),
            FormatArg::SelfUpper =>
                ::core::fmt::Formatter::write_str(f, "SelfUpper"),
            FormatArg::This => ::core::fmt::Formatter::write_str(f, "This"),
            FormatArg::Trait => ::core::fmt::Formatter::write_str(f, "Trait"),
            FormatArg::ItemContext =>
                ::core::fmt::Formatter::write_str(f, "ItemContext"),
            FormatArg::AsIs(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "AsIs",
                    &__self_0),
        }
    }
}Debug, const _: () =
    {
        impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            for FormatArg 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 {
                    FormatArg::GenericParam {
                        generic_param: ref __binding_0, span: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                    FormatArg::SelfUpper => {}
                    FormatArg::This => {}
                    FormatArg::Trait => {}
                    FormatArg::ItemContext => {}
                    FormatArg::AsIs(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_Generic, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for FormatArg {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        FormatArg::GenericParam {
                            generic_param: ref __binding_0, span: ref __binding_1 } => {
                            0usize
                        }
                        FormatArg::SelfUpper => { 1usize }
                        FormatArg::This => { 2usize }
                        FormatArg::Trait => { 3usize }
                        FormatArg::ItemContext => { 4usize }
                        FormatArg::AsIs(ref __binding_0) => { 5usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    FormatArg::GenericParam {
                        generic_param: ref __binding_0, span: ref __binding_1 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                    FormatArg::SelfUpper => {}
                    FormatArg::This => {}
                    FormatArg::Trait => {}
                    FormatArg::ItemContext => {}
                    FormatArg::AsIs(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for FormatArg {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        FormatArg::GenericParam {
                            generic_param: ::rustc_serialize::Decodable::decode(__decoder),
                            span: ::rustc_serialize::Decodable::decode(__decoder),
                        }
                    }
                    1usize => { FormatArg::SelfUpper }
                    2usize => { FormatArg::This }
                    3usize => { FormatArg::Trait }
                    4usize => { FormatArg::ItemContext }
                    5usize => {
                        FormatArg::AsIs(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `FormatArg`, expected 0..6, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable, const _: () =
    {
        #[allow(unused)]
        impl PrintAttribute for FormatArg {
            fn should_render(&self) -> bool { true }
            fn print_attribute(&self,
                __p: &mut rustc_ast_pretty::pp::Printer) {
                match self {
                    Self::GenericParam { generic_param, span } => {
                        __p.word("GenericParam");
                        if true && !generic_param.should_render() &&
                                !span.should_render() {
                            return;
                        }
                        __p.nbsp();
                        __p.word("{");
                        let mut __printed_anything = false;
                        if generic_param.should_render() {
                            if __printed_anything { __p.word_space(","); }
                            __p.word("generic_param");
                            __p.word(":");
                            __p.nbsp();
                            __printed_anything = true;
                        }
                        generic_param.print_attribute(__p);
                        if span.should_render() {
                            if __printed_anything { __p.word_space(","); }
                            __p.word("span");
                            __p.word(":");
                            __p.nbsp();
                            __printed_anything = true;
                        }
                        span.print_attribute(__p);
                        __p.word("}");
                    }
                    Self::SelfUpper => { __p.word("SelfUpper") }
                    Self::This => { __p.word("This") }
                    Self::Trait => { __p.word("Trait") }
                    Self::ItemContext => { __p.word("ItemContext") }
                    Self::AsIs(f0) => {
                        __p.word("AsIs");
                        if true && !f0.should_render() { return; }
                        __p.popen();
                        let mut __printed_anything = false;
                        if f0.should_render() {
                            if __printed_anything { __p.word_space(","); }
                            __printed_anything = true;
                        }
                        f0.print_attribute(__p);
                        __p.pclose();
                    }
                }
            }
        }
    };PrintAttribute)]
232pub enum FormatArg {
233    // A generic parameter, like `{T}` if we're on the `From<T>` trait.
234    GenericParam {
235        generic_param: Symbol,
236        span: Span,
237    },
238    // `{Self}`
239    SelfUpper,
240    /// `{This}` or `{TraitName}`
241    This,
242    /// The sugared form of the trait
243    Trait,
244    /// what we're in, like a function, method, closure etc.
245    ItemContext,
246    /// What the user typed, if it doesn't match anything we can use.
247    AsIs(Symbol),
248}
249
250/// Represents the `on` filter in `#[rustc_on_unimplemented]`.
251#[derive(#[automatically_derived]
impl ::core::clone::Clone for OnUnimplementedCondition {
    #[inline]
    fn clone(&self) -> OnUnimplementedCondition {
        OnUnimplementedCondition {
            span: ::core::clone::Clone::clone(&self.span),
            pred: ::core::clone::Clone::clone(&self.pred),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for OnUnimplementedCondition {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "OnUnimplementedCondition", "span", &self.span, "pred",
            &&self.pred)
    }
}Debug, const _: () =
    {
        impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            for OnUnimplementedCondition where __CTX: crate::HashStableContext
            {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    OnUnimplementedCondition {
                        span: ref __binding_0, pred: ref __binding_1 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_Generic, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for OnUnimplementedCondition {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    OnUnimplementedCondition {
                        span: ref __binding_0, pred: 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 OnUnimplementedCondition {
            fn decode(__decoder: &mut __D) -> Self {
                OnUnimplementedCondition {
                    span: ::rustc_serialize::Decodable::decode(__decoder),
                    pred: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable, const _: () =
    {
        #[allow(unused)]
        impl PrintAttribute for OnUnimplementedCondition {
            fn should_render(&self) -> bool { true }
            fn print_attribute(&self,
                __p: &mut rustc_ast_pretty::pp::Printer) {
                let Self { span, pred } = self;
                __p.word("OnUnimplementedCondition");
                if true && !span.should_render() && !pred.should_render() {
                    return;
                }
                __p.nbsp();
                __p.word("{");
                let mut __printed_anything = false;
                if span.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("span");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                span.print_attribute(__p);
                if pred.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("pred");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                pred.print_attribute(__p);
                __p.word("}");
            }
        }
    };PrintAttribute)]
252pub struct OnUnimplementedCondition {
253    pub span: Span,
254    pub pred: Predicate,
255}
256impl OnUnimplementedCondition {
257    pub fn matches_predicate(self: &OnUnimplementedCondition, options: &ConditionOptions) -> bool {
258        self.pred.eval(&mut |p| match p {
259            FlagOrNv::Flag(b) => options.has_flag(*b),
260            FlagOrNv::NameValue(NameValue { name, value }) => {
261                let value = value.format(&options.generic_args);
262                options.contains(*name, value)
263            }
264        })
265    }
266
267    pub fn visit_params(&self, visit: &mut impl FnMut(Symbol, Span)) {
268        self.pred.visit_params(self.span, visit);
269    }
270}
271
272/// Predicate(s) in `#[rustc_on_unimplemented]`'s `on` filter. See [`OnUnimplementedCondition`].
273///
274/// It is similar to the predicate in the `cfg` attribute,
275/// and may contain nested predicates.
276#[derive(#[automatically_derived]
impl ::core::clone::Clone for Predicate {
    #[inline]
    fn clone(&self) -> Predicate {
        match self {
            Predicate::Flag(__self_0) =>
                Predicate::Flag(::core::clone::Clone::clone(__self_0)),
            Predicate::Match(__self_0) =>
                Predicate::Match(::core::clone::Clone::clone(__self_0)),
            Predicate::Not(__self_0) =>
                Predicate::Not(::core::clone::Clone::clone(__self_0)),
            Predicate::All(__self_0) =>
                Predicate::All(::core::clone::Clone::clone(__self_0)),
            Predicate::Any(__self_0) =>
                Predicate::Any(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for Predicate {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Predicate::Flag(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Flag",
                    &__self_0),
            Predicate::Match(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Match",
                    &__self_0),
            Predicate::Not(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Not",
                    &__self_0),
            Predicate::All(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "All",
                    &__self_0),
            Predicate::Any(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Any",
                    &__self_0),
        }
    }
}Debug, const _: () =
    {
        impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            for Predicate 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 {
                    Predicate::Flag(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    Predicate::Match(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    Predicate::Not(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    Predicate::All(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    Predicate::Any(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_Generic, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for Predicate {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        Predicate::Flag(ref __binding_0) => { 0usize }
                        Predicate::Match(ref __binding_0) => { 1usize }
                        Predicate::Not(ref __binding_0) => { 2usize }
                        Predicate::All(ref __binding_0) => { 3usize }
                        Predicate::Any(ref __binding_0) => { 4usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    Predicate::Flag(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    Predicate::Match(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    Predicate::Not(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    Predicate::All(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    Predicate::Any(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for Predicate {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        Predicate::Flag(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    1usize => {
                        Predicate::Match(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    2usize => {
                        Predicate::Not(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    3usize => {
                        Predicate::All(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    4usize => {
                        Predicate::Any(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `Predicate`, expected 0..5, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable, const _: () =
    {
        #[allow(unused)]
        impl PrintAttribute for Predicate {
            fn should_render(&self) -> bool { true }
            fn print_attribute(&self,
                __p: &mut rustc_ast_pretty::pp::Printer) {
                match self {
                    Self::Flag(f0) => {
                        __p.word("Flag");
                        if true && !f0.should_render() { return; }
                        __p.popen();
                        let mut __printed_anything = false;
                        if f0.should_render() {
                            if __printed_anything { __p.word_space(","); }
                            __printed_anything = true;
                        }
                        f0.print_attribute(__p);
                        __p.pclose();
                    }
                    Self::Match(f0) => {
                        __p.word("Match");
                        if true && !f0.should_render() { return; }
                        __p.popen();
                        let mut __printed_anything = false;
                        if f0.should_render() {
                            if __printed_anything { __p.word_space(","); }
                            __printed_anything = true;
                        }
                        f0.print_attribute(__p);
                        __p.pclose();
                    }
                    Self::Not(f0) => {
                        __p.word("Not");
                        if true && !f0.should_render() { return; }
                        __p.popen();
                        let mut __printed_anything = false;
                        if f0.should_render() {
                            if __printed_anything { __p.word_space(","); }
                            __printed_anything = true;
                        }
                        f0.print_attribute(__p);
                        __p.pclose();
                    }
                    Self::All(f0) => {
                        __p.word("All");
                        if true && !f0.should_render() { return; }
                        __p.popen();
                        let mut __printed_anything = false;
                        if f0.should_render() {
                            if __printed_anything { __p.word_space(","); }
                            __printed_anything = true;
                        }
                        f0.print_attribute(__p);
                        __p.pclose();
                    }
                    Self::Any(f0) => {
                        __p.word("Any");
                        if true && !f0.should_render() { return; }
                        __p.popen();
                        let mut __printed_anything = false;
                        if f0.should_render() {
                            if __printed_anything { __p.word_space(","); }
                            __printed_anything = true;
                        }
                        f0.print_attribute(__p);
                        __p.pclose();
                    }
                }
            }
        }
    };PrintAttribute)]
277pub enum Predicate {
278    /// A condition like `on(crate_local)`.
279    Flag(Flag),
280    /// A match, like `on(Rhs = "Whatever")`.
281    Match(NameValue),
282    /// Negation, like `on(not($pred))`.
283    Not(Box<Predicate>),
284    /// True if all predicates are true, like `on(all($a, $b, $c))`.
285    All(ThinVec<Predicate>),
286    /// True if any predicate is true, like `on(any($a, $b, $c))`.
287    Any(ThinVec<Predicate>),
288}
289
290impl Predicate {
291    pub fn eval(&self, eval: &mut impl FnMut(FlagOrNv<'_>) -> bool) -> bool {
292        match self {
293            Predicate::Flag(flag) => eval(FlagOrNv::Flag(flag)),
294            Predicate::Match(nv) => eval(FlagOrNv::NameValue(nv)),
295            Predicate::Not(not) => !not.eval(eval),
296            Predicate::All(preds) => preds.into_iter().all(|pred| pred.eval(eval)),
297            Predicate::Any(preds) => preds.into_iter().any(|pred| pred.eval(eval)),
298        }
299    }
300
301    pub fn visit_params(&self, span: Span, visit: &mut impl FnMut(Symbol, Span)) {
302        match self {
303            Predicate::Flag(_) => {}
304            Predicate::Match(nv) => nv.visit_params(span, visit),
305            Predicate::Not(not) => not.visit_params(span, visit),
306            Predicate::All(preds) | Predicate::Any(preds) => {
307                preds.iter().for_each(|pred| pred.visit_params(span, visit))
308            }
309        }
310    }
311}
312
313/// Represents a `MetaWord` in an `on`-filter.
314#[derive(#[automatically_derived]
impl ::core::clone::Clone for Flag {
    #[inline]
    fn clone(&self) -> Flag { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Flag { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for Flag {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                Flag::CrateLocal => "CrateLocal",
                Flag::Direct => "Direct",
                Flag::FromDesugaring => "FromDesugaring",
            })
    }
}Debug, const _: () =
    {
        impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            for Flag 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 {
                    Flag::CrateLocal => {}
                    Flag::Direct => {}
                    Flag::FromDesugaring => {}
                }
            }
        }
    };HashStable_Generic, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for Flag {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        Flag::CrateLocal => { 0usize }
                        Flag::Direct => { 1usize }
                        Flag::FromDesugaring => { 2usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    Flag::CrateLocal => {}
                    Flag::Direct => {}
                    Flag::FromDesugaring => {}
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for Flag {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { Flag::CrateLocal }
                    1usize => { Flag::Direct }
                    2usize => { Flag::FromDesugaring }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `Flag`, expected 0..3, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable, const _: () =
    {
        #[allow(unused)]
        impl PrintAttribute for Flag {
            fn should_render(&self) -> bool { true }
            fn print_attribute(&self,
                __p: &mut rustc_ast_pretty::pp::Printer) {
                match self {
                    Self::CrateLocal => { __p.word("CrateLocal") }
                    Self::Direct => { __p.word("Direct") }
                    Self::FromDesugaring => { __p.word("FromDesugaring") }
                }
            }
        }
    };PrintAttribute)]
315pub enum Flag {
316    /// Whether the code causing the trait bound to not be fulfilled
317    /// is part of the user's crate.
318    CrateLocal,
319    /// Whether the obligation is user-specified rather than derived.
320    Direct,
321    /// Whether we are in some kind of desugaring like
322    /// `?` or `try { .. }`.
323    FromDesugaring,
324}
325
326/// A `MetaNameValueStr` in an `on`-filter.
327///
328/// For example, `#[rustc_on_unimplemented(on(name = "value", message = "hello"))]`.
329#[derive(#[automatically_derived]
impl ::core::clone::Clone for NameValue {
    #[inline]
    fn clone(&self) -> NameValue {
        NameValue {
            name: ::core::clone::Clone::clone(&self.name),
            value: ::core::clone::Clone::clone(&self.value),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for NameValue {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "NameValue",
            "name", &self.name, "value", &&self.value)
    }
}Debug, const _: () =
    {
        impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            for NameValue where __CTX: crate::HashStableContext {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    NameValue { name: ref __binding_0, value: ref __binding_1 }
                        => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                        { __binding_1.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_Generic, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for NameValue {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    NameValue { name: ref __binding_0, value: 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 NameValue {
            fn decode(__decoder: &mut __D) -> Self {
                NameValue {
                    name: ::rustc_serialize::Decodable::decode(__decoder),
                    value: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable, const _: () =
    {
        #[allow(unused)]
        impl PrintAttribute for NameValue {
            fn should_render(&self) -> bool { true }
            fn print_attribute(&self,
                __p: &mut rustc_ast_pretty::pp::Printer) {
                let Self { name, value } = self;
                __p.word("NameValue");
                if true && !name.should_render() && !value.should_render() {
                    return;
                }
                __p.nbsp();
                __p.word("{");
                let mut __printed_anything = false;
                if name.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("name");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                name.print_attribute(__p);
                if value.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("value");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                value.print_attribute(__p);
                __p.word("}");
            }
        }
    };PrintAttribute)]
330pub struct NameValue {
331    pub name: Name,
332    /// Something like `"&str"` or `"alloc::string::String"`,
333    /// in which case it just contains a single string piece.
334    /// But if it is something like `"&[{A}]"` then it must be formatted later.
335    pub value: FilterFormatString,
336}
337
338impl NameValue {
339    pub fn visit_params(&self, span: Span, visit: &mut impl FnMut(Symbol, Span)) {
340        if let Name::GenericArg(arg) = self.name {
341            visit(arg, span);
342        }
343        self.value.visit_params(span, visit);
344    }
345}
346
347/// The valid names of the `on` filter.
348#[derive(#[automatically_derived]
impl ::core::clone::Clone for Name {
    #[inline]
    fn clone(&self) -> Name {
        let _: ::core::clone::AssertParamIsClone<Symbol>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Name { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for Name {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Name::Cause => ::core::fmt::Formatter::write_str(f, "Cause"),
            Name::FromDesugaring =>
                ::core::fmt::Formatter::write_str(f, "FromDesugaring"),
            Name::SelfUpper =>
                ::core::fmt::Formatter::write_str(f, "SelfUpper"),
            Name::GenericArg(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "GenericArg", &__self_0),
        }
    }
}Debug, const _: () =
    {
        impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            for Name 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 {
                    Name::Cause => {}
                    Name::FromDesugaring => {}
                    Name::SelfUpper => {}
                    Name::GenericArg(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_Generic, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for Name {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        Name::Cause => { 0usize }
                        Name::FromDesugaring => { 1usize }
                        Name::SelfUpper => { 2usize }
                        Name::GenericArg(ref __binding_0) => { 3usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    Name::Cause => {}
                    Name::FromDesugaring => {}
                    Name::SelfUpper => {}
                    Name::GenericArg(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for Name {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { Name::Cause }
                    1usize => { Name::FromDesugaring }
                    2usize => { Name::SelfUpper }
                    3usize => {
                        Name::GenericArg(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `Name`, expected 0..4, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable, const _: () =
    {
        #[allow(unused)]
        impl PrintAttribute for Name {
            fn should_render(&self) -> bool { true }
            fn print_attribute(&self,
                __p: &mut rustc_ast_pretty::pp::Printer) {
                match self {
                    Self::Cause => { __p.word("Cause") }
                    Self::FromDesugaring => { __p.word("FromDesugaring") }
                    Self::SelfUpper => { __p.word("SelfUpper") }
                    Self::GenericArg(f0) => {
                        __p.word("GenericArg");
                        if true && !f0.should_render() { return; }
                        __p.popen();
                        let mut __printed_anything = false;
                        if f0.should_render() {
                            if __printed_anything { __p.word_space(","); }
                            __printed_anything = true;
                        }
                        f0.print_attribute(__p);
                        __p.pclose();
                    }
                }
            }
        }
    };PrintAttribute)]
349pub enum Name {
350    Cause,
351    FromDesugaring,
352    SelfUpper,
353    GenericArg(Symbol),
354}
355
356#[derive(#[automatically_derived]
impl<'p> ::core::fmt::Debug for FlagOrNv<'p> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            FlagOrNv::Flag(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Flag",
                    &__self_0),
            FlagOrNv::NameValue(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "NameValue", &__self_0),
        }
    }
}Debug, #[automatically_derived]
impl<'p> ::core::clone::Clone for FlagOrNv<'p> {
    #[inline]
    fn clone(&self) -> FlagOrNv<'p> {
        match self {
            FlagOrNv::Flag(__self_0) =>
                FlagOrNv::Flag(::core::clone::Clone::clone(__self_0)),
            FlagOrNv::NameValue(__self_0) =>
                FlagOrNv::NameValue(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone)]
357pub enum FlagOrNv<'p> {
358    Flag(&'p Flag),
359    NameValue(&'p NameValue),
360}
361
362/// Represents a value inside an `on` filter.
363///
364/// For example, `#[rustc_on_unimplemented(on(name = "value", message = "hello"))]`.
365/// If it is a simple literal like this then `pieces` will be `[LitOrArg::Lit("value")]`.
366/// The `Arg` variant is used when it contains formatting like
367/// `#[rustc_on_unimplemented(on(Self = "&[{A}]", message = "hello"))]`.
368#[derive(#[automatically_derived]
impl ::core::clone::Clone for FilterFormatString {
    #[inline]
    fn clone(&self) -> FilterFormatString {
        FilterFormatString {
            pieces: ::core::clone::Clone::clone(&self.pieces),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for FilterFormatString {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f,
            "FilterFormatString", "pieces", &&self.pieces)
    }
}Debug, const _: () =
    {
        impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            for FilterFormatString where __CTX: crate::HashStableContext {
            #[inline]
            fn hash_stable(&self, __hcx: &mut __CTX,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    FilterFormatString { pieces: ref __binding_0 } => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_Generic, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for FilterFormatString {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    FilterFormatString { pieces: ref __binding_0 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for FilterFormatString {
            fn decode(__decoder: &mut __D) -> Self {
                FilterFormatString {
                    pieces: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable, const _: () =
    {
        #[allow(unused)]
        impl PrintAttribute for FilterFormatString {
            fn should_render(&self) -> bool { true }
            fn print_attribute(&self,
                __p: &mut rustc_ast_pretty::pp::Printer) {
                let Self { pieces } = self;
                __p.word("FilterFormatString");
                if true && !pieces.should_render() { return; }
                __p.nbsp();
                __p.word("{");
                let mut __printed_anything = false;
                if pieces.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("pieces");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                pieces.print_attribute(__p);
                __p.word("}");
            }
        }
    };PrintAttribute)]
369pub struct FilterFormatString {
370    pub pieces: ThinVec<LitOrArg>,
371}
372
373impl FilterFormatString {
374    fn format(&self, generic_args: &[(Symbol, String)]) -> String {
375        let mut ret = String::new();
376
377        for piece in &self.pieces {
378            match piece {
379                LitOrArg::Lit(s) => ret.push_str(s.as_str()),
380                LitOrArg::Arg(s) => match generic_args.iter().find(|(k, _)| k == s) {
381                    Some((_, val)) => ret.push_str(val),
382                    None => {
383                        let _ = std::fmt::write(&mut ret, format_args!("{{{0}}}", s)format_args!("{{{s}}}"));
384                    }
385                },
386            }
387        }
388
389        ret
390    }
391    pub fn visit_params(&self, span: Span, visit: &mut impl FnMut(Symbol, Span)) {
392        for piece in &self.pieces {
393            if let LitOrArg::Arg(arg) = piece {
394                visit(*arg, span);
395            }
396        }
397    }
398}
399
400#[derive(#[automatically_derived]
impl ::core::clone::Clone for LitOrArg {
    #[inline]
    fn clone(&self) -> LitOrArg {
        match self {
            LitOrArg::Lit(__self_0) =>
                LitOrArg::Lit(::core::clone::Clone::clone(__self_0)),
            LitOrArg::Arg(__self_0) =>
                LitOrArg::Arg(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for LitOrArg {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            LitOrArg::Lit(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Lit",
                    &__self_0),
            LitOrArg::Arg(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Arg",
                    &__self_0),
        }
    }
}Debug, const _: () =
    {
        impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
            for LitOrArg 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 {
                    LitOrArg::Lit(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                    LitOrArg::Arg(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };HashStable_Generic, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for LitOrArg {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        LitOrArg::Lit(ref __binding_0) => { 0usize }
                        LitOrArg::Arg(ref __binding_0) => { 1usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    LitOrArg::Lit(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    LitOrArg::Arg(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for LitOrArg {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        LitOrArg::Lit(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    1usize => {
                        LitOrArg::Arg(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `LitOrArg`, expected 0..2, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable, const _: () =
    {
        #[allow(unused)]
        impl PrintAttribute for LitOrArg {
            fn should_render(&self) -> bool { true }
            fn print_attribute(&self,
                __p: &mut rustc_ast_pretty::pp::Printer) {
                match self {
                    Self::Lit(f0) => {
                        __p.word("Lit");
                        if true && !f0.should_render() { return; }
                        __p.popen();
                        let mut __printed_anything = false;
                        if f0.should_render() {
                            if __printed_anything { __p.word_space(","); }
                            __printed_anything = true;
                        }
                        f0.print_attribute(__p);
                        __p.pclose();
                    }
                    Self::Arg(f0) => {
                        __p.word("Arg");
                        if true && !f0.should_render() { return; }
                        __p.popen();
                        let mut __printed_anything = false;
                        if f0.should_render() {
                            if __printed_anything { __p.word_space(","); }
                            __printed_anything = true;
                        }
                        f0.print_attribute(__p);
                        __p.pclose();
                    }
                }
            }
        }
    };PrintAttribute)]
401pub enum LitOrArg {
402    Lit(Symbol),
403    Arg(Symbol),
404}
405
406/// Used with `OnUnimplementedCondition::matches_predicate` to evaluate the
407/// [`OnUnimplementedCondition`].
408///
409/// For example, given a
410/// ```rust,ignore (just an example)
411/// #[rustc_on_unimplemented(
412///     on(all(from_desugaring = "QuestionMark"),
413///         message = "the `?` operator can only be used in {ItemContext} \
414///                     that returns `Result` or `Option` \
415///                     (or another type that implements `{FromResidual}`)",
416///         label = "cannot use the `?` operator in {ItemContext} that returns `{Self}`",
417///         parent_label = "this function should return `Result` or `Option` to accept `?`"
418///     ),
419/// )]
420/// pub trait FromResidual<R = <Self as Try>::Residual> {
421///    ...
422/// }
423///
424/// async fn an_async_function() -> u32 {
425///     let x: Option<u32> = None;
426///     x?; //~ ERROR the `?` operator
427///     22
428/// }
429///  ```
430/// it will look like this:
431///
432/// ```rust,ignore (just an example)
433/// ConditionOptions {
434///     self_types: ["u32", "{integral}"],
435///     from_desugaring: Some("QuestionMark"),
436///     cause: None,
437///     crate_local: false,
438///     direct: true,
439///     generic_args: [("Self","u32"),
440///         ("R", "core::option::Option<core::convert::Infallible>"),
441///         ("R", "core::option::Option<T>" ),
442///     ],
443/// }
444/// ```
445#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ConditionOptions {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["self_types", "from_desugaring", "cause", "crate_local",
                        "direct", "generic_args"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.self_types, &self.from_desugaring, &self.cause,
                        &self.crate_local, &self.direct, &&self.generic_args];
        ::core::fmt::Formatter::debug_struct_fields_finish(f,
            "ConditionOptions", names, values)
    }
}Debug)]
446pub struct ConditionOptions {
447    /// All the self types that may apply.
448    pub self_types: Vec<String>,
449    // The kind of compiler desugaring.
450    pub from_desugaring: Option<DesugaringKind>,
451    /// Match on a variant of rustc_infer's `ObligationCauseCode`.
452    pub cause: Option<String>,
453    pub crate_local: bool,
454    /// Is the obligation "directly" user-specified, rather than derived?
455    pub direct: bool,
456    // A list of the generic arguments and their reified types.
457    pub generic_args: Vec<(Symbol, String)>,
458}
459
460impl ConditionOptions {
461    pub fn has_flag(&self, name: Flag) -> bool {
462        match name {
463            Flag::CrateLocal => self.crate_local,
464            Flag::Direct => self.direct,
465            Flag::FromDesugaring => self.from_desugaring.is_some(),
466        }
467    }
468    pub fn contains(&self, name: Name, value: String) -> bool {
469        match name {
470            Name::SelfUpper => self.self_types.contains(&value),
471            Name::FromDesugaring => self.from_desugaring.is_some_and(|ds| ds.matches(&value)),
472            Name::Cause => self.cause == Some(value),
473            Name::GenericArg(arg) => self.generic_args.contains(&(arg, value)),
474        }
475    }
476}