From 85b572c44236deab9550572183953b9df743939d Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 2 Jan 2025 20:19:08 -0800 Subject: [PATCH] Support impl Trait in return type --- Cargo.toml | 2 +- src/expand.rs | 21 ++++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3590089..050b10a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ proc-macro = true [dependencies] proc-macro2 = "1.0.74" quote = "1.0.35" -syn = { version = "2.0.46", default-features = false, features = ["full", "parsing", "printing", "proc-macro", "visit-mut"] } +syn = { version = "2.0.46", default-features = false, features = ["clone-impls", "full", "parsing", "printing", "proc-macro", "visit-mut"] } [dev-dependencies] futures = "0.3.30" diff --git a/src/expand.rs b/src/expand.rs index 5adba58..df02106 100644 --- a/src/expand.rs +++ b/src/expand.rs @@ -12,7 +12,7 @@ use syn::visit_mut::{self, VisitMut}; use syn::{ parse_quote, parse_quote_spanned, Attribute, Block, FnArg, GenericArgument, GenericParam, Generics, Ident, ImplItem, Lifetime, LifetimeParam, Pat, PatIdent, PathArguments, Receiver, - ReturnType, Signature, Token, TraitItem, Type, TypePath, WhereClause, + ReturnType, Signature, Token, TraitItem, Type, TypeInfer, TypePath, WhereClause, }; impl ToTokens for Item { @@ -410,6 +410,8 @@ fn transform_block(context: Context, sig: &mut Signature, block: &mut Block) { quote!(#(#decls)* { #(#stmts)* }) } } else { + let mut ret = ret.clone(); + replace_impl_trait_with_infer(&mut ret); quote! { if let ::core::option::Option::Some(__ret) = ::core::option::Option::None::<#ret> { #[allow(unreachable_code)] @@ -475,3 +477,20 @@ fn where_clause_or_default(clause: &mut Option) -> &mut WhereClause predicates: Punctuated::new(), }) } + +fn replace_impl_trait_with_infer(ty: &mut Type) { + struct ReplaceImplTraitWithInfer; + + impl VisitMut for ReplaceImplTraitWithInfer { + fn visit_type_mut(&mut self, ty: &mut Type) { + if let Type::ImplTrait(impl_trait) = ty { + *ty = Type::Infer(TypeInfer { + underscore_token: Token![_](impl_trait.impl_token.span), + }); + } + visit_mut::visit_type_mut(self, ty); + } + } + + ReplaceImplTraitWithInfer.visit_type_mut(ty); +}