summaryrefslogtreecommitdiffstats
path: root/vendor/tracing-attributes/src
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/tracing-attributes/src')
-rw-r--r--vendor/tracing-attributes/src/expand.rs118
-rw-r--r--vendor/tracing-attributes/src/lib.rs60
2 files changed, 125 insertions, 53 deletions
diff --git a/vendor/tracing-attributes/src/expand.rs b/vendor/tracing-attributes/src/expand.rs
index 81ee6ed90..7005b4423 100644
--- a/vendor/tracing-attributes/src/expand.rs
+++ b/vendor/tracing-attributes/src/expand.rs
@@ -2,15 +2,16 @@ use std::iter;
use proc_macro2::TokenStream;
use quote::{quote, quote_spanned, ToTokens};
+use syn::visit_mut::VisitMut;
use syn::{
punctuated::Punctuated, spanned::Spanned, Block, Expr, ExprAsync, ExprCall, FieldPat, FnArg,
Ident, Item, ItemFn, Pat, PatIdent, PatReference, PatStruct, PatTuple, PatTupleStruct, PatType,
- Path, Signature, Stmt, Token, TypePath,
+ Path, ReturnType, Signature, Stmt, Token, Type, TypePath,
};
use crate::{
attr::{Field, Fields, FormatMode, InstrumentArgs},
- MaybeItemFnRef,
+ MaybeItemFn, MaybeItemFnRef,
};
/// Given an existing function, generate an instrumented version of that function
@@ -18,20 +19,21 @@ pub(crate) fn gen_function<'a, B: ToTokens + 'a>(
input: MaybeItemFnRef<'a, B>,
args: InstrumentArgs,
instrumented_function_name: &str,
- self_type: Option<&syn::TypePath>,
+ self_type: Option<&TypePath>,
) -> proc_macro2::TokenStream {
// these are needed ahead of time, as ItemFn contains the function body _and_
// isn't representable inside a quote!/quote_spanned! macro
// (Syn's ToTokens isn't implemented for ItemFn)
let MaybeItemFnRef {
- attrs,
+ outer_attrs,
+ inner_attrs,
vis,
sig,
block,
} = input;
let Signature {
- output: return_type,
+ output,
inputs: params,
unsafety,
asyncness,
@@ -49,8 +51,35 @@ pub(crate) fn gen_function<'a, B: ToTokens + 'a>(
let warnings = args.warnings();
+ let (return_type, return_span) = if let ReturnType::Type(_, return_type) = &output {
+ (erase_impl_trait(return_type), return_type.span())
+ } else {
+ // Point at function name if we don't have an explicit return type
+ (syn::parse_quote! { () }, ident.span())
+ };
+ // Install a fake return statement as the first thing in the function
+ // body, so that we eagerly infer that the return type is what we
+ // declared in the async fn signature.
+ // The `#[allow(..)]` is given because the return statement is
+ // unreachable, but does affect inference, so it needs to be written
+ // exactly that way for it to do its magic.
+ let fake_return_edge = quote_spanned! {return_span=>
+ #[allow(unreachable_code, clippy::diverging_sub_expression, clippy::let_unit_value)]
+ if false {
+ let __tracing_attr_fake_return: #return_type =
+ unreachable!("this is just for type inference, and is unreachable code");
+ return __tracing_attr_fake_return;
+ }
+ };
+ let block = quote! {
+ {
+ #fake_return_edge
+ #block
+ }
+ };
+
let body = gen_block(
- block,
+ &block,
params,
asyncness.is_some(),
args,
@@ -59,10 +88,11 @@ pub(crate) fn gen_function<'a, B: ToTokens + 'a>(
);
quote!(
- #(#attrs) *
- #vis #constness #unsafety #asyncness #abi fn #ident<#gen_params>(#params) #return_type
+ #(#outer_attrs) *
+ #vis #constness #unsafety #asyncness #abi fn #ident<#gen_params>(#params) #output
#where_clause
{
+ #(#inner_attrs) *
#warnings
#body
}
@@ -76,7 +106,7 @@ fn gen_block<B: ToTokens>(
async_context: bool,
mut args: InstrumentArgs,
instrumented_function_name: &str,
- self_type: Option<&syn::TypePath>,
+ self_type: Option<&TypePath>,
) -> proc_macro2::TokenStream {
// generate the span's name
let span_name = args
@@ -393,11 +423,11 @@ impl RecordType {
"Wrapping",
];
- /// Parse `RecordType` from [syn::Type] by looking up
+ /// Parse `RecordType` from [Type] by looking up
/// the [RecordType::TYPES_FOR_VALUE] array.
- fn parse_from_ty(ty: &syn::Type) -> Self {
+ fn parse_from_ty(ty: &Type) -> Self {
match ty {
- syn::Type::Path(syn::TypePath { path, .. })
+ Type::Path(TypePath { path, .. })
if path
.segments
.iter()
@@ -410,9 +440,7 @@ impl RecordType {
{
RecordType::Value
}
- syn::Type::Reference(syn::TypeReference { elem, .. }) => {
- RecordType::parse_from_ty(&*elem)
- }
+ Type::Reference(syn::TypeReference { elem, .. }) => RecordType::parse_from_ty(elem),
_ => RecordType::Debug,
}
}
@@ -471,7 +499,7 @@ pub(crate) struct AsyncInfo<'block> {
// statement that must be patched
source_stmt: &'block Stmt,
kind: AsyncKind<'block>,
- self_type: Option<syn::TypePath>,
+ self_type: Option<TypePath>,
input: &'block ItemFn,
}
@@ -606,11 +634,11 @@ impl<'block> AsyncInfo<'block> {
if ident == "_self" {
let mut ty = *ty.ty.clone();
// extract the inner type if the argument is "&self" or "&mut self"
- if let syn::Type::Reference(syn::TypeReference { elem, .. }) = ty {
+ if let Type::Reference(syn::TypeReference { elem, .. }) = ty {
ty = *elem;
}
- if let syn::Type::Path(tp) = ty {
+ if let Type::Path(tp) = ty {
self_type = Some(tp);
break;
}
@@ -631,7 +659,7 @@ impl<'block> AsyncInfo<'block> {
self,
args: InstrumentArgs,
instrumented_function_name: &str,
- ) -> proc_macro::TokenStream {
+ ) -> Result<proc_macro::TokenStream, syn::Error> {
// let's rewrite some statements!
let mut out_stmts: Vec<TokenStream> = self
.input
@@ -652,12 +680,15 @@ impl<'block> AsyncInfo<'block> {
// instrument the future by rewriting the corresponding statement
out_stmts[iter] = match self.kind {
// `Box::pin(immediately_invoked_async_fn())`
- AsyncKind::Function(fun) => gen_function(
- fun.into(),
- args,
- instrumented_function_name,
- self.self_type.as_ref(),
- ),
+ AsyncKind::Function(fun) => {
+ let fun = MaybeItemFn::from(fun.clone());
+ gen_function(
+ fun.as_ref(),
+ args,
+ instrumented_function_name,
+ self.self_type.as_ref(),
+ )
+ }
// `async move { ... }`, optionally pinned
AsyncKind::Async {
async_expr,
@@ -688,13 +719,13 @@ impl<'block> AsyncInfo<'block> {
let vis = &self.input.vis;
let sig = &self.input.sig;
let attrs = &self.input.attrs;
- quote!(
+ Ok(quote!(
#(#attrs) *
#vis #sig {
#(#out_stmts) *
}
)
- .into()
+ .into())
}
}
@@ -722,7 +753,7 @@ struct IdentAndTypesRenamer<'a> {
idents: Vec<(Ident, Ident)>,
}
-impl<'a> syn::visit_mut::VisitMut for IdentAndTypesRenamer<'a> {
+impl<'a> VisitMut for IdentAndTypesRenamer<'a> {
// we deliberately compare strings because we want to ignore the spans
// If we apply clippy's lint, the behavior changes
#[allow(clippy::cmp_owned)]
@@ -734,11 +765,11 @@ impl<'a> syn::visit_mut::VisitMut for IdentAndTypesRenamer<'a> {
}
}
- fn visit_type_mut(&mut self, ty: &mut syn::Type) {
+ fn visit_type_mut(&mut self, ty: &mut Type) {
for (type_name, new_type) in &self.types {
- if let syn::Type::Path(TypePath { path, .. }) = ty {
+ if let Type::Path(TypePath { path, .. }) = ty {
if path_to_string(path) == *type_name {
- *ty = syn::Type::Path(new_type.clone());
+ *ty = Type::Path(new_type.clone());
}
}
}
@@ -751,10 +782,33 @@ struct AsyncTraitBlockReplacer<'a> {
patched_block: Block,
}
-impl<'a> syn::visit_mut::VisitMut for AsyncTraitBlockReplacer<'a> {
+impl<'a> VisitMut for AsyncTraitBlockReplacer<'a> {
fn visit_block_mut(&mut self, i: &mut Block) {
if i == self.block {
*i = self.patched_block.clone();
}
}
}
+
+// Replaces any `impl Trait` with `_` so it can be used as the type in
+// a `let` statement's LHS.
+struct ImplTraitEraser;
+
+impl VisitMut for ImplTraitEraser {
+ fn visit_type_mut(&mut self, t: &mut Type) {
+ if let Type::ImplTrait(..) = t {
+ *t = syn::TypeInfer {
+ underscore_token: Token![_](t.span()),
+ }
+ .into();
+ } else {
+ syn::visit_mut::visit_type_mut(self, t);
+ }
+ }
+}
+
+fn erase_impl_trait(ty: &Type) -> Type {
+ let mut ty = ty.clone();
+ ImplTraitEraser.visit_type_mut(&mut ty);
+ ty
+}
diff --git a/vendor/tracing-attributes/src/lib.rs b/vendor/tracing-attributes/src/lib.rs
index 49b3c794a..f5974e4e5 100644
--- a/vendor/tracing-attributes/src/lib.rs
+++ b/vendor/tracing-attributes/src/lib.rs
@@ -16,7 +16,7 @@
//!
//! ```toml
//! [dependencies]
-//! tracing-attributes = "0.1.22"
+//! tracing-attributes = "0.1.23"
//! ```
//!
//! The [`#[instrument]`][instrument] attribute can now be added to a function
@@ -52,7 +52,7 @@
//! supported compiler version is not considered a semver breaking change as
//! long as doing so complies with this policy.
//!
-#![doc(html_root_url = "https://docs.rs/tracing-attributes/0.1.22")]
+#![doc(html_root_url = "https://docs.rs/tracing-attributes/0.1.23")]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/logo-type.png",
issue_tracker_base_url = "https://github.com/tokio-rs/tracing/issues/"
@@ -86,7 +86,7 @@ extern crate proc_macro;
use proc_macro2::TokenStream;
use quote::ToTokens;
use syn::parse::{Parse, ParseStream};
-use syn::{Attribute, Block, ItemFn, Signature, Visibility};
+use syn::{Attribute, ItemFn, Signature, Visibility};
mod attr;
mod expand;
@@ -587,11 +587,13 @@ fn instrument_precise(
// check for async_trait-like patterns in the block, and instrument
// the future instead of the wrapper
if let Some(async_like) = expand::AsyncInfo::from_fn(&input) {
- return Ok(async_like.gen_async(args, instrumented_function_name.as_str()));
+ return async_like.gen_async(args, instrumented_function_name.as_str());
}
+ let input = MaybeItemFn::from(input);
+
Ok(expand::gen_function(
- (&input).into(),
+ input.as_ref(),
args,
instrumented_function_name.as_str(),
None,
@@ -603,7 +605,8 @@ fn instrument_precise(
/// which's block is just a `TokenStream` (it may contain invalid code).
#[derive(Debug, Clone)]
struct MaybeItemFn {
- attrs: Vec<Attribute>,
+ outer_attrs: Vec<Attribute>,
+ inner_attrs: Vec<Attribute>,
vis: Visibility,
sig: Signature,
block: TokenStream,
@@ -612,7 +615,8 @@ struct MaybeItemFn {
impl MaybeItemFn {
fn as_ref(&self) -> MaybeItemFnRef<'_, TokenStream> {
MaybeItemFnRef {
- attrs: &self.attrs,
+ outer_attrs: &self.outer_attrs,
+ inner_attrs: &self.inner_attrs,
vis: &self.vis,
sig: &self.sig,
block: &self.block,
@@ -624,12 +628,14 @@ impl MaybeItemFn {
/// (just like `ItemFn`, but skips parsing the body).
impl Parse for MaybeItemFn {
fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
- let attrs = input.call(syn::Attribute::parse_outer)?;
+ let outer_attrs = input.call(Attribute::parse_outer)?;
let vis: Visibility = input.parse()?;
let sig: Signature = input.parse()?;
+ let inner_attrs = input.call(Attribute::parse_inner)?;
let block: TokenStream = input.parse()?;
Ok(Self {
- attrs,
+ outer_attrs,
+ inner_attrs,
vis,
sig,
block,
@@ -637,23 +643,35 @@ impl Parse for MaybeItemFn {
}
}
+impl From<ItemFn> for MaybeItemFn {
+ fn from(
+ ItemFn {
+ attrs,
+ vis,
+ sig,
+ block,
+ }: ItemFn,
+ ) -> Self {
+ let (outer_attrs, inner_attrs) = attrs
+ .into_iter()
+ .partition(|attr| attr.style == syn::AttrStyle::Outer);
+ Self {
+ outer_attrs,
+ inner_attrs,
+ vis,
+ sig,
+ block: block.to_token_stream(),
+ }
+ }
+}
+
/// A generic reference type for `MaybeItemFn`,
/// that takes a generic block type `B` that implements `ToTokens` (eg. `TokenStream`, `Block`).
#[derive(Debug, Clone)]
struct MaybeItemFnRef<'a, B: ToTokens> {
- attrs: &'a Vec<Attribute>,
+ outer_attrs: &'a Vec<Attribute>,
+ inner_attrs: &'a Vec<Attribute>,
vis: &'a Visibility,
sig: &'a Signature,
block: &'a B,
}
-
-impl<'a> From<&'a ItemFn> for MaybeItemFnRef<'a, Box<Block>> {
- fn from(val: &'a ItemFn) -> Self {
- MaybeItemFnRef {
- attrs: &val.attrs,
- vis: &val.vis,
- sig: &val.sig,
- block: &val.block,
- }
- }
-}