diff options
| author | mo khan <mo@mokhan.ca> | 2025-07-15 16:37:08 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-07-17 16:30:22 -0600 |
| commit | 45df4d0d9b577fecee798d672695fe24ff57fb1b (patch) | |
| tree | 1b99bf645035b58e0d6db08c7a83521f41f7a75b /vendor/async-trait/src | |
| parent | f94f79608393d4ab127db63cc41668445ef6b243 (diff) | |
feat: migrate from Cedar to SpiceDB authorization system
This is a major architectural change that replaces the Cedar policy-based
authorization system with SpiceDB's relation-based authorization.
Key changes:
- Migrate from Rust to Go implementation
- Replace Cedar policies with SpiceDB schema and relationships
- Switch from envoy `ext_authz` with Cedar to SpiceDB permission checks
- Update build system and dependencies for Go ecosystem
- Maintain Envoy integration for external authorization
This change enables more flexible permission modeling through SpiceDB's
Google Zanzibar inspired relation-based system, supporting complex
hierarchical permissions that were difficult to express in Cedar.
Breaking change: Existing Cedar policies and Rust-based configuration
will no longer work and need to be migrated to SpiceDB schema.
Diffstat (limited to 'vendor/async-trait/src')
| -rw-r--r-- | vendor/async-trait/src/args.rs | 36 | ||||
| -rw-r--r-- | vendor/async-trait/src/bound.rs | 50 | ||||
| -rw-r--r-- | vendor/async-trait/src/expand.rs | 504 | ||||
| -rw-r--r-- | vendor/async-trait/src/lib.rs | 257 | ||||
| -rw-r--r-- | vendor/async-trait/src/lifetime.rs | 112 | ||||
| -rw-r--r-- | vendor/async-trait/src/parse.rs | 34 | ||||
| -rw-r--r-- | vendor/async-trait/src/receiver.rs | 169 | ||||
| -rw-r--r-- | vendor/async-trait/src/verbatim.rs | 34 |
8 files changed, 0 insertions, 1196 deletions
diff --git a/vendor/async-trait/src/args.rs b/vendor/async-trait/src/args.rs deleted file mode 100644 index 72d97e95..00000000 --- a/vendor/async-trait/src/args.rs +++ /dev/null @@ -1,36 +0,0 @@ -use proc_macro2::Span; -use syn::parse::{Error, Parse, ParseStream, Result}; -use syn::Token; - -#[derive(Copy, Clone)] -pub struct Args { - pub local: bool, -} - -mod kw { - syn::custom_keyword!(Send); -} - -impl Parse for Args { - fn parse(input: ParseStream) -> Result<Self> { - match try_parse(input) { - Ok(args) if input.is_empty() => Ok(args), - _ => Err(error()), - } - } -} - -fn try_parse(input: ParseStream) -> Result<Args> { - if input.peek(Token![?]) { - input.parse::<Token![?]>()?; - input.parse::<kw::Send>()?; - Ok(Args { local: true }) - } else { - Ok(Args { local: false }) - } -} - -fn error() -> Error { - let msg = "expected #[async_trait] or #[async_trait(?Send)]"; - Error::new(Span::call_site(), msg) -} diff --git a/vendor/async-trait/src/bound.rs b/vendor/async-trait/src/bound.rs deleted file mode 100644 index 12105177..00000000 --- a/vendor/async-trait/src/bound.rs +++ /dev/null @@ -1,50 +0,0 @@ -use proc_macro2::{Ident, Span, TokenStream}; -use quote::{quote, ToTokens}; -use syn::punctuated::Punctuated; -use syn::{Token, TypeParamBound}; - -pub type Supertraits = Punctuated<TypeParamBound, Token![+]>; - -pub enum InferredBound { - Send, - Sync, -} - -pub fn has_bound(supertraits: &Supertraits, bound: &InferredBound) -> bool { - for supertrait in supertraits { - if let TypeParamBound::Trait(supertrait) = supertrait { - if supertrait.path.is_ident(bound) - || supertrait.path.segments.len() == 3 - && (supertrait.path.segments[0].ident == "std" - || supertrait.path.segments[0].ident == "core") - && supertrait.path.segments[1].ident == "marker" - && supertrait.path.segments[2].ident == *bound - { - return true; - } - } - } - false -} - -impl InferredBound { - fn as_str(&self) -> &str { - match self { - InferredBound::Send => "Send", - InferredBound::Sync => "Sync", - } - } -} - -impl ToTokens for InferredBound { - fn to_tokens(&self, tokens: &mut TokenStream) { - let ident = Ident::new(self.as_str(), Span::call_site()); - quote!(::core::marker::#ident).to_tokens(tokens); - } -} - -impl PartialEq<InferredBound> for Ident { - fn eq(&self, bound: &InferredBound) -> bool { - self == bound.as_str() - } -} diff --git a/vendor/async-trait/src/expand.rs b/vendor/async-trait/src/expand.rs deleted file mode 100644 index 573ad1dd..00000000 --- a/vendor/async-trait/src/expand.rs +++ /dev/null @@ -1,504 +0,0 @@ -use crate::bound::{has_bound, InferredBound, Supertraits}; -use crate::lifetime::{AddLifetimeToImplTrait, CollectLifetimes}; -use crate::parse::Item; -use crate::receiver::{has_self_in_block, has_self_in_sig, mut_pat, ReplaceSelf}; -use crate::verbatim::VerbatimFn; -use proc_macro2::{Span, TokenStream}; -use quote::{format_ident, quote, quote_spanned, ToTokens}; -use std::collections::BTreeSet as Set; -use std::mem; -use syn::punctuated::Punctuated; -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, TypeInfer, TypePath, WhereClause, -}; - -impl ToTokens for Item { - fn to_tokens(&self, tokens: &mut TokenStream) { - match self { - Item::Trait(item) => item.to_tokens(tokens), - Item::Impl(item) => item.to_tokens(tokens), - } - } -} - -#[derive(Clone, Copy)] -enum Context<'a> { - Trait { - generics: &'a Generics, - supertraits: &'a Supertraits, - }, - Impl { - impl_generics: &'a Generics, - associated_type_impl_traits: &'a Set<Ident>, - }, -} - -impl Context<'_> { - fn lifetimes<'a>(&'a self, used: &'a [Lifetime]) -> impl Iterator<Item = &'a LifetimeParam> { - let generics = match self { - Context::Trait { generics, .. } => generics, - Context::Impl { impl_generics, .. } => impl_generics, - }; - generics.params.iter().filter_map(move |param| { - if let GenericParam::Lifetime(param) = param { - if used.contains(¶m.lifetime) { - return Some(param); - } - } - None - }) - } -} - -pub fn expand(input: &mut Item, is_local: bool) { - match input { - Item::Trait(input) => { - let context = Context::Trait { - generics: &input.generics, - supertraits: &input.supertraits, - }; - for inner in &mut input.items { - if let TraitItem::Fn(method) = inner { - let sig = &mut method.sig; - if sig.asyncness.is_some() { - let block = &mut method.default; - let mut has_self = has_self_in_sig(sig); - method.attrs.push(parse_quote!(#[must_use])); - if let Some(block) = block { - has_self |= has_self_in_block(block); - transform_block(context, sig, block); - method.attrs.push(lint_suppress_with_body()); - } else { - method.attrs.push(lint_suppress_without_body()); - } - let has_default = method.default.is_some(); - transform_sig(context, sig, has_self, has_default, is_local); - } - } - } - } - Item::Impl(input) => { - let mut associated_type_impl_traits = Set::new(); - for inner in &input.items { - if let ImplItem::Type(assoc) = inner { - if let Type::ImplTrait(_) = assoc.ty { - associated_type_impl_traits.insert(assoc.ident.clone()); - } - } - } - - let context = Context::Impl { - impl_generics: &input.generics, - associated_type_impl_traits: &associated_type_impl_traits, - }; - for inner in &mut input.items { - match inner { - ImplItem::Fn(method) if method.sig.asyncness.is_some() => { - let sig = &mut method.sig; - let block = &mut method.block; - let has_self = has_self_in_sig(sig); - transform_block(context, sig, block); - transform_sig(context, sig, has_self, false, is_local); - method.attrs.push(lint_suppress_with_body()); - } - ImplItem::Verbatim(tokens) => { - let mut method = match syn::parse2::<VerbatimFn>(tokens.clone()) { - Ok(method) if method.sig.asyncness.is_some() => method, - _ => continue, - }; - let sig = &mut method.sig; - let has_self = has_self_in_sig(sig); - transform_sig(context, sig, has_self, false, is_local); - method.attrs.push(lint_suppress_with_body()); - *tokens = quote!(#method); - } - _ => {} - } - } - } - } -} - -fn lint_suppress_with_body() -> Attribute { - parse_quote! { - #[allow( - elided_named_lifetimes, - clippy::async_yields_async, - clippy::diverging_sub_expression, - clippy::let_unit_value, - clippy::needless_arbitrary_self_type, - clippy::no_effect_underscore_binding, - clippy::shadow_same, - clippy::type_complexity, - clippy::type_repetition_in_bounds, - clippy::used_underscore_binding - )] - } -} - -fn lint_suppress_without_body() -> Attribute { - parse_quote! { - #[allow( - elided_named_lifetimes, - clippy::type_complexity, - clippy::type_repetition_in_bounds - )] - } -} - -// Input: -// async fn f<T>(&self, x: &T) -> Ret; -// -// Output: -// fn f<'life0, 'life1, 'async_trait, T>( -// &'life0 self, -// x: &'life1 T, -// ) -> Pin<Box<dyn Future<Output = Ret> + Send + 'async_trait>> -// where -// 'life0: 'async_trait, -// 'life1: 'async_trait, -// T: 'async_trait, -// Self: Sync + 'async_trait; -fn transform_sig( - context: Context, - sig: &mut Signature, - has_self: bool, - has_default: bool, - is_local: bool, -) { - sig.fn_token.span = sig.asyncness.take().unwrap().span; - - let (ret_arrow, ret) = match &sig.output { - ReturnType::Default => (quote!(->), quote!(())), - ReturnType::Type(arrow, ret) => (quote!(#arrow), quote!(#ret)), - }; - - let mut lifetimes = CollectLifetimes::new(); - for arg in &mut sig.inputs { - match arg { - FnArg::Receiver(arg) => lifetimes.visit_receiver_mut(arg), - FnArg::Typed(arg) => lifetimes.visit_type_mut(&mut arg.ty), - } - } - - for param in &mut sig.generics.params { - match param { - GenericParam::Type(param) => { - let param_name = ¶m.ident; - let span = match param.colon_token.take() { - Some(colon_token) => colon_token.span, - None => param_name.span(), - }; - if param.attrs.is_empty() { - let bounds = mem::take(&mut param.bounds); - where_clause_or_default(&mut sig.generics.where_clause) - .predicates - .push(parse_quote_spanned!(span=> #param_name: 'async_trait + #bounds)); - } else { - param.bounds.push(parse_quote!('async_trait)); - } - } - GenericParam::Lifetime(param) => { - let param_name = ¶m.lifetime; - let span = match param.colon_token.take() { - Some(colon_token) => colon_token.span, - None => param_name.span(), - }; - if param.attrs.is_empty() { - let bounds = mem::take(&mut param.bounds); - where_clause_or_default(&mut sig.generics.where_clause) - .predicates - .push(parse_quote_spanned!(span=> #param: 'async_trait + #bounds)); - } else { - param.bounds.push(parse_quote!('async_trait)); - } - } - GenericParam::Const(_) => {} - } - } - - for param in context.lifetimes(&lifetimes.explicit) { - let param = ¶m.lifetime; - let span = param.span(); - where_clause_or_default(&mut sig.generics.where_clause) - .predicates - .push(parse_quote_spanned!(span=> #param: 'async_trait)); - } - - if sig.generics.lt_token.is_none() { - sig.generics.lt_token = Some(Token)); - } - if sig.generics.gt_token.is_none() { - sig.generics.gt_token = Some(Token)); - } - - for elided in lifetimes.elided { - sig.generics.params.push(parse_quote!(#elided)); - where_clause_or_default(&mut sig.generics.where_clause) - .predicates - .push(parse_quote_spanned!(elided.span()=> #elided: 'async_trait)); - } - - sig.generics.params.push(parse_quote!('async_trait)); - - if has_self { - let bounds: &[InferredBound] = if is_local { - &[] - } else if let Some(receiver) = sig.receiver() { - match receiver.ty.as_ref() { - // self: &Self - Type::Reference(ty) if ty.mutability.is_none() => &[InferredBound::Sync], - // self: Arc<Self> - Type::Path(ty) - if { - let segment = ty.path.segments.last().unwrap(); - segment.ident == "Arc" - && match &segment.arguments { - PathArguments::AngleBracketed(arguments) => { - arguments.args.len() == 1 - && match &arguments.args[0] { - GenericArgument::Type(Type::Path(arg)) => { - arg.path.is_ident("Self") - } - _ => false, - } - } - _ => false, - } - } => - { - &[InferredBound::Sync, InferredBound::Send] - } - _ => &[InferredBound::Send], - } - } else { - &[InferredBound::Send] - }; - - let bounds = bounds.iter().filter(|bound| match context { - Context::Trait { supertraits, .. } => has_default && !has_bound(supertraits, bound), - Context::Impl { .. } => false, - }); - - where_clause_or_default(&mut sig.generics.where_clause) - .predicates - .push(parse_quote! { - Self: #(#bounds +)* 'async_trait - }); - } - - for (i, arg) in sig.inputs.iter_mut().enumerate() { - match arg { - FnArg::Receiver(receiver) => { - if receiver.reference.is_none() { - receiver.mutability = None; - } - } - FnArg::Typed(arg) => { - if match *arg.ty { - Type::Reference(_) => false, - _ => true, - } { - if let Pat::Ident(pat) = &mut *arg.pat { - pat.by_ref = None; - pat.mutability = None; - } else { - let positional = positional_arg(i, &arg.pat); - let m = mut_pat(&mut arg.pat); - arg.pat = parse_quote!(#m #positional); - } - } - AddLifetimeToImplTrait.visit_type_mut(&mut arg.ty); - } - } - } - - let bounds = if is_local { - quote!('async_trait) - } else { - quote!(::core::marker::Send + 'async_trait) - }; - sig.output = parse_quote! { - #ret_arrow ::core::pin::Pin<Box< - dyn ::core::future::Future<Output = #ret> + #bounds - >> - }; -} - -// Input: -// async fn f<T>(&self, x: &T, (a, b): (A, B)) -> Ret { -// self + x + a + b -// } -// -// Output: -// Box::pin(async move { -// let ___ret: Ret = { -// let __self = self; -// let x = x; -// let (a, b) = __arg1; -// -// __self + x + a + b -// }; -// -// ___ret -// }) -fn transform_block(context: Context, sig: &mut Signature, block: &mut Block) { - let mut replace_self = false; - let decls = sig - .inputs - .iter() - .enumerate() - .map(|(i, arg)| match arg { - FnArg::Receiver(Receiver { - self_token, - mutability, - .. - }) => { - replace_self = true; - let ident = Ident::new("__self", self_token.span); - quote!(let #mutability #ident = #self_token;) - } - FnArg::Typed(arg) => { - // If there is a #[cfg(...)] attribute that selectively enables - // the parameter, forward it to the variable. - // - // This is currently not applied to the `self` parameter. - let attrs = arg.attrs.iter().filter(|attr| attr.path().is_ident("cfg")); - - if let Type::Reference(_) = *arg.ty { - quote!() - } else if let Pat::Ident(PatIdent { - ident, mutability, .. - }) = &*arg.pat - { - quote! { - #(#attrs)* - let #mutability #ident = #ident; - } - } else { - let pat = &arg.pat; - let ident = positional_arg(i, pat); - if let Pat::Wild(_) = **pat { - quote! { - #(#attrs)* - let #ident = #ident; - } - } else { - quote! { - #(#attrs)* - let #pat = { - let #ident = #ident; - #ident - }; - } - } - } - } - }) - .collect::<Vec<_>>(); - - if replace_self { - ReplaceSelf.visit_block_mut(block); - } - - let stmts = &block.stmts; - let let_ret = match &mut sig.output { - ReturnType::Default => quote_spanned! {block.brace_token.span=> - #(#decls)* - let () = { #(#stmts)* }; - }, - ReturnType::Type(_, ret) => { - if contains_associated_type_impl_trait(context, ret) { - if decls.is_empty() { - quote!(#(#stmts)*) - } else { - 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)] - return __ret; - } - #(#decls)* - let __ret: #ret = { #(#stmts)* }; - #[allow(unreachable_code)] - __ret - } - } - } - }; - let box_pin = quote_spanned!(block.brace_token.span=> - Box::pin(async move { #let_ret }) - ); - block.stmts = parse_quote!(#box_pin); -} - -fn positional_arg(i: usize, pat: &Pat) -> Ident { - let span = syn::spanned::Spanned::span(pat).resolved_at(Span::mixed_site()); - format_ident!("__arg{}", i, span = span) -} - -fn contains_associated_type_impl_trait(context: Context, ret: &mut Type) -> bool { - struct AssociatedTypeImplTraits<'a> { - set: &'a Set<Ident>, - contains: bool, - } - - impl<'a> VisitMut for AssociatedTypeImplTraits<'a> { - fn visit_type_path_mut(&mut self, ty: &mut TypePath) { - if ty.qself.is_none() - && ty.path.segments.len() == 2 - && ty.path.segments[0].ident == "Self" - && self.set.contains(&ty.path.segments[1].ident) - { - self.contains = true; - } - visit_mut::visit_type_path_mut(self, ty); - } - } - - match context { - Context::Trait { .. } => false, - Context::Impl { - associated_type_impl_traits, - .. - } => { - let mut visit = AssociatedTypeImplTraits { - set: associated_type_impl_traits, - contains: false, - }; - visit.visit_type_mut(ret); - visit.contains - } - } -} - -fn where_clause_or_default(clause: &mut Option<WhereClause>) -> &mut WhereClause { - clause.get_or_insert_with(|| WhereClause { - where_token: Default::default(), - 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, - }); - } - visit_mut::visit_type_mut(self, ty); - } - } - - ReplaceImplTraitWithInfer.visit_type_mut(ty); -} diff --git a/vendor/async-trait/src/lib.rs b/vendor/async-trait/src/lib.rs deleted file mode 100644 index bc9bd923..00000000 --- a/vendor/async-trait/src/lib.rs +++ /dev/null @@ -1,257 +0,0 @@ -//! [![github]](https://github.com/dtolnay/async-trait) [![crates-io]](https://crates.io/crates/async-trait) [![docs-rs]](https://docs.rs/async-trait) -//! -//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github -//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust -//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs -//! -//! <br> -//! -//! <h4>Type erasure for async trait methods</h4> -//! -//! The stabilization of async functions in traits in Rust 1.75 did not include -//! support for using traits containing async functions as `dyn Trait`. Trying -//! to use dyn with an async trait produces the following error: -//! -//! ```compile_fail -//! pub trait Trait { -//! async fn f(&self); -//! } -//! -//! pub fn make() -> Box<dyn Trait> { -//! unimplemented!() -//! } -//! ``` -//! -//! ```text -//! error[E0038]: the trait `Trait` is not dyn compatible -//! --> src/main.rs:5:22 -//! | -//! 5 | pub fn make() -> Box<dyn Trait> { -//! | ^^^^^^^^^ `Trait` is not dyn compatible -//! | -//! note: for a trait to be dyn compatible it needs to allow building a vtable -//! for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> -//! --> src/main.rs:2:14 -//! | -//! 1 | pub trait Trait { -//! | ----- this trait is not dyn compatible... -//! 2 | async fn f(&self); -//! | ^ ...because method `f` is `async` -//! = help: consider moving `f` to another trait -//! ``` -//! -//! This crate provides an attribute macro to make async fn in traits work with -//! dyn traits. -//! -//! Please refer to [*why async fn in traits are hard*][hard] for a deeper -//! analysis of how this implementation differs from what the compiler and -//! language deliver natively. -//! -//! [hard]: https://smallcultfollowing.com/babysteps/blog/2019/10/26/async-fn-in-traits-are-hard/ -//! -//! <br> -//! -//! # Example -//! -//! This example implements the core of a highly effective advertising platform -//! using async fn in a trait. -//! -//! The only thing to notice here is that we write an `#[async_trait]` macro on -//! top of traits and trait impls that contain async fn, and then they work. We -//! get to have `Vec<Box<dyn Advertisement + Sync>>` or `&[&dyn Advertisement]`, -//! for example. -//! -//! ``` -//! use async_trait::async_trait; -//! -//! #[async_trait] -//! trait Advertisement { -//! async fn run(&self); -//! } -//! -//! struct Modal; -//! -//! #[async_trait] -//! impl Advertisement for Modal { -//! async fn run(&self) { -//! self.render_fullscreen().await; -//! for _ in 0..4u16 { -//! remind_user_to_join_mailing_list().await; -//! } -//! self.hide_for_now().await; -//! } -//! } -//! -//! struct AutoplayingVideo { -//! media_url: String, -//! } -//! -//! #[async_trait] -//! impl Advertisement for AutoplayingVideo { -//! async fn run(&self) { -//! let stream = connect(&self.media_url).await; -//! stream.play().await; -//! -//! // Video probably persuaded user to join our mailing list! -//! Modal.run().await; -//! } -//! } -//! # -//! # impl Modal { -//! # async fn render_fullscreen(&self) {} -//! # async fn hide_for_now(&self) {} -//! # } -//! # -//! # async fn remind_user_to_join_mailing_list() {} -//! # -//! # struct Stream; -//! # async fn connect(_media_url: &str) -> Stream { Stream } -//! # impl Stream { -//! # async fn play(&self) {} -//! # } -//! ``` -//! -//! <br><br> -//! -//! # Supported features -//! -//! It is the intention that all features of Rust traits should work nicely with -//! #\[async_trait\], but the edge cases are numerous. Please file an issue if -//! you see unexpected borrow checker errors, type errors, or warnings. There is -//! no use of `unsafe` in the expanded code, so rest assured that if your code -//! compiles it can't be that badly broken. -//! -//! > ☑ Self by value, by reference, by mut reference, or no self;<br> -//! > ☑ Any number of arguments, any return value;<br> -//! > ☑ Generic type parameters and lifetime parameters;<br> -//! > ☑ Associated types;<br> -//! > ☑ Having async and non-async functions in the same trait;<br> -//! > ☑ Default implementations provided by the trait;<br> -//! > ☑ Elided lifetimes.<br> -//! -//! <br> -//! -//! # Explanation -//! -//! Async fns get transformed into methods that return `Pin<Box<dyn Future + -//! Send + 'async_trait>>` and delegate to an async block. -//! -//! For example the `impl Advertisement for AutoplayingVideo` above would be -//! expanded as: -//! -//! ``` -//! # const IGNORE: &str = stringify! { -//! impl Advertisement for AutoplayingVideo { -//! fn run<'async_trait>( -//! &'async_trait self, -//! ) -> Pin<Box<dyn core::future::Future<Output = ()> + Send + 'async_trait>> -//! where -//! Self: Sync + 'async_trait, -//! { -//! Box::pin(async move { -//! /* the original method body */ -//! }) -//! } -//! } -//! # }; -//! ``` -//! -//! <br><br> -//! -//! # Non-threadsafe futures -//! -//! Not all async traits need futures that are `dyn Future + Send`. To avoid -//! having Send and Sync bounds placed on the async trait methods, invoke the -//! async trait macro as `#[async_trait(?Send)]` on both the trait and the impl -//! blocks. -//! -//! <br> -//! -//! # Elided lifetimes -//! -//! Be aware that async fn syntax does not allow lifetime elision outside of `&` -//! and `&mut` references. (This is true even when not using #\[async_trait\].) -//! Lifetimes must be named or marked by the placeholder `'_`. -//! -//! Fortunately the compiler is able to diagnose missing lifetimes with a good -//! error message. -//! -//! ```compile_fail -//! # use async_trait::async_trait; -//! # -//! type Elided<'a> = &'a usize; -//! -//! #[async_trait] -//! trait Test { -//! async fn test(not_okay: Elided, okay: &usize) {} -//! } -//! ``` -//! -//! ```text -//! error[E0726]: implicit elided lifetime not allowed here -//! --> src/main.rs:9:29 -//! | -//! 9 | async fn test(not_okay: Elided, okay: &usize) {} -//! | ^^^^^^- help: indicate the anonymous lifetime: `<'_>` -//! ``` -//! -//! The fix is to name the lifetime or use `'_`. -//! -//! ``` -//! # use async_trait::async_trait; -//! # -//! # type Elided<'a> = &'a usize; -//! # -//! #[async_trait] -//! trait Test { -//! // either -//! async fn test<'e>(elided: Elided<'e>) {} -//! # } -//! # #[async_trait] -//! # trait Test2 { -//! // or -//! async fn test(elided: Elided<'_>) {} -//! } -//! ``` - -#![doc(html_root_url = "https://docs.rs/async-trait/0.1.88")] -#![allow( - clippy::default_trait_access, - clippy::doc_markdown, - clippy::elidable_lifetime_names, - clippy::explicit_auto_deref, - clippy::if_not_else, - clippy::items_after_statements, - clippy::match_like_matches_macro, - clippy::module_name_repetitions, - clippy::needless_lifetimes, - clippy::shadow_unrelated, - clippy::similar_names, - clippy::too_many_lines, - clippy::trivially_copy_pass_by_ref -)] - -extern crate proc_macro; - -mod args; -mod bound; -mod expand; -mod lifetime; -mod parse; -mod receiver; -mod verbatim; - -use crate::args::Args; -use crate::expand::expand; -use crate::parse::Item; -use proc_macro::TokenStream; -use quote::quote; -use syn::parse_macro_input; - -#[proc_macro_attribute] -pub fn async_trait(args: TokenStream, input: TokenStream) -> TokenStream { - let args = parse_macro_input!(args as Args); - let mut item = parse_macro_input!(input as Item); - expand(&mut item, args.local); - TokenStream::from(quote!(#item)) -} diff --git a/vendor/async-trait/src/lifetime.rs b/vendor/async-trait/src/lifetime.rs deleted file mode 100644 index 60658616..00000000 --- a/vendor/async-trait/src/lifetime.rs +++ /dev/null @@ -1,112 +0,0 @@ -use proc_macro2::{Span, TokenStream}; -use std::mem; -use syn::visit_mut::{self, VisitMut}; -use syn::{ - parse_quote_spanned, token, Expr, GenericArgument, Lifetime, Receiver, ReturnType, Token, Type, - TypeBareFn, TypeImplTrait, TypeParen, TypePtr, TypeReference, -}; - -pub struct CollectLifetimes { - pub elided: Vec<Lifetime>, - pub explicit: Vec<Lifetime>, -} - -impl CollectLifetimes { - pub fn new() -> Self { - CollectLifetimes { - elided: Vec::new(), - explicit: Vec::new(), - } - } - - fn visit_opt_lifetime(&mut self, reference: &Token![&], lifetime: &mut Option<Lifetime>) { - match lifetime { - None => *lifetime = Some(self.next_lifetime(reference.span)), - Some(lifetime) => self.visit_lifetime(lifetime), - } - } - - fn visit_lifetime(&mut self, lifetime: &mut Lifetime) { - if lifetime.ident == "_" { - *lifetime = self.next_lifetime(lifetime.span()); - } else { - self.explicit.push(lifetime.clone()); - } - } - - fn next_lifetime(&mut self, span: Span) -> Lifetime { - let name = format!("'life{}", self.elided.len()); - let life = Lifetime::new(&name, span); - self.elided.push(life.clone()); - life - } -} - -impl VisitMut for CollectLifetimes { - fn visit_receiver_mut(&mut self, arg: &mut Receiver) { - if let Some((reference, lifetime)) = &mut arg.reference { - self.visit_opt_lifetime(reference, lifetime); - } else { - visit_mut::visit_type_mut(self, &mut arg.ty); - } - } - - fn visit_type_reference_mut(&mut self, ty: &mut TypeReference) { - self.visit_opt_lifetime(&ty.and_token, &mut ty.lifetime); - visit_mut::visit_type_reference_mut(self, ty); - } - - fn visit_generic_argument_mut(&mut self, gen: &mut GenericArgument) { - if let GenericArgument::Lifetime(lifetime) = gen { - self.visit_lifetime(lifetime); - } - visit_mut::visit_generic_argument_mut(self, gen); - } -} - -pub struct AddLifetimeToImplTrait; - -impl VisitMut for AddLifetimeToImplTrait { - fn visit_type_impl_trait_mut(&mut self, ty: &mut TypeImplTrait) { - let span = ty.impl_token.span; - let lifetime = parse_quote_spanned!(span=> 'async_trait); - ty.bounds.insert(0, lifetime); - if let Some(punct) = ty.bounds.pairs_mut().next().unwrap().punct_mut() { - punct.span = span; - } - visit_mut::visit_type_impl_trait_mut(self, ty); - } - - fn visit_type_reference_mut(&mut self, ty: &mut TypeReference) { - parenthesize_impl_trait(&mut ty.elem, ty.and_token.span); - visit_mut::visit_type_reference_mut(self, ty); - } - - fn visit_type_ptr_mut(&mut self, ty: &mut TypePtr) { - parenthesize_impl_trait(&mut ty.elem, ty.star_token.span); - visit_mut::visit_type_ptr_mut(self, ty); - } - - fn visit_type_bare_fn_mut(&mut self, ty: &mut TypeBareFn) { - if let ReturnType::Type(arrow, return_type) = &mut ty.output { - parenthesize_impl_trait(return_type, arrow.spans[0]); - } - visit_mut::visit_type_bare_fn_mut(self, ty); - } - - fn visit_expr_mut(&mut self, _e: &mut Expr) { - // Do not recurse into impl Traits inside of an array length expression. - // - // fn outer(arg: [u8; { fn inner(_: impl Trait) {}; 0 }]); - } -} - -fn parenthesize_impl_trait(elem: &mut Type, paren_span: Span) { - if let Type::ImplTrait(_) = *elem { - let placeholder = Type::Verbatim(TokenStream::new()); - *elem = Type::Paren(TypeParen { - paren_token: token::Paren(paren_span), - elem: Box::new(mem::replace(elem, placeholder)), - }); - } -} diff --git a/vendor/async-trait/src/parse.rs b/vendor/async-trait/src/parse.rs deleted file mode 100644 index ebd25351..00000000 --- a/vendor/async-trait/src/parse.rs +++ /dev/null @@ -1,34 +0,0 @@ -use proc_macro2::Span; -use syn::parse::{Error, Parse, ParseStream, Result}; -use syn::{Attribute, ItemImpl, ItemTrait, Token}; - -pub enum Item { - Trait(ItemTrait), - Impl(ItemImpl), -} - -impl Parse for Item { - fn parse(input: ParseStream) -> Result<Self> { - let attrs = input.call(Attribute::parse_outer)?; - let mut lookahead = input.lookahead1(); - if lookahead.peek(Token![unsafe]) { - let ahead = input.fork(); - ahead.parse::<Token![unsafe]>()?; - lookahead = ahead.lookahead1(); - } - if lookahead.peek(Token![pub]) || lookahead.peek(Token![trait]) { - let mut item: ItemTrait = input.parse()?; - item.attrs = attrs; - Ok(Item::Trait(item)) - } else if lookahead.peek(Token![impl]) { - let mut item: ItemImpl = input.parse()?; - if item.trait_.is_none() { - return Err(Error::new(Span::call_site(), "expected a trait impl")); - } - item.attrs = attrs; - Ok(Item::Impl(item)) - } else { - Err(lookahead.error()) - } - } -} diff --git a/vendor/async-trait/src/receiver.rs b/vendor/async-trait/src/receiver.rs deleted file mode 100644 index 1531be62..00000000 --- a/vendor/async-trait/src/receiver.rs +++ /dev/null @@ -1,169 +0,0 @@ -use proc_macro2::{Group, TokenStream, TokenTree}; -use syn::visit_mut::{self, VisitMut}; -use syn::{ - Block, ExprPath, Ident, Item, Macro, Pat, PatIdent, Path, Receiver, Signature, Token, TypePath, -}; - -pub fn has_self_in_sig(sig: &mut Signature) -> bool { - let mut visitor = HasSelf(false); - visitor.visit_signature_mut(sig); - visitor.0 -} - -pub fn has_self_in_block(block: &mut Block) -> bool { - let mut visitor = HasSelf(false); - visitor.visit_block_mut(block); - visitor.0 -} - -fn has_self_in_token_stream(tokens: TokenStream) -> bool { - tokens.into_iter().any(|tt| match tt { - TokenTree::Ident(ident) => ident == "Self", - TokenTree::Group(group) => has_self_in_token_stream(group.stream()), - _ => false, - }) -} - -pub fn mut_pat(pat: &mut Pat) -> Option<Token![mut]> { - let mut visitor = HasMutPat(None); - visitor.visit_pat_mut(pat); - visitor.0 -} - -fn contains_fn(tokens: TokenStream) -> bool { - tokens.into_iter().any(|tt| match tt { - TokenTree::Ident(ident) => ident == "fn", - TokenTree::Group(group) => contains_fn(group.stream()), - _ => false, - }) -} - -struct HasMutPat(Option<Token![mut]>); - -impl VisitMut for HasMutPat { - fn visit_pat_ident_mut(&mut self, i: &mut PatIdent) { - if let Some(m) = &i.mutability { - self.0 = Some(Token); - } else { - visit_mut::visit_pat_ident_mut(self, i); - } - } -} - -struct HasSelf(bool); - -impl VisitMut for HasSelf { - fn visit_expr_path_mut(&mut self, expr: &mut ExprPath) { - self.0 |= expr.path.segments[0].ident == "Self"; - visit_mut::visit_expr_path_mut(self, expr); - } - - fn visit_type_path_mut(&mut self, ty: &mut TypePath) { - self.0 |= ty.path.segments[0].ident == "Self"; - visit_mut::visit_type_path_mut(self, ty); - } - - fn visit_receiver_mut(&mut self, _arg: &mut Receiver) { - self.0 = true; - } - - fn visit_item_mut(&mut self, _: &mut Item) { - // Do not recurse into nested items. - } - - fn visit_macro_mut(&mut self, mac: &mut Macro) { - if !contains_fn(mac.tokens.clone()) { - self.0 |= has_self_in_token_stream(mac.tokens.clone()); - } - } -} - -pub struct ReplaceSelf; - -fn prepend_underscore_to_self(ident: &mut Ident) -> bool { - let modified = ident == "self"; - if modified { - *ident = Ident::new("__self", ident.span()); - } - modified -} - -impl ReplaceSelf { - fn visit_token_stream(&mut self, tokens: &mut TokenStream) -> bool { - let mut out = Vec::new(); - let mut modified = false; - visit_token_stream_impl(self, tokens.clone(), &mut modified, &mut out); - if modified { - *tokens = TokenStream::from_iter(out); - } - return modified; - - fn visit_token_stream_impl( - visitor: &mut ReplaceSelf, - tokens: TokenStream, - modified: &mut bool, - out: &mut Vec<TokenTree>, - ) { - for tt in tokens { - match tt { - TokenTree::Ident(mut ident) => { - *modified |= prepend_underscore_to_self(&mut ident); - out.push(TokenTree::Ident(ident)); - } - TokenTree::Group(group) => { - let mut content = group.stream(); - *modified |= visitor.visit_token_stream(&mut content); - let mut new = Group::new(group.delimiter(), content); - new.set_span(group.span()); - out.push(TokenTree::Group(new)); - } - other => out.push(other), - } - } - } - } -} - -impl VisitMut for ReplaceSelf { - fn visit_ident_mut(&mut self, i: &mut Ident) { - prepend_underscore_to_self(i); - } - - fn visit_path_mut(&mut self, p: &mut Path) { - if p.segments.len() == 1 { - // Replace `self`, but not `self::function`. - self.visit_ident_mut(&mut p.segments[0].ident); - } - for segment in &mut p.segments { - self.visit_path_arguments_mut(&mut segment.arguments); - } - } - - fn visit_item_mut(&mut self, i: &mut Item) { - // Visit `macro_rules!` because locally defined macros can refer to - // `self`. - // - // Visit `futures::select` and similar select macros, which commonly - // appear syntactically like an item despite expanding to an expression. - // - // Otherwise, do not recurse into nested items. - if let Item::Macro(i) = i { - if i.mac.path.is_ident("macro_rules") - || i.mac.path.segments.last().unwrap().ident == "select" - { - self.visit_macro_mut(&mut i.mac); - } - } - } - - fn visit_macro_mut(&mut self, mac: &mut Macro) { - // We can't tell in general whether `self` inside a macro invocation - // refers to the self in the argument list or a different self - // introduced within the macro. Heuristic: if the macro input contains - // `fn`, then `self` is more likely to refer to something other than the - // outer function's self argument. - if !contains_fn(mac.tokens.clone()) { - self.visit_token_stream(&mut mac.tokens); - } - } -} diff --git a/vendor/async-trait/src/verbatim.rs b/vendor/async-trait/src/verbatim.rs deleted file mode 100644 index d064f6ee..00000000 --- a/vendor/async-trait/src/verbatim.rs +++ /dev/null @@ -1,34 +0,0 @@ -use proc_macro2::TokenStream; -use quote::{ToTokens, TokenStreamExt}; -use syn::parse::{Parse, ParseStream, Result}; -use syn::{Attribute, Signature, Token, Visibility}; - -pub struct VerbatimFn { - pub attrs: Vec<Attribute>, - pub vis: Visibility, - pub defaultness: Option<Token![default]>, - pub sig: Signature, - pub semi_token: Token![;], -} - -impl Parse for VerbatimFn { - fn parse(input: ParseStream) -> Result<Self> { - Ok(VerbatimFn { - attrs: input.call(Attribute::parse_outer)?, - vis: input.parse()?, - defaultness: input.parse()?, - sig: input.parse()?, - semi_token: input.parse()?, - }) - } -} - -impl ToTokens for VerbatimFn { - fn to_tokens(&self, tokens: &mut TokenStream) { - tokens.append_all(&self.attrs); - self.vis.to_tokens(tokens); - self.defaultness.to_tokens(tokens); - self.sig.to_tokens(tokens); - self.semi_token.to_tokens(tokens); - } -} |
