aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--Android.bp4
-rw-r--r--CHANGELOG.md28
-rw-r--r--Cargo.toml12
-rw-r--r--Cargo.toml.orig6
-rw-r--r--LICENSE2
-rw-r--r--METADATA12
-rw-r--r--TEST_MAPPING17
-rw-r--r--src/entry.rs116
-rw-r--r--src/lib.rs199
10 files changed, 320 insertions, 78 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 13f94be..6e0797d 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
{
"git": {
- "sha1": "f64673580dfc649954eb744eb2734f2f118baa47"
+ "sha1": "993a60b7c79b6fbdad872c6a173c2e6fe42b117f"
},
"path_in_vcs": "tokio-macros"
} \ No newline at end of file
diff --git a/Android.bp b/Android.bp
index 47abc03..2f4eafc 100644
--- a/Android.bp
+++ b/Android.bp
@@ -22,7 +22,7 @@ rust_proc_macro {
name: "libtokio_macros",
crate_name: "tokio_macros",
cargo_env_compat: true,
- cargo_pkg_version: "1.7.0",
+ cargo_pkg_version: "1.8.2",
srcs: ["src/lib.rs"],
edition: "2018",
rustlibs: [
@@ -30,4 +30,6 @@ rust_proc_macro {
"libquote",
"libsyn",
],
+ product_available: true,
+ vendor_available: true,
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 633b43f..93d52e7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,32 @@
+# 1.8.2 (November 30th, 2022)
+
+- fix a regression introduced in 1.8.1 ([#5244])
+
+[#5244]: https://github.com/tokio-rs/tokio/pull/5244
+
+# 1.8.1 (November 29th, 2022)
+
+(yanked)
+
+- macros: Pin Futures in `#[tokio::test]` to stack ([#5205])
+- macros: Reduce usage of last statement spans in proc-macros ([#5092])
+- macros: Improve the documentation for `#[tokio::test]` ([#4761])
+
+[#5205]: https://github.com/tokio-rs/tokio/pull/5205
+[#5092]: https://github.com/tokio-rs/tokio/pull/5092
+[#4761]: https://github.com/tokio-rs/tokio/pull/4761
+
+# 1.8.0 (June 4th, 2022)
+
+- macros: always emit return statement ([#4636])
+- macros: support setting a custom crate name for `#[tokio::main]` and `#[tokio::test]` ([#4613])
+
+[#4613]: https://github.com/tokio-rs/tokio/pull/4613
+[#4636]: https://github.com/tokio-rs/tokio/pull/4636
+
# 1.7.0 (December 15th, 2021)
-- macros: address remainging clippy::semicolon_if_nothing_returned warning ([#4252])
+- macros: address remaining `clippy::semicolon_if_nothing_returned` warning ([#4252])
[#4252]: https://github.com/tokio-rs/tokio/pull/4252
diff --git a/Cargo.toml b/Cargo.toml
index a2342b9..04bfa41 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,20 +11,25 @@
[package]
edition = "2018"
-rust-version = "1.46"
+rust-version = "1.49"
name = "tokio-macros"
-version = "1.7.0"
+version = "1.8.2"
authors = ["Tokio Contributors <team@tokio.rs>"]
-description = "Tokio's proc macros.\n"
+description = """
+Tokio's proc macros.
+"""
homepage = "https://tokio.rs"
+readme = "README.md"
categories = ["asynchronous"]
license = "MIT"
repository = "https://github.com/tokio-rs/tokio"
+
[package.metadata.docs.rs]
all-features = true
[lib]
proc-macro = true
+
[dependencies.proc-macro2]
version = "1.0.7"
@@ -34,6 +39,7 @@ version = "1"
[dependencies.syn]
version = "1.0.56"
features = ["full"]
+
[dev-dependencies.tokio]
version = "1.0.0"
features = ["full"]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index d9b0579..ea536a8 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -3,10 +3,10 @@ name = "tokio-macros"
# When releasing to crates.io:
# - Remove path dependencies
# - Update CHANGELOG.md.
-# - Create "tokio-macros-1.0.x" git tag.
-version = "1.7.0"
+# - Create "tokio-macros-1.x.y" git tag.
+version = "1.8.2"
edition = "2018"
-rust-version = "1.46"
+rust-version = "1.49"
authors = ["Tokio Contributors <team@tokio.rs>"]
license = "MIT"
repository = "https://github.com/tokio-rs/tokio"
diff --git a/LICENSE b/LICENSE
index e4f802a..a3753c0 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2021 Tokio Contributors
+Copyright (c) 2022 Tokio Contributors
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
diff --git a/METADATA b/METADATA
index c40d9bc..e03bdf5 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,7 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update rust/crates/tokio-macros
+# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+
name: "tokio-macros"
description: "Tokio\'s proc macros."
third_party {
@@ -7,13 +11,13 @@ third_party {
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/tokio-macros/tokio-macros-1.7.0.crate"
+ value: "https://static.crates.io/crates/tokio-macros/tokio-macros-1.8.2.crate"
}
- version: "1.7.0"
+ version: "1.8.2"
license_type: NOTICE
last_upgrade_date {
year: 2022
- month: 3
- day: 1
+ month: 12
+ day: 12
}
}
diff --git a/TEST_MAPPING b/TEST_MAPPING
index de9aee1..170da8f 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -2,6 +2,9 @@
{
"imports": [
{
+ "path": "external/rust/crates/async-stream"
+ },
+ {
"path": "external/rust/crates/futures-util"
},
{
@@ -9,22 +12,12 @@
},
{
"path": "external/rust/crates/tokio-test"
- }
- ],
- "presubmit": [
- {
- "name": "doh_unit_test"
},
{
- "name": "rustBinderTest"
- }
- ],
- "presubmit-rust": [
- {
- "name": "doh_unit_test"
+ "path": "external/uwb/src"
},
{
- "name": "rustBinderTest"
+ "path": "packages/modules/DnsResolver"
}
]
}
diff --git a/src/entry.rs b/src/entry.rs
index 5cb4a49..6460e70 100644
--- a/src/entry.rs
+++ b/src/entry.rs
@@ -1,5 +1,5 @@
use proc_macro::TokenStream;
-use proc_macro2::Span;
+use proc_macro2::{Ident, Span};
use quote::{quote, quote_spanned, ToTokens};
use syn::parse::Parser;
@@ -29,6 +29,7 @@ struct FinalConfig {
flavor: RuntimeFlavor,
worker_threads: Option<usize>,
start_paused: Option<bool>,
+ crate_name: Option<String>,
}
/// Config used in case of the attribute not being able to build a valid config
@@ -36,6 +37,7 @@ const DEFAULT_ERROR_CONFIG: FinalConfig = FinalConfig {
flavor: RuntimeFlavor::CurrentThread,
worker_threads: None,
start_paused: None,
+ crate_name: None,
};
struct Configuration {
@@ -45,6 +47,7 @@ struct Configuration {
worker_threads: Option<(usize, Span)>,
start_paused: Option<(bool, Span)>,
is_test: bool,
+ crate_name: Option<String>,
}
impl Configuration {
@@ -59,6 +62,7 @@ impl Configuration {
worker_threads: None,
start_paused: None,
is_test,
+ crate_name: None,
}
}
@@ -104,6 +108,15 @@ impl Configuration {
Ok(())
}
+ fn set_crate_name(&mut self, name: syn::Lit, span: Span) -> Result<(), syn::Error> {
+ if self.crate_name.is_some() {
+ return Err(syn::Error::new(span, "`crate` set multiple times."));
+ }
+ let name_ident = parse_ident(name, span, "crate")?;
+ self.crate_name = Some(name_ident.to_string());
+ Ok(())
+ }
+
fn macro_name(&self) -> &'static str {
if self.is_test {
"tokio::test"
@@ -151,6 +164,7 @@ impl Configuration {
};
Ok(FinalConfig {
+ crate_name: self.crate_name.clone(),
flavor,
worker_threads,
start_paused,
@@ -185,6 +199,27 @@ fn parse_string(int: syn::Lit, span: Span, field: &str) -> Result<String, syn::E
}
}
+fn parse_ident(lit: syn::Lit, span: Span, field: &str) -> Result<Ident, syn::Error> {
+ match lit {
+ syn::Lit::Str(s) => {
+ let err = syn::Error::new(
+ span,
+ format!(
+ "Failed to parse value of `{}` as ident: \"{}\"",
+ field,
+ s.value()
+ ),
+ );
+ let path = s.parse::<syn::Path>().map_err(|_| err.clone())?;
+ path.get_ident().cloned().ok_or(err)
+ }
+ _ => Err(syn::Error::new(
+ span,
+ format!("Failed to parse value of `{}` as ident.", field),
+ )),
+ }
+}
+
fn parse_bool(bool: syn::Lit, span: Span, field: &str) -> Result<bool, syn::Error> {
match bool {
syn::Lit::Bool(b) => Ok(b.value),
@@ -243,9 +278,15 @@ fn build_config(
let msg = "Attribute `core_threads` is renamed to `worker_threads`";
return Err(syn::Error::new_spanned(namevalue, msg));
}
+ "crate" => {
+ config.set_crate_name(
+ namevalue.lit.clone(),
+ syn::spanned::Spanned::span(&namevalue.lit),
+ )?;
+ }
name => {
let msg = format!(
- "Unknown attribute {} is specified; expected one of: `flavor`, `worker_threads`, `start_paused`",
+ "Unknown attribute {} is specified; expected one of: `flavor`, `worker_threads`, `start_paused`, `crate`",
name,
);
return Err(syn::Error::new_spanned(namevalue, msg));
@@ -275,7 +316,7 @@ fn build_config(
format!("The `{}` attribute requires an argument.", name)
}
name => {
- format!("Unknown attribute {} is specified; expected one of: `flavor`, `worker_threads`, `start_paused`", name)
+ format!("Unknown attribute {} is specified; expected one of: `flavor`, `worker_threads`, `start_paused`, `crate`", name)
}
};
return Err(syn::Error::new_spanned(path, msg));
@@ -313,12 +354,16 @@ fn parse_knobs(mut input: syn::ItemFn, is_test: bool, config: FinalConfig) -> To
(start, end)
};
+ let crate_name = config.crate_name.as_deref().unwrap_or("tokio");
+
+ let crate_ident = Ident::new(crate_name, last_stmt_start_span);
+
let mut rt = match config.flavor {
RuntimeFlavor::CurrentThread => quote_spanned! {last_stmt_start_span=>
- tokio::runtime::Builder::new_current_thread()
+ #crate_ident::runtime::Builder::new_current_thread()
},
RuntimeFlavor::Threaded => quote_spanned! {last_stmt_start_span=>
- tokio::runtime::Builder::new_multi_thread()
+ #crate_ident::runtime::Builder::new_multi_thread()
},
};
if let Some(v) = config.worker_threads {
@@ -338,29 +383,50 @@ fn parse_knobs(mut input: syn::ItemFn, is_test: bool, config: FinalConfig) -> To
let body = &input.block;
let brace_token = input.block.brace_token;
- let (tail_return, tail_semicolon) = match body.stmts.last() {
- Some(syn::Stmt::Semi(syn::Expr::Return(_), _)) => (quote! { return }, quote! { ; }),
- Some(syn::Stmt::Semi(..)) | Some(syn::Stmt::Local(..)) | None => {
- match &input.sig.output {
- syn::ReturnType::Type(_, ty) if matches!(&**ty, syn::Type::Tuple(ty) if ty.elems.is_empty()) =>
- {
- (quote! {}, quote! { ; }) // unit
- }
- syn::ReturnType::Default => (quote! {}, quote! { ; }), // unit
- syn::ReturnType::Type(..) => (quote! {}, quote! {}), // ! or another
- }
- }
- _ => (quote! {}, quote! {}),
- };
- input.block = syn::parse2(quote_spanned! {last_stmt_end_span=>
+ let body_ident = quote! { body };
+ let block_expr = quote_spanned! {last_stmt_end_span=>
+ #[allow(clippy::expect_used, clippy::diverging_sub_expression)]
{
- let body = async #body;
- #[allow(clippy::expect_used)]
- #tail_return #rt
+ return #rt
.enable_all()
.build()
.expect("Failed building the Runtime")
- .block_on(body)#tail_semicolon
+ .block_on(#body_ident);
+ }
+ };
+
+ // For test functions pin the body to the stack and use `Pin<&mut dyn
+ // Future>` to reduce the amount of `Runtime::block_on` (and related
+ // functions) copies we generate during compilation due to the generic
+ // parameter `F` (the future to block on). This could have an impact on
+ // performance, but because it's only for testing it's unlikely to be very
+ // large.
+ //
+ // We don't do this for the main function as it should only be used once so
+ // there will be no benefit.
+ let body = if is_test {
+ let output_type = match &input.sig.output {
+ // For functions with no return value syn doesn't print anything,
+ // but that doesn't work as `Output` for our boxed `Future`, so
+ // default to `()` (the same type as the function output).
+ syn::ReturnType::Default => quote! { () },
+ syn::ReturnType::Type(_, ret_type) => quote! { #ret_type },
+ };
+ quote! {
+ let body = async #body;
+ #crate_ident::pin!(body);
+ let body: ::std::pin::Pin<&mut dyn ::std::future::Future<Output = #output_type>> = body;
+ }
+ } else {
+ quote! {
+ let body = async #body;
+ }
+ };
+
+ input.block = syn::parse2(quote! {
+ {
+ #body
+ #block_expr
}
})
.expect("Parsing failure");
@@ -414,7 +480,7 @@ pub(crate) fn test(args: TokenStream, item: TokenStream, rt_multi_thread: bool)
};
let config = if let Some(attr) = input.attrs.iter().find(|attr| attr.path.is_ident("test")) {
let msg = "second test attribute is supplied";
- Err(syn::Error::new_spanned(&attr, msg))
+ Err(syn::Error::new_spanned(attr, msg))
} else {
AttributeArgs::parse_terminated
.parse(args)
diff --git a/src/lib.rs b/src/lib.rs
index 38638a1..34041af 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -168,12 +168,32 @@ use proc_macro::TokenStream;
///
/// Note that `start_paused` requires the `test-util` feature to be enabled.
///
-/// ### NOTE:
+/// ### Rename package
///
-/// If you rename the Tokio crate in your dependencies this macro will not work.
-/// If you must rename the current version of Tokio because you're also using an
-/// older version of Tokio, you _must_ make the current version of Tokio
-/// available as `tokio` in the module where this macro is expanded.
+/// ```rust
+/// use tokio as tokio1;
+///
+/// #[tokio1::main(crate = "tokio1")]
+/// async fn main() {
+/// println!("Hello world");
+/// }
+/// ```
+///
+/// Equivalent code not using `#[tokio::main]`
+///
+/// ```rust
+/// use tokio as tokio1;
+///
+/// fn main() {
+/// tokio1::runtime::Builder::new_multi_thread()
+/// .enable_all()
+/// .build()
+/// .unwrap()
+/// .block_on(async {
+/// println!("Hello world");
+/// })
+/// }
+/// ```
#[proc_macro_attribute]
#[cfg(not(test))] // Work around for rust-lang/rust#62127
pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
@@ -213,23 +233,52 @@ pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
/// }
/// ```
///
-/// ### NOTE:
+/// ### Rename package
+///
+/// ```rust
+/// use tokio as tokio1;
+///
+/// #[tokio1::main(crate = "tokio1")]
+/// async fn main() {
+/// println!("Hello world");
+/// }
+/// ```
///
-/// If you rename the Tokio crate in your dependencies this macro will not work.
-/// If you must rename the current version of Tokio because you're also using an
-/// older version of Tokio, you _must_ make the current version of Tokio
-/// available as `tokio` in the module where this macro is expanded.
+/// Equivalent code not using `#[tokio::main]`
+///
+/// ```rust
+/// use tokio as tokio1;
+///
+/// fn main() {
+/// tokio1::runtime::Builder::new_multi_thread()
+/// .enable_all()
+/// .build()
+/// .unwrap()
+/// .block_on(async {
+/// println!("Hello world");
+/// })
+/// }
+/// ```
#[proc_macro_attribute]
#[cfg(not(test))] // Work around for rust-lang/rust#62127
pub fn main_rt(args: TokenStream, item: TokenStream) -> TokenStream {
entry::main(args, item, false)
}
-/// Marks async function to be executed by runtime, suitable to test environment
+/// Marks async function to be executed by runtime, suitable to test environment.
+/// This macro helps set up a `Runtime` without requiring the user to use
+/// [Runtime](../tokio/runtime/struct.Runtime.html) or
+/// [Builder](../tokio/runtime/struct.Builder.html) directly.
///
-/// ## Usage
+/// Note: This macro is designed to be simplistic and targets applications that
+/// do not require a complex setup. If the provided functionality is not
+/// sufficient, you may be interested in using
+/// [Builder](../tokio/runtime/struct.Builder.html), which provides a more
+/// powerful interface.
///
-/// ### Multi-thread runtime
+/// # Multi-threaded runtime
+///
+/// To use the multi-threaded runtime, the macro can be configured using
///
/// ```no_run
/// #[tokio::test(flavor = "multi_thread", worker_threads = 1)]
@@ -238,9 +287,52 @@ pub fn main_rt(args: TokenStream, item: TokenStream) -> TokenStream {
/// }
/// ```
///
-/// ### Using default
+/// The `worker_threads` option configures the number of worker threads, and
+/// defaults to the number of cpus on the system. This is the default
+/// flavor.
+///
+/// Note: The multi-threaded runtime requires the `rt-multi-thread` feature
+/// flag.
+///
+/// # Current thread runtime
+///
+/// The default test runtime is single-threaded. Each test gets a
+/// separate current-thread runtime.
+///
+/// ```no_run
+/// #[tokio::test]
+/// async fn my_test() {
+/// assert!(true);
+/// }
+/// ```
+///
+/// ## Usage
+///
+/// ### Using the multi-thread runtime
///
-/// The default test runtime is single-threaded.
+/// ```no_run
+/// #[tokio::test(flavor = "multi_thread")]
+/// async fn my_test() {
+/// assert!(true);
+/// }
+/// ```
+///
+/// Equivalent code not using `#[tokio::test]`
+///
+/// ```no_run
+/// #[test]
+/// fn my_test() {
+/// tokio::runtime::Builder::new_multi_thread()
+/// .enable_all()
+/// .build()
+/// .unwrap()
+/// .block_on(async {
+/// assert!(true);
+/// })
+/// }
+/// ```
+///
+/// ### Using current thread runtime
///
/// ```no_run
/// #[tokio::test]
@@ -249,6 +341,46 @@ pub fn main_rt(args: TokenStream, item: TokenStream) -> TokenStream {
/// }
/// ```
///
+/// Equivalent code not using `#[tokio::test]`
+///
+/// ```no_run
+/// #[test]
+/// fn my_test() {
+/// tokio::runtime::Builder::new_current_thread()
+/// .enable_all()
+/// .build()
+/// .unwrap()
+/// .block_on(async {
+/// assert!(true);
+/// })
+/// }
+/// ```
+///
+/// ### Set number of worker threads
+///
+/// ```no_run
+/// #[tokio::test(flavor ="multi_thread", worker_threads = 2)]
+/// async fn my_test() {
+/// assert!(true);
+/// }
+/// ```
+///
+/// Equivalent code not using `#[tokio::test]`
+///
+/// ```no_run
+/// #[test]
+/// fn my_test() {
+/// tokio::runtime::Builder::new_multi_thread()
+/// .worker_threads(2)
+/// .enable_all()
+/// .build()
+/// .unwrap()
+/// .block_on(async {
+/// assert!(true);
+/// })
+/// }
+/// ```
+///
/// ### Configure the runtime to start with time paused
///
/// ```no_run
@@ -258,14 +390,34 @@ pub fn main_rt(args: TokenStream, item: TokenStream) -> TokenStream {
/// }
/// ```
///
+/// Equivalent code not using `#[tokio::test]`
+///
+/// ```no_run
+/// #[test]
+/// fn my_test() {
+/// tokio::runtime::Builder::new_current_thread()
+/// .enable_all()
+/// .start_paused(true)
+/// .build()
+/// .unwrap()
+/// .block_on(async {
+/// assert!(true);
+/// })
+/// }
+/// ```
+///
/// Note that `start_paused` requires the `test-util` feature to be enabled.
///
-/// ### NOTE:
+/// ### Rename package
///
-/// If you rename the Tokio crate in your dependencies this macro will not work.
-/// If you must rename the current version of Tokio because you're also using an
-/// older version of Tokio, you _must_ make the current version of Tokio
-/// available as `tokio` in the module where this macro is expanded.
+/// ```rust
+/// use tokio as tokio1;
+///
+/// #[tokio1::test(crate = "tokio1")]
+/// async fn my_test() {
+/// println!("Hello world");
+/// }
+/// ```
#[proc_macro_attribute]
pub fn test(args: TokenStream, item: TokenStream) -> TokenStream {
entry::test(args, item, true)
@@ -281,13 +433,6 @@ pub fn test(args: TokenStream, item: TokenStream) -> TokenStream {
/// assert!(true);
/// }
/// ```
-///
-/// ### NOTE:
-///
-/// If you rename the Tokio crate in your dependencies this macro will not work.
-/// If you must rename the current version of Tokio because you're also using an
-/// older version of Tokio, you _must_ make the current version of Tokio
-/// available as `tokio` in the module where this macro is expanded.
#[proc_macro_attribute]
pub fn test_rt(args: TokenStream, item: TokenStream) -> TokenStream {
entry::test(args, item, false)