1use proc_macro2::{Delimiter, Group, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
2use quote::{format_ident, quote, quote_spanned, ToTokens};
3use std::collections::BTreeSet as Set;
4use syn::parse::discouraged::Speculative;
5use syn::parse::{End, ParseStream};
6use syn::{
7 braced, bracketed, parenthesized, token, Attribute, Error, ExprPath, Ident, Index, LitFloat,
8 LitInt, LitStr, Meta, Result, Token,
9};
10
11pub struct Attrs<'a> {
12 pub display: Option<Display<'a>>,
13 pub source: Option<Source<'a>>,
14 pub backtrace: Option<&'a Attribute>,
15 pub from: Option<From<'a>>,
16 pub transparent: Option<Transparent<'a>>,
17 pub fmt: Option<Fmt<'a>>,
18}
19
20#[derive(#[automatically_derived]
impl<'a> ::core::clone::Clone for Display<'a> {
#[inline]
fn clone(&self) -> Display<'a> {
Display {
original: ::core::clone::Clone::clone(&self.original),
fmt: ::core::clone::Clone::clone(&self.fmt),
args: ::core::clone::Clone::clone(&self.args),
requires_fmt_machinery: ::core::clone::Clone::clone(&self.requires_fmt_machinery),
has_bonus_display: ::core::clone::Clone::clone(&self.has_bonus_display),
infinite_recursive: ::core::clone::Clone::clone(&self.infinite_recursive),
implied_bounds: ::core::clone::Clone::clone(&self.implied_bounds),
bindings: ::core::clone::Clone::clone(&self.bindings),
}
}
}Clone)]
21pub struct Display<'a> {
22 pub original: &'a Attribute,
23 pub fmt: LitStr,
24 pub args: TokenStream,
25 pub requires_fmt_machinery: bool,
26 pub has_bonus_display: bool,
27 pub infinite_recursive: bool,
28 pub implied_bounds: Set<(usize, Trait)>,
29 pub bindings: Vec<(Ident, TokenStream)>,
30}
31
32#[derive(#[automatically_derived]
impl<'a> ::core::marker::Copy for Source<'a> { }Copy, #[automatically_derived]
impl<'a> ::core::clone::Clone for Source<'a> {
#[inline]
fn clone(&self) -> Source<'a> {
let _: ::core::clone::AssertParamIsClone<&'a Attribute>;
let _: ::core::clone::AssertParamIsClone<Span>;
*self
}
}Clone)]
33pub struct Source<'a> {
34 pub original: &'a Attribute,
35 pub span: Span,
36}
37
38#[derive(#[automatically_derived]
impl<'a> ::core::marker::Copy for From<'a> { }Copy, #[automatically_derived]
impl<'a> ::core::clone::Clone for From<'a> {
#[inline]
fn clone(&self) -> From<'a> {
let _: ::core::clone::AssertParamIsClone<&'a Attribute>;
let _: ::core::clone::AssertParamIsClone<Span>;
*self
}
}Clone)]
39pub struct From<'a> {
40 pub original: &'a Attribute,
41 pub span: Span,
42}
43
44#[derive(#[automatically_derived]
impl<'a> ::core::marker::Copy for Transparent<'a> { }Copy, #[automatically_derived]
impl<'a> ::core::clone::Clone for Transparent<'a> {
#[inline]
fn clone(&self) -> Transparent<'a> {
let _: ::core::clone::AssertParamIsClone<&'a Attribute>;
let _: ::core::clone::AssertParamIsClone<Span>;
*self
}
}Clone)]
45pub struct Transparent<'a> {
46 pub original: &'a Attribute,
47 pub span: Span,
48}
49
50#[derive(#[automatically_derived]
impl<'a> ::core::clone::Clone for Fmt<'a> {
#[inline]
fn clone(&self) -> Fmt<'a> {
Fmt {
original: ::core::clone::Clone::clone(&self.original),
path: ::core::clone::Clone::clone(&self.path),
}
}
}Clone)]
51pub struct Fmt<'a> {
52 pub original: &'a Attribute,
53 pub path: ExprPath,
54}
55
56#[derive(#[automatically_derived]
impl ::core::marker::Copy for Trait { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Trait {
#[inline]
fn clone(&self) -> Trait { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::Eq for Trait {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for Trait {
#[inline]
fn eq(&self, other: &Trait) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Ord for Trait {
#[inline]
fn cmp(&self, other: &Trait) -> ::core::cmp::Ordering {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
}
}Ord, #[automatically_derived]
impl ::core::cmp::PartialOrd for Trait {
#[inline]
fn partial_cmp(&self, other: &Trait)
-> ::core::option::Option<::core::cmp::Ordering> {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::PartialOrd::partial_cmp(&__self_discr, &__arg1_discr)
}
}PartialOrd, #[automatically_derived]
impl ::core::fmt::Debug for Trait {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
Trait::Debug => "Debug",
Trait::Display => "Display",
Trait::Octal => "Octal",
Trait::LowerHex => "LowerHex",
Trait::UpperHex => "UpperHex",
Trait::Pointer => "Pointer",
Trait::Binary => "Binary",
Trait::LowerExp => "LowerExp",
Trait::UpperExp => "UpperExp",
})
}
}Debug)]
57pub enum Trait {
58 Debug,
59 Display,
60 Octal,
61 LowerHex,
62 UpperHex,
63 Pointer,
64 Binary,
65 LowerExp,
66 UpperExp,
67}
68
69pub fn get(input: &[Attribute]) -> Result<Attrs> {
70 let mut attrs = Attrs {
71 display: None,
72 source: None,
73 backtrace: None,
74 from: None,
75 transparent: None,
76 fmt: None,
77 };
78
79 for attr in input {
80 if attr.path().is_ident("error") {
81 parse_error_attribute(&mut attrs, attr)?;
82 } else if attr.path().is_ident("source") {
83 attr.meta.require_path_only()?;
84 if attrs.source.is_some() {
85 return Err(Error::new_spanned(attr, "duplicate #[source] attribute"));
86 }
87 let span = (attr.pound_token.span)
88 .join(attr.bracket_token.span.join())
89 .unwrap_or(attr.path().get_ident().unwrap().span());
90 attrs.source = Some(Source {
91 original: attr,
92 span,
93 });
94 } else if attr.path().is_ident("backtrace") {
95 attr.meta.require_path_only()?;
96 if attrs.backtrace.is_some() {
97 return Err(Error::new_spanned(attr, "duplicate #[backtrace] attribute"));
98 }
99 attrs.backtrace = Some(attr);
100 } else if attr.path().is_ident("from") {
101 match attr.meta {
102 Meta::Path(_) => {}
103 Meta::List(_) | Meta::NameValue(_) => {
104 continue;
106 }
107 }
108 if attrs.from.is_some() {
109 return Err(Error::new_spanned(attr, "duplicate #[from] attribute"));
110 }
111 let span = (attr.pound_token.span)
112 .join(attr.bracket_token.span.join())
113 .unwrap_or(attr.path().get_ident().unwrap().span());
114 attrs.from = Some(From {
115 original: attr,
116 span,
117 });
118 }
119 }
120
121 Ok(attrs)
122}
123
124fn parse_error_attribute<'a>(attrs: &mut Attrs<'a>, attr: &'a Attribute) -> Result<()> {
125 mod kw {
126 #[allow(non_camel_case_types)]
pub struct transparent {
#[allow(dead_code)]
pub span: ::syn::__private::Span,
}
#[doc(hidden)]
#[allow(dead_code, non_snake_case)]
pub fn transparent<__S: ::syn::__private::IntoSpans<::syn::__private::Span>>(span:
__S) -> transparent {
transparent { span: ::syn::__private::IntoSpans::into_spans(span) }
}
const _: () =
{
impl ::syn::__private::Default for transparent {
fn default() -> Self {
transparent { span: ::syn::__private::Span::call_site() }
}
}
impl ::syn::__private::CustomToken for transparent {
fn peek(cursor: ::syn::buffer::Cursor) -> ::syn::__private::bool {
if let ::syn::__private::Some((ident, _rest)) = cursor.ident()
{
ident == "transparent"
} else { false }
}
fn display() -> &'static ::syn::__private::str { "`transparent`" }
}
impl ::syn::parse::Parse for transparent {
fn parse(input: ::syn::parse::ParseStream)
-> ::syn::parse::Result<transparent> {
input.step(|cursor|
{
if let ::syn::__private::Some((ident, rest)) =
cursor.ident() {
if ident == "transparent" {
return ::syn::__private::Ok((transparent {
span: ident.span(),
}, rest));
}
}
::syn::__private::Err(cursor.error("expected `transparent`"))
})
}
}
impl ::syn::__private::ToTokens for transparent {
fn to_tokens(&self, tokens: &mut ::syn::__private::TokenStream2) {
let ident = ::syn::Ident::new("transparent", self.span);
::syn::__private::TokenStreamExt::append(tokens, ident);
}
}
impl ::syn::__private::Copy for transparent {}
#[allow(clippy :: expl_impl_clone_on_copy)]
impl ::syn::__private::Clone for transparent {
fn clone(&self) -> Self { *self }
}
;
};syn::custom_keyword!(transparent);
127 #[allow(non_camel_case_types)]
pub struct fmt {
#[allow(dead_code)]
pub span: ::syn::__private::Span,
}
#[doc(hidden)]
#[allow(dead_code, non_snake_case)]
pub fn fmt<__S: ::syn::__private::IntoSpans<::syn::__private::Span>>(span:
__S) -> fmt {
fmt { span: ::syn::__private::IntoSpans::into_spans(span) }
}
const _: () =
{
impl ::syn::__private::Default for fmt {
fn default() -> Self {
fmt { span: ::syn::__private::Span::call_site() }
}
}
impl ::syn::__private::CustomToken for fmt {
fn peek(cursor: ::syn::buffer::Cursor) -> ::syn::__private::bool {
if let ::syn::__private::Some((ident, _rest)) = cursor.ident()
{
ident == "fmt"
} else { false }
}
fn display() -> &'static ::syn::__private::str { "`fmt`" }
}
impl ::syn::parse::Parse for fmt {
fn parse(input: ::syn::parse::ParseStream)
-> ::syn::parse::Result<fmt> {
input.step(|cursor|
{
if let ::syn::__private::Some((ident, rest)) =
cursor.ident() {
if ident == "fmt" {
return ::syn::__private::Ok((fmt { span: ident.span() },
rest));
}
}
::syn::__private::Err(cursor.error("expected `fmt`"))
})
}
}
impl ::syn::__private::ToTokens for fmt {
fn to_tokens(&self, tokens: &mut ::syn::__private::TokenStream2) {
let ident = ::syn::Ident::new("fmt", self.span);
::syn::__private::TokenStreamExt::append(tokens, ident);
}
}
impl ::syn::__private::Copy for fmt {}
#[allow(clippy :: expl_impl_clone_on_copy)]
impl ::syn::__private::Clone for fmt {
fn clone(&self) -> Self { *self }
}
;
};syn::custom_keyword!(fmt);
128 }
129
130 attr.parse_args_with(|input: ParseStream| {
131 let lookahead = input.lookahead1();
132 let fmt = if lookahead.peek(LitStr) {
133 input.parse::<LitStr>()?
134 } else if lookahead.peek(kw::transparent) {
135 let kw: kw::transparent = input.parse()?;
136 if attrs.transparent.is_some() {
137 return Err(Error::new_spanned(
138 attr,
139 "duplicate #[error(transparent)] attribute",
140 ));
141 }
142 attrs.transparent = Some(Transparent {
143 original: attr,
144 span: kw.span,
145 });
146 return Ok(());
147 } else if lookahead.peek(kw::fmt) {
148 input.parse::<kw::fmt>()?;
149 input.parse::<Token![=]>()?;
150 let path: ExprPath = input.parse()?;
151 if attrs.fmt.is_some() {
152 return Err(Error::new_spanned(
153 attr,
154 "duplicate #[error(fmt = ...)] attribute",
155 ));
156 }
157 attrs.fmt = Some(Fmt {
158 original: attr,
159 path,
160 });
161 return Ok(());
162 } else {
163 return Err(lookahead.error());
164 };
165
166 let args = if input.is_empty() || input.peek(::syn::token::CommaToken![,]) && input.peek2(End) {
167 input.parse::<Option<Token![,]>>()?;
168 TokenStream::new()
169 } else {
170 parse_token_expr(input, false)?
171 };
172
173 let requires_fmt_machinery = !args.is_empty();
174
175 let display = Display {
176 original: attr,
177 fmt,
178 args,
179 requires_fmt_machinery,
180 has_bonus_display: false,
181 infinite_recursive: false,
182 implied_bounds: Set::new(),
183 bindings: Vec::new(),
184 };
185 if attrs.display.is_some() {
186 return Err(Error::new_spanned(
187 attr,
188 "only one #[error(...)] attribute is allowed",
189 ));
190 }
191 attrs.display = Some(display);
192 Ok(())
193 })
194}
195
196fn parse_token_expr(input: ParseStream, mut begin_expr: bool) -> Result<TokenStream> {
197 let mut tokens = Vec::new();
198 while !input.is_empty() {
199 if input.peek(token::Group) {
200 let group: TokenTree = input.parse()?;
201 tokens.push(group);
202 begin_expr = false;
203 continue;
204 }
205
206 if begin_expr && input.peek(::syn::token::DotToken![.]) {
207 if input.peek2(Ident) {
208 input.parse::<Token![.]>()?;
209 begin_expr = false;
210 continue;
211 } else if input.peek2(LitInt) {
212 input.parse::<Token![.]>()?;
213 let int: Index = input.parse()?;
214 tokens.push({
215 let ident = match ::quote::__private::IdentFragmentAdapter(&int.index) {
arg =>
::quote::__private::mk_ident(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("_{0}", arg))
}),
::quote::__private::Option::Some::<::quote::__private::Span>(int.span)),
}format_ident!("_{}", int.index, span = int.span);
216 TokenTree::Ident(ident)
217 });
218 begin_expr = false;
219 continue;
220 } else if input.peek2(LitFloat) {
221 let ahead = input.fork();
222 ahead.parse::<Token![.]>()?;
223 let float: LitFloat = ahead.parse()?;
224 let repr = float.to_string();
225 let mut indices = repr.split('.').map(syn::parse_str::<Index>);
226 if let (Some(Ok(first)), Some(Ok(second)), None) =
227 (indices.next(), indices.next(), indices.next())
228 {
229 input.advance_to(&ahead);
230 tokens.push({
231 let ident = match ::quote::__private::IdentFragmentAdapter(&first) {
arg =>
::quote::__private::mk_ident(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("_{0}", arg))
}),
::quote::__private::Option::Some::<::quote::__private::Span>(float.span())),
}format_ident!("_{}", first, span = float.span());
232 TokenTree::Ident(ident)
233 });
234 tokens.push({
235 let mut punct = Punct::new('.', Spacing::Alone);
236 punct.set_span(float.span());
237 TokenTree::Punct(punct)
238 });
239 tokens.push({
240 let mut literal = Literal::u32_unsuffixed(second.index);
241 literal.set_span(float.span());
242 TokenTree::Literal(literal)
243 });
244 begin_expr = false;
245 continue;
246 }
247 }
248 }
249
250 begin_expr = input.peek(::syn::token::BreakToken![break])
251 || input.peek(::syn::token::ContinueToken![continue])
252 || input.peek(::syn::token::IfToken![if])
253 || input.peek(::syn::token::InToken![in])
254 || input.peek(::syn::token::MatchToken![match])
255 || input.peek(::syn::token::MutToken![mut])
256 || input.peek(::syn::token::ReturnToken![return])
257 || input.peek(::syn::token::WhileToken![while])
258 || input.peek(::syn::token::PlusToken![+])
259 || input.peek(::syn::token::AndToken![&])
260 || input.peek(::syn::token::NotToken![!])
261 || input.peek(::syn::token::CaretToken![^])
262 || input.peek(::syn::token::CommaToken![,])
263 || input.peek(::syn::token::SlashToken![/])
264 || input.peek(::syn::token::EqToken![=])
265 || input.peek(::syn::token::GtToken![>])
266 || input.peek(::syn::token::LtToken![<])
267 || input.peek(::syn::token::OrToken![|])
268 || input.peek(::syn::token::PercentToken![%])
269 || input.peek(::syn::token::SemiToken![;])
270 || input.peek(::syn::token::StarToken![*])
271 || input.peek(::syn::token::MinusToken![-]);
272
273 let token: TokenTree = if input.peek(token::Paren) {
274 let content;
275 let delimiter = match ::syn::__private::parse_parens(&input) {
::syn::__private::Ok(parens) => { content = parens.content; parens.token }
::syn::__private::Err(error) => { return ::syn::__private::Err(error); }
}parenthesized!(content in input);
276 let nested = parse_token_expr(&content, true)?;
277 let mut group = Group::new(Delimiter::Parenthesis, nested);
278 group.set_span(delimiter.span.join());
279 TokenTree::Group(group)
280 } else if input.peek(token::Brace) {
281 let content;
282 let delimiter = match ::syn::__private::parse_braces(&input) {
::syn::__private::Ok(braces) => { content = braces.content; braces.token }
::syn::__private::Err(error) => { return ::syn::__private::Err(error); }
}braced!(content in input);
283 let nested = parse_token_expr(&content, true)?;
284 let mut group = Group::new(Delimiter::Brace, nested);
285 group.set_span(delimiter.span.join());
286 TokenTree::Group(group)
287 } else if input.peek(token::Bracket) {
288 let content;
289 let delimiter = match ::syn::__private::parse_brackets(&input) {
::syn::__private::Ok(brackets) => {
content = brackets.content;
brackets.token
}
::syn::__private::Err(error) => { return ::syn::__private::Err(error); }
}bracketed!(content in input);
290 let nested = parse_token_expr(&content, true)?;
291 let mut group = Group::new(Delimiter::Bracket, nested);
292 group.set_span(delimiter.span.join());
293 TokenTree::Group(group)
294 } else {
295 input.parse()?
296 };
297 tokens.push(token);
298 }
299 Ok(TokenStream::from_iter(tokens))
300}
301
302impl ToTokens for Display<'_> {
303 fn to_tokens(&self, tokens: &mut TokenStream) {
304 if self.infinite_recursive {
305 let span = self.fmt.span();
306 tokens.extend({
let mut _s = ::quote::__private::TokenStream::new();
let _span: ::quote::__private::Span =
::quote::__private::get_span(span).__into_span();
::quote::__private::push_pound_spanned(&mut _s, _span);
::quote::__private::push_group_spanned(&mut _s, _span,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
let _span: ::quote::__private::Span =
::quote::__private::get_span(_span).__into_span();
::quote::__private::push_ident_spanned(&mut _s, _span, "warn");
::quote::__private::push_group_spanned(&mut _s, _span,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
let _span: ::quote::__private::Span =
::quote::__private::get_span(_span).__into_span();
::quote::__private::push_ident_spanned(&mut _s, _span,
"unconditional_recursion");
_s
});
_s
});
::quote::__private::push_ident_spanned(&mut _s, _span, "fn");
::quote::__private::push_ident_spanned(&mut _s, _span, "_fmt");
::quote::__private::push_group_spanned(&mut _s, _span,
::quote::__private::Delimiter::Parenthesis,
{
let _: ::quote::__private::Span =
::quote::__private::get_span(_span).__into_span();
::quote::__private::TokenStream::new()
});
::quote::__private::push_group_spanned(&mut _s, _span,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
let _span: ::quote::__private::Span =
::quote::__private::get_span(_span).__into_span();
::quote::__private::push_ident_spanned(&mut _s, _span, "_fmt");
::quote::__private::push_group_spanned(&mut _s, _span,
::quote::__private::Delimiter::Parenthesis,
{
let _: ::quote::__private::Span =
::quote::__private::get_span(_span).__into_span();
::quote::__private::TokenStream::new()
});
_s
});
_s
}quote_spanned! {span=>
307 #[warn(unconditional_recursion)]
308 fn _fmt() { _fmt() }
309 });
310 }
311
312 let fmt = &self.fmt;
313 let args = &self.args;
314
315 let write = if self.requires_fmt_machinery {
319 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "write");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "__formatter");
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&fmt, &mut _s);
::quote::ToTokens::to_tokens(&args, &mut _s);
_s
});
_s
}quote! {
320 ::core::write!(__formatter, #fmt #args)
321 }
322 } else {
323 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "__formatter");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "write_str");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&fmt, &mut _s);
_s
});
_s
}quote! {
324 __formatter.write_str(#fmt)
325 }
326 };
327
328 tokens.extend(if self.bindings.is_empty() {
329 write
330 } else {
331 let locals = self.bindings.iter().map(|(local, _value)| local);
332 let values = self.bindings.iter().map(|(_local, value)| value);
333 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "match");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter =
::quote::__private::ThereIsNoIteratorInRepetition;
#[allow(unused_mut)]
let (mut values, i) = values.quote_into_iter();
let has_iter = has_iter | i;
let _: ::quote::__private::HasIterator = has_iter;
while true {
let values =
match values.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&values, &mut _s);
::quote::__private::push_comma(&mut _s);
}
}
_s
});
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter =
::quote::__private::ThereIsNoIteratorInRepetition;
#[allow(unused_mut)]
let (mut locals, i) = locals.quote_into_iter();
let has_iter = has_iter | i;
let _: ::quote::__private::HasIterator = has_iter;
while true {
let locals =
match locals.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&locals, &mut _s);
::quote::__private::push_comma(&mut _s);
}
}
_s
});
::quote::__private::push_fat_arrow(&mut _s);
::quote::ToTokens::to_tokens(&write, &mut _s);
_s
});
_s
}quote! {
334 match (#(#values,)*) {
335 (#(#locals,)*) => #write
336 }
337 }
338 });
339 }
340}
341
342impl ToTokens for Trait {
343 fn to_tokens(&self, tokens: &mut TokenStream) {
344 let trait_name = match self {
345 Trait::Debug => "Debug",
346 Trait::Display => "Display",
347 Trait::Octal => "Octal",
348 Trait::LowerHex => "LowerHex",
349 Trait::UpperHex => "UpperHex",
350 Trait::Pointer => "Pointer",
351 Trait::Binary => "Binary",
352 Trait::LowerExp => "LowerExp",
353 Trait::UpperExp => "UpperExp",
354 };
355 let ident = Ident::new(trait_name, Span::call_site());
356 tokens.extend({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "fmt");
::quote::__private::push_colon2(&mut _s);
::quote::ToTokens::to_tokens(&ident, &mut _s);
_s
}quote!(::core::fmt::#ident));
357 }
358}