Skip to content

Commit

Permalink
Support impl Trait in return type
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Jan 3, 2025
1 parent aff365f commit 85b572c
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
21 changes: 20 additions & 1 deletion src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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)]
Expand Down Expand Up @@ -475,3 +477,20 @@ fn where_clause_or_default(clause: &mut Option<WhereClause>) -> &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);
}

0 comments on commit 85b572c

Please sign in to comment.