1use crate::bound::{has_bound, InferredBound, Supertraits};
2use crate::lifetime::{AddLifetimeToImplTrait, CollectLifetimes};
3use crate::parse::Item;
4use crate::receiver::{has_self_in_block, has_self_in_sig, mut_pat, ReplaceSelf};
5use crate::verbatim::VerbatimFn;
6use proc_macro2::{Span, TokenStream};
7use quote::{format_ident, quote, quote_spanned, ToTokens};
8use std::collections::BTreeSet as Set;
9use std::mem;
10use syn::punctuated::Punctuated;
11use syn::visit_mut::{self, VisitMut};
12use syn::{
13 parse_quote, parse_quote_spanned, Attribute, Block, FnArg, GenericArgument, GenericParam,
14 Generics, Ident, ImplItem, Lifetime, LifetimeParam, Pat, PatIdent, PathArguments, Receiver,
15 ReceiverKind, ReturnType, Signature, Token, TraitItem, Type, TypeInfer, TypePath, WhereClause,
16};
17
18impl ToTokens for Item {
19 fn to_tokens(&self, tokens: &mut TokenStream) {
20 match self {
21 Item::Trait(item) => item.to_tokens(tokens),
22 Item::Impl(item) => item.to_tokens(tokens),
23 }
24 }
25}
26
27#[derive(#[automatically_derived]
impl<'a> ::core::clone::Clone for Context<'a> {
#[inline]
fn clone(&self) -> Context<'a> {
let _: ::core::clone::AssertParamIsClone<&'a Generics>;
let _: ::core::clone::AssertParamIsClone<&'a Supertraits>;
let _: ::core::clone::AssertParamIsClone<&'a Generics>;
let _: ::core::clone::AssertParamIsClone<&'a Set<Ident>>;
*self
}
}Clone, #[automatically_derived]
impl<'a> ::core::marker::Copy for Context<'a> { }Copy)]
28enum Context<'a> {
29 Trait {
30 generics: &'a Generics,
31 supertraits: &'a Supertraits,
32 },
33 Impl {
34 impl_generics: &'a Generics,
35 associated_type_impl_traits: &'a Set<Ident>,
36 },
37}
38
39impl Context<'_> {
40 fn lifetimes<'a>(&'a self, used: &'a [Lifetime]) -> impl Iterator<Item = &'a LifetimeParam> {
41 let generics = match self {
42 Context::Trait { generics, .. } => generics,
43 Context::Impl { impl_generics, .. } => impl_generics,
44 };
45 generics.params.iter().filter_map(move |param| {
46 if let GenericParam::Lifetime(param) = param {
47 if used.contains(¶m.lifetime) {
48 return Some(param);
49 }
50 }
51 None
52 })
53 }
54}
55
56pub fn expand(input: &mut Item, is_local: bool) {
57 match input {
58 Item::Trait(input) => {
59 let context = Context::Trait {
60 generics: &input.generics,
61 supertraits: &input.supertraits,
62 };
63 for inner in &mut input.items {
64 if let TraitItem::Fn(method) = inner {
65 let sig = &mut method.sig;
66 if sig.asyncness.is_some() {
67 let block = &mut method.default;
68 let mut has_self = has_self_in_sig(sig);
69 if let Some(block) = block {
70 has_self |= has_self_in_block(block);
71 transform_block(context, sig, block);
72 method.attrs.push(lint_suppress_with_body());
73 } else {
74 method.attrs.push(lint_suppress_without_body());
75 }
76 let has_default = method.default.is_some();
77 transform_sig(context, sig, has_self, has_default, is_local);
78 }
79 }
80 }
81 }
82 Item::Impl(input) => {
83 let mut associated_type_impl_traits = Set::new();
84 for inner in &input.items {
85 if let ImplItem::Type(assoc) = inner {
86 if let Type::ImplTrait(_) = assoc.ty {
87 associated_type_impl_traits.insert(assoc.ident.clone());
88 }
89 }
90 }
91
92 let context = Context::Impl {
93 impl_generics: &input.generics,
94 associated_type_impl_traits: &associated_type_impl_traits,
95 };
96 for inner in &mut input.items {
97 match inner {
98 ImplItem::Fn(method) if method.sig.asyncness.is_some() => {
99 let sig = &mut method.sig;
100 let block = &mut method.block;
101 let has_self = has_self_in_sig(sig);
102 transform_block(context, sig, block);
103 transform_sig(context, sig, has_self, false, is_local);
104 method.attrs.push(lint_suppress_with_body());
105 }
106 ImplItem::Verbatim(tokens) => {
107 let mut method = match syn::parse2::<VerbatimFn>(tokens.clone()) {
108 Ok(method) if method.sig.asyncness.is_some() => method,
109 _ => continue,
110 };
111 let sig = &mut method.sig;
112 let has_self = has_self_in_sig(sig);
113 transform_sig(context, sig, has_self, false, is_local);
114 method.attrs.push(lint_suppress_with_body());
115 *tokens = {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&method, &mut _s);
_s
}quote!(#method);
116 }
117 _ => {}
118 }
119 }
120 }
121 }
122}
123
124fn lint_suppress_with_body() -> Attribute {
125 ::syn::__private::parse_quote({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "allow");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s,
"elided_named_lifetimes");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "clippy");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s,
"async_yields_async");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "clippy");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s,
"diverging_sub_expression");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "clippy");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "let_unit_value");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "clippy");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s,
"needless_arbitrary_self_type");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "clippy");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s,
"no_effect_underscore_binding");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "clippy");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "shadow_same");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "clippy");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "type_complexity");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "clippy");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s,
"type_repetition_in_bounds");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "clippy");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s,
"used_underscore_binding");
_s
});
_s
});
_s
});parse_quote! {
126 #[allow(
127 elided_named_lifetimes,
128 clippy::async_yields_async,
129 clippy::diverging_sub_expression,
130 clippy::let_unit_value,
131 clippy::needless_arbitrary_self_type,
132 clippy::no_effect_underscore_binding,
133 clippy::shadow_same,
134 clippy::type_complexity,
135 clippy::type_repetition_in_bounds,
136 clippy::used_underscore_binding
137 )]
138 }
139}
140
141fn lint_suppress_without_body() -> Attribute {
142 ::syn::__private::parse_quote({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "allow");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s,
"elided_named_lifetimes");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "clippy");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "type_complexity");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "clippy");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s,
"type_repetition_in_bounds");
_s
});
_s
});
_s
});parse_quote! {
143 #[allow(
144 elided_named_lifetimes,
145 clippy::type_complexity,
146 clippy::type_repetition_in_bounds
147 )]
148 }
149}
150
151fn transform_sig(
165 context: Context,
166 sig: &mut Signature,
167 has_self: bool,
168 has_default: bool,
169 is_local: bool,
170) {
171 sig.fn_token.span = sig.asyncness.take().unwrap().span;
172
173 let (ret_arrow, ret) = match &sig.output {
174 ReturnType::Default => ({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_rarrow(&mut _s);
_s
}quote!(->), {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
_s
}quote!(())),
175 ReturnType::Type(arrow, ret) => ({
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&arrow, &mut _s);
_s
}quote!(#arrow), {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&ret, &mut _s);
_s
}quote!(#ret)),
176 };
177
178 let mut lifetimes = CollectLifetimes::new();
179 for arg in &mut sig.inputs {
180 match arg {
181 FnArg::Receiver(arg) => lifetimes.visit_receiver_mut(arg),
182 FnArg::Typed(arg) => lifetimes.visit_type_mut(&mut arg.ty),
183 }
184 }
185
186 for param in &mut sig.generics.params {
187 match param {
188 GenericParam::Type(param) => {
189 let param_name = ¶m.ident;
190 let span = match param.colon_token.take() {
191 Some(colon_token) => colon_token.span,
192 None => param_name.span(),
193 };
194 if param.attrs.is_empty() {
195 let bounds = mem::take(&mut param.bounds);
196 where_clause_or_default(&mut sig.generics.where_clause)
197 .predicates
198 .push(::syn::__private::parse_quote({
let _span: ::quote::__private::Span =
::quote::__private::get_span(span).__into_span();
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(¶m_name, &mut _s);
::quote::__private::push_colon_spanned(&mut _s, _span);
::quote::__private::push_lifetime_spanned(&mut _s, _span,
"\'async_trait");
::quote::__private::push_add_spanned(&mut _s, _span);
::quote::ToTokens::to_tokens(&bounds, &mut _s);
_s
})parse_quote_spanned!(span=> #param_name: 'async_trait + #bounds));
199 } else {
200 param.bounds.push(::syn::__private::parse_quote({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_lifetime(&mut _s, "\'async_trait");
_s
})parse_quote!('async_trait));
201 }
202 }
203 GenericParam::Lifetime(param) => {
204 let param_name = ¶m.lifetime;
205 let span = match param.colon_token.take() {
206 Some(colon_token) => colon_token.span,
207 None => param_name.span(),
208 };
209 if param.attrs.is_empty() {
210 let bounds = mem::take(&mut param.bounds);
211 where_clause_or_default(&mut sig.generics.where_clause)
212 .predicates
213 .push(::syn::__private::parse_quote({
let _span: ::quote::__private::Span =
::quote::__private::get_span(span).__into_span();
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(¶m, &mut _s);
::quote::__private::push_colon_spanned(&mut _s, _span);
::quote::__private::push_lifetime_spanned(&mut _s, _span,
"\'async_trait");
::quote::__private::push_add_spanned(&mut _s, _span);
::quote::ToTokens::to_tokens(&bounds, &mut _s);
_s
})parse_quote_spanned!(span=> #param: 'async_trait + #bounds));
214 } else {
215 param.bounds.push(::syn::__private::parse_quote({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_lifetime(&mut _s, "\'async_trait");
_s
})parse_quote!('async_trait));
216 }
217 }
218 GenericParam::Const(_) => {}
219 }
220 }
221
222 for param in context.lifetimes(&lifetimes.explicit) {
223 let param = ¶m.lifetime;
224 let span = param.span();
225 where_clause_or_default(&mut sig.generics.where_clause)
226 .predicates
227 .push(::syn::__private::parse_quote({
let _span: ::quote::__private::Span =
::quote::__private::get_span(span).__into_span();
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(¶m, &mut _s);
::quote::__private::push_colon_spanned(&mut _s, _span);
::quote::__private::push_lifetime_spanned(&mut _s, _span,
"\'async_trait");
_s
})parse_quote_spanned!(span=> #param: 'async_trait));
228 }
229
230 if sig.generics.lt_token.is_none() {
231 sig.generics.lt_token = Some(::syn::token::LtToken));
232 }
233 if sig.generics.gt_token.is_none() {
234 sig.generics.gt_token = Some(::syn::token::GtToken));
235 }
236
237 for elided in lifetimes.elided {
238 sig.generics.params.push(::syn::__private::parse_quote({
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&elided, &mut _s);
_s
})parse_quote!(#elided));
239 where_clause_or_default(&mut sig.generics.where_clause)
240 .predicates
241 .push(::syn::__private::parse_quote({
let _span: ::quote::__private::Span =
::quote::__private::get_span(elided.span()).__into_span();
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&elided, &mut _s);
::quote::__private::push_colon_spanned(&mut _s, _span);
::quote::__private::push_lifetime_spanned(&mut _s, _span,
"\'async_trait");
_s
})parse_quote_spanned!(elided.span()=> #elided: 'async_trait));
242 }
243
244 sig.generics.params.push(::syn::__private::parse_quote({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_lifetime(&mut _s, "\'async_trait");
_s
})parse_quote!('async_trait));
245
246 if has_self {
247 let bounds: &[InferredBound] = if is_local {
248 &[]
249 } else if let Some(receiver) = sig.receiver() {
250 match &receiver.kind {
251 ReceiverKind::Reference(_ampersand, _lifetime, None::<::syn::token::MutToken![mut]>) => {
253 &[InferredBound::Sync]
254 }
255 ReceiverKind::Typed(_colon, ty) => match ty.as_ref() {
256 Type::Reference(ty) if ty.mutability.is_none() => &[InferredBound::Sync],
258 Type::Path(ty)
260 if {
261 let segment = ty.path.segments.last().unwrap();
262 segment.ident == "Arc"
263 && match &segment.arguments {
264 PathArguments::AngleBracketed(arguments) => {
265 arguments.args.len() == 1
266 && match &arguments.args[0] {
267 GenericArgument::Type(Type::Path(arg)) => {
268 arg.path.is_ident("Self")
269 }
270 _ => false,
271 }
272 }
273 _ => false,
274 }
275 } =>
276 {
277 &[InferredBound::Sync, InferredBound::Send]
278 }
279 _ => &[InferredBound::Send],
280 },
281 _ => &[InferredBound::Send],
282 }
283 } else {
284 &[InferredBound::Send]
285 };
286
287 let bounds = bounds.iter().filter(|bound| match context {
288 Context::Trait { supertraits, .. } => has_default && !has_bound(supertraits, bound),
289 Context::Impl { .. } => false,
290 });
291
292 where_clause_or_default(&mut sig.generics.where_clause)
293 .predicates
294 .push(::syn::__private::parse_quote({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "Self");
::quote::__private::push_colon(&mut _s);
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut bounds, i) = bounds.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let bounds =
match bounds.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&bounds, &mut _s);
::quote::__private::push_add(&mut _s);
}
}
::quote::__private::push_lifetime(&mut _s, "\'async_trait");
_s
})parse_quote! {
295 Self: #(#bounds +)* 'async_trait
296 });
297 }
298
299 for (i, arg) in sig.inputs.iter_mut().enumerate() {
300 match arg {
301 FnArg::Receiver(receiver) => {
302 receiver.mutability = None;
303 }
304 FnArg::Typed(arg) => {
305 if match *arg.ty {
306 Type::Reference(_) => false,
307 _ => true,
308 } {
309 if let Pat::Ident(pat) = &mut *arg.pat {
310 pat.by_ref = None;
311 pat.mutability = None;
312 } else {
313 let positional = positional_arg(i, &arg.pat);
314 let m = mut_pat(&mut arg.pat);
315 arg.pat = ::syn::__private::parse_quote({
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&m, &mut _s);
::quote::ToTokens::to_tokens(&positional, &mut _s);
_s
})parse_quote!(#m #positional);
316 }
317 }
318 AddLifetimeToImplTrait.visit_type_mut(&mut arg.ty);
319 }
320 }
321 }
322
323 let bounds = if is_local {
324 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_lifetime(&mut _s, "\'async_trait");
_s
}quote!('async_trait)
325 } else {
326 {
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, "marker");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Send");
::quote::__private::push_add(&mut _s);
::quote::__private::push_lifetime(&mut _s, "\'async_trait");
_s
}quote!(::core::marker::Send + 'async_trait)
327 };
328 sig.output = ::syn::__private::parse_quote({
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&ret_arrow, &mut _s);
::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, "pin");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Pin");
::quote::__private::push_lt(&mut _s);
::quote::__private::push_ident(&mut _s, "Box");
::quote::__private::push_lt(&mut _s);
::quote::__private::push_ident(&mut _s, "dyn");
::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, "future");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Future");
::quote::__private::push_lt(&mut _s);
::quote::__private::push_ident(&mut _s, "Output");
::quote::__private::push_eq(&mut _s);
::quote::ToTokens::to_tokens(&ret, &mut _s);
::quote::__private::push_gt(&mut _s);
::quote::__private::push_add(&mut _s);
::quote::ToTokens::to_tokens(&bounds, &mut _s);
::quote::__private::push_shr(&mut _s);
_s
})parse_quote! {
329 #ret_arrow ::core::pin::Pin<Box<
330 dyn ::core::future::Future<Output = #ret> + #bounds
331 >>
332 };
333}
334
335fn transform_block(context: Context, sig: &mut Signature, block: &mut Block) {
353 let mut replace_self = false;
354 let decls = sig
355 .inputs
356 .iter()
357 .enumerate()
358 .map(|(i, arg)| match arg {
359 FnArg::Receiver(Receiver {
360 self_token,
361 mut mutability,
362 kind,
363 ..
364 }) => {
365 replace_self = true;
366 let ident = Ident::new("__self", self_token.span);
367 if let ReceiverKind::Reference(_ampersand, _lifetime, reference_mutability) = kind {
368 mutability = *reference_mutability;
369 }
370 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "let");
::quote::ToTokens::to_tokens(&mutability, &mut _s);
::quote::ToTokens::to_tokens(&ident, &mut _s);
::quote::__private::push_eq(&mut _s);
::quote::ToTokens::to_tokens(&self_token, &mut _s);
::quote::__private::push_semi(&mut _s);
_s
}quote!(let #mutability #ident = #self_token;)
371 }
372 FnArg::Typed(arg) => {
373 let attrs = arg.attrs.iter().filter(|attr| attr.path().is_ident("cfg"));
378
379 if let Type::Reference(_) = *arg.ty {
380 ::quote::__private::TokenStream::new()quote!()
381 } else if let Pat::Ident(PatIdent {
382 ident, mutability, ..
383 }) = &*arg.pat
384 {
385 {
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut attrs, i) = attrs.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let attrs =
match attrs.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&attrs, &mut _s);
}
}
::quote::__private::push_ident(&mut _s, "let");
::quote::ToTokens::to_tokens(&mutability, &mut _s);
::quote::ToTokens::to_tokens(&ident, &mut _s);
::quote::__private::push_eq(&mut _s);
::quote::ToTokens::to_tokens(&ident, &mut _s);
::quote::__private::push_semi(&mut _s);
_s
}quote! {
386 #(#attrs)*
387 let #mutability #ident = #ident;
388 }
389 } else {
390 let pat = &arg.pat;
391 let ident = positional_arg(i, pat);
392 if let Pat::Wild(_) = **pat {
393 {
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut attrs, i) = attrs.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let attrs =
match attrs.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&attrs, &mut _s);
}
}
::quote::__private::push_ident(&mut _s, "let");
::quote::ToTokens::to_tokens(&ident, &mut _s);
::quote::__private::push_eq(&mut _s);
::quote::ToTokens::to_tokens(&ident, &mut _s);
::quote::__private::push_semi(&mut _s);
_s
}quote! {
394 #(#attrs)*
395 let #ident = #ident;
396 }
397 } else {
398 {
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut attrs, i) = attrs.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let attrs =
match attrs.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&attrs, &mut _s);
}
}
::quote::__private::push_ident(&mut _s, "let");
::quote::ToTokens::to_tokens(&pat, &mut _s);
::quote::__private::push_eq(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "let");
::quote::ToTokens::to_tokens(&ident, &mut _s);
::quote::__private::push_eq(&mut _s);
::quote::ToTokens::to_tokens(&ident, &mut _s);
::quote::__private::push_semi(&mut _s);
::quote::ToTokens::to_tokens(&ident, &mut _s);
_s
});
::quote::__private::push_semi(&mut _s);
_s
}quote! {
399 #(#attrs)*
400 let #pat = {
401 let #ident = #ident;
402 #ident
403 };
404 }
405 }
406 }
407 }
408 })
409 .collect::<Vec<_>>();
410
411 if replace_self {
412 ReplaceSelf.visit_block_mut(block);
413 }
414
415 let let_ret = match &mut sig.output {
416 ReturnType::Default => {
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut decls, i) = decls.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let decls =
match decls.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&decls, &mut _s);
}
}
::quote::__private::push_ident(&mut _s, "let");
::quote::__private::push_underscore(&mut _s);
::quote::__private::push_colon(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
::quote::__private::push_eq(&mut _s);
::quote::ToTokens::to_tokens(&block, &mut _s);
::quote::__private::push_semi(&mut _s);
_s
}quote! {
417 #(#decls)*
418 let _: () = #block;
419 },
420 ReturnType::Type(_, ret) => {
421 if contains_associated_type_impl_trait(context, ret) {
422 if decls.is_empty() {
423 let stmts = &block.stmts;
424 {
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut stmts, i) = stmts.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let stmts =
match stmts.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&stmts, &mut _s);
}
}
_s
}quote!(#(#stmts)*)
425 } else {
426 {
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut decls, i) = decls.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let decls =
match decls.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&decls, &mut _s);
}
}
::quote::ToTokens::to_tokens(&block, &mut _s);
_s
}quote!(#(#decls)* #block)
427 }
428 } else {
429 let mut ret = ret.clone();
430 replace_impl_trait_with_infer(&mut ret);
431 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "if");
::quote::__private::push_ident(&mut _s, "let");
::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, "option");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Option");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Some");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "__ret");
_s
});
::quote::__private::push_eq(&mut _s);
::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, "option");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Option");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "None");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&ret, &mut _s);
::quote::__private::push_gt(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "allow");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "unreachable_code");
_s
});
_s
});
::quote::__private::push_ident(&mut _s, "return");
::quote::__private::push_ident(&mut _s, "__ret");
::quote::__private::push_semi(&mut _s);
_s
});
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut decls, i) = decls.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let decls =
match decls.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&decls, &mut _s);
}
}
::quote::__private::push_ident(&mut _s, "let");
::quote::__private::push_ident(&mut _s, "__ret");
::quote::__private::push_colon(&mut _s);
::quote::ToTokens::to_tokens(&ret, &mut _s);
::quote::__private::push_eq(&mut _s);
::quote::ToTokens::to_tokens(&block, &mut _s);
::quote::__private::push_semi(&mut _s);
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "allow");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "unreachable_code");
_s
});
_s
});
::quote::__private::push_ident(&mut _s, "__ret");
_s
}quote! {
432 if let ::core::option::Option::Some(__ret) = ::core::option::Option::None::<#ret> {
433 #[allow(unreachable_code)]
434 return __ret;
435 }
436 #(#decls)*
437 let __ret: #ret = #block;
438 #[allow(unreachable_code)]
439 __ret
440 }
441 }
442 }
443 };
444 let box_pin = {
let _span: ::quote::__private::Span =
::quote::__private::get_span(sig.asyncness.unwrap().span).__into_span();
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident_spanned(&mut _s, _span, "Box");
::quote::__private::push_colon2_spanned(&mut _s, _span);
::quote::__private::push_ident_spanned(&mut _s, _span, "pin");
::quote::__private::push_group_spanned(&mut _s, _span,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident_spanned(&mut _s, _span, "async");
::quote::__private::push_ident_spanned(&mut _s, _span, "move");
::quote::__private::push_group_spanned(&mut _s, _span,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&let_ret, &mut _s);
_s
});
_s
});
_s
}quote_spanned!(sig.asyncness.unwrap().span=>
445 Box::pin(async move { #let_ret })
446 );
447 block.stmts = ::syn::__private::parse_quote({
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&box_pin, &mut _s);
_s
})parse_quote!(#box_pin);
448}
449
450fn positional_arg(i: usize, pat: &Pat) -> Ident {
451 let span = syn::spanned::Spanned::span(pat).resolved_at(Span::mixed_site());
452 match ::quote::__private::IdentFragmentAdapter(&i) {
arg =>
::quote::__private::mk_ident(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("__arg{0}", arg))
}),
::quote::__private::Option::Some::<::quote::__private::Span>(span)),
}format_ident!("__arg{}", i, span = span)
453}
454
455fn contains_associated_type_impl_trait(context: Context, ret: &mut Type) -> bool {
456 struct AssociatedTypeImplTraits<'a> {
457 set: &'a Set<Ident>,
458 contains: bool,
459 }
460
461 impl<'a> VisitMut for AssociatedTypeImplTraits<'a> {
462 fn visit_type_path_mut(&mut self, ty: &mut TypePath) {
463 if ty.qself.is_none()
464 && ty.path.segments.len() == 2
465 && ty.path.segments[0].ident == "Self"
466 && self.set.contains(&ty.path.segments[1].ident)
467 {
468 self.contains = true;
469 }
470 visit_mut::visit_type_path_mut(self, ty);
471 }
472 }
473
474 match context {
475 Context::Trait { .. } => false,
476 Context::Impl {
477 associated_type_impl_traits,
478 ..
479 } => {
480 let mut visit = AssociatedTypeImplTraits {
481 set: associated_type_impl_traits,
482 contains: false,
483 };
484 visit.visit_type_mut(ret);
485 visit.contains
486 }
487 }
488}
489
490fn where_clause_or_default(clause: &mut Option<WhereClause>) -> &mut WhereClause {
491 clause.get_or_insert_with(|| WhereClause {
492 where_token: Default::default(),
493 predicates: Punctuated::new(),
494 })
495}
496
497fn replace_impl_trait_with_infer(ty: &mut Type) {
498 struct ReplaceImplTraitWithInfer;
499
500 impl VisitMut for ReplaceImplTraitWithInfer {
501 fn visit_type_mut(&mut self, ty: &mut Type) {
502 if let Type::ImplTrait(impl_trait) = ty {
503 *ty = Type::Infer(TypeInfer {
504 attrs: Vec::new(),
505 underscore_token: ::syn::token::UnderscoreToken,
506 });
507 }
508 visit_mut::visit_type_mut(self, ty);
509 }
510 }
511
512 ReplaceImplTraitWithInfer.visit_type_mut(ty);
513}