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