From 659e0486c9f4cf70ced1abd1c93c6bded220da0d Mon Sep 17 00:00:00 2001 From: Kenny <3454741+kvc0@users.noreply.github.com> Date: Tue, 20 May 2025 22:38:04 -0700 Subject: [PATCH] feat(tonic): rpit future for generated server traits Supported at 1.75, which is tonic's current MSRV, return position impl trait (RPIT) makes user code cleaner, friendlier in a debugger, and possibly a couple nanoseconds faster due to fewer boxed Future indirections. There is still a Box Future at the tower_service interface due to the switch from RPIT style "simple" traits and the fancier static associated type Future style from tower. It's similar to https://github.com/hyperium/tonic/pull/1697 but instead I went for the full change, to evaluate the expected impact more fully. In the expected use cases where people generate their code, they would remove `#[tonic::async_trait]` from their implementations of Server stubs. You can see in all the tests and examples, that's the only user-facing delta. It is a breaking change, but it's a simplification that seemed worthwhile to me with the burden of 1-line deletion per service. The vs code auto-generated todo!() implementations are a little nicer this way too, which is a quality of life boost for me :-) Relates to: https://github.com/hyperium/tonic/issues/1651 ________________ **UX before:** ```rust #[tonic::async_trait] impl Greeter for MyGreeter { ``` **UX after:** ```rust impl Greeter for MyGreeter { ``` ________________ **Testing** Due to the nature of the change, a wide range of tests exercise it. It is a change to the existing infrastructure rather than a new feature, so there's no duplication or parameterization of tests that would increase coverage. --- examples/helloworld-tutorial.md | 2 - examples/routeguide-tutorial.md | 5 +- examples/src/authentication/server.rs | 1 - examples/src/autoreload/server.rs | 1 - examples/src/blocking/server.rs | 1 - examples/src/cancellation/server.rs | 1 - examples/src/codec_buffers/server.rs | 1 - examples/src/compression/server.rs | 1 - examples/src/dynamic/server.rs | 2 - examples/src/dynamic_load_balance/server.rs | 1 - examples/src/grpc-web/server.rs | 1 - examples/src/h2c/server.rs | 1 - examples/src/health/server.rs | 1 - examples/src/helloworld/server.rs | 1 - examples/src/interceptor/server.rs | 1 - examples/src/json-codec/server.rs | 1 - examples/src/load_balance/server.rs | 1 - examples/src/mock/mock.rs | 1 - examples/src/multiplex/server.rs | 2 - examples/src/reflection/server.rs | 1 - examples/src/richer-error/server.rs | 1 - examples/src/richer-error/server_vec.rs | 1 - examples/src/routeguide/server.rs | 1 - examples/src/streaming/server.rs | 1 - examples/src/tls/server.rs | 1 - examples/src/tls_client_auth/server.rs | 1 - examples/src/tls_rustls/server.rs | 1 - examples/src/tower/server.rs | 1 - examples/src/tracing/server.rs | 1 - examples/src/uds/server.rs | 1 - grpc/Cargo.toml | 3 +- grpc/src/client/name_resolution/mod.rs | 2 +- interop/src/server.rs | 2 - tests/compression/src/lib.rs | 1 - tests/default_stubs/src/lib.rs | 2 - tests/integration_tests/tests/client_layer.rs | 1 - .../tests/complex_tower_middleware.rs | 1 - tests/integration_tests/tests/connect_info.rs | 2 - tests/integration_tests/tests/connection.rs | 1 - tests/integration_tests/tests/extensions.rs | 2 - .../tests/http2_keep_alive.rs | 1 - .../tests/http2_max_header_list_size.rs | 1 - tests/integration_tests/tests/interceptor.rs | 1 - .../tests/max_message_size.rs | 2 - tests/integration_tests/tests/origin.rs | 1 - .../integration_tests/tests/routes_builder.rs | 2 - tests/integration_tests/tests/status.rs | 5 - tests/integration_tests/tests/streams.rs | 1 - tests/integration_tests/tests/timeout.rs | 1 - tests/integration_tests/tests/user_agent.rs | 1 - tests/use_arc_self/src/lib.rs | 1 - tests/web/src/lib.rs | 1 - tonic-build/src/server.rs | 106 ++++++++---------- tonic-health/src/generated/grpc_health_v1.rs | 54 ++++----- tonic-health/src/server.rs | 1 - .../src/generated/grpc_reflection_v1.rs | 29 ++--- .../src/generated/grpc_reflection_v1alpha.rs | 29 ++--- tonic-reflection/src/server/v1.rs | 1 - tonic-reflection/src/server/v1alpha.rs | 1 - tonic/Cargo.toml | 6 +- tonic/src/codegen.rs | 1 - tonic/src/lib.rs | 4 - tonic/src/request.rs | 4 +- tonic/src/server/grpc.rs | 8 -- tonic/src/server/service.rs | 60 ++++++---- 65 files changed, 150 insertions(+), 226 deletions(-) diff --git a/examples/helloworld-tutorial.md b/examples/helloworld-tutorial.md index 2e910a9ca..62731385a 100644 --- a/examples/helloworld-tutorial.md +++ b/examples/helloworld-tutorial.md @@ -158,7 +158,6 @@ Next up, let's implement the Greeter service we previously defined in our `.prot #[derive(Debug, Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, @@ -207,7 +206,6 @@ pub mod hello_world { #[derive(Debug, Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, diff --git a/examples/routeguide-tutorial.md b/examples/routeguide-tutorial.md index c434ff8b7..b7145f6e5 100644 --- a/examples/routeguide-tutorial.md +++ b/examples/routeguide-tutorial.md @@ -269,7 +269,6 @@ use tokio_stream::{wrappers::ReceiverStream, Stream}; ``` ```rust -#[tonic::async_trait] impl RouteGuide for RouteGuideService { async fn get_feature(&self, _request: Request) -> Result, Status> { unimplemented!() @@ -302,8 +301,8 @@ impl RouteGuide for RouteGuideService { } ``` -**Note**: The `tonic::async_trait` attribute macro adds support for async functions in traits. It -uses [async-trait] internally. You can learn more about `async fn` in traits in the [async book]. +**Note**: The stubbed traits use `impl Future<...> + Send` for the return values. It +uses RPIT internally. You can learn more about `async fn` in traits in the [async book]. [cargo book]: https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts diff --git a/examples/src/authentication/server.rs b/examples/src/authentication/server.rs index aed197413..78f60802a 100644 --- a/examples/src/authentication/server.rs +++ b/examples/src/authentication/server.rs @@ -10,7 +10,6 @@ type EchoResult = Result, Status>; #[derive(Default)] pub struct EchoServer {} -#[tonic::async_trait] impl pb::echo_server::Echo for EchoServer { async fn unary_echo(&self, request: Request) -> EchoResult { let message = request.into_inner().message; diff --git a/examples/src/autoreload/server.rs b/examples/src/autoreload/server.rs index f8794314f..9e8c619d7 100644 --- a/examples/src/autoreload/server.rs +++ b/examples/src/autoreload/server.rs @@ -10,7 +10,6 @@ pub mod hello_world { #[derive(Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, diff --git a/examples/src/blocking/server.rs b/examples/src/blocking/server.rs index d7ef6177b..6a7b89ced 100644 --- a/examples/src/blocking/server.rs +++ b/examples/src/blocking/server.rs @@ -12,7 +12,6 @@ pub mod hello_world { #[derive(Debug, Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, diff --git a/examples/src/cancellation/server.rs b/examples/src/cancellation/server.rs index 18f92ef2d..2effbc46f 100644 --- a/examples/src/cancellation/server.rs +++ b/examples/src/cancellation/server.rs @@ -17,7 +17,6 @@ pub mod hello_world { #[derive(Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, diff --git a/examples/src/codec_buffers/server.rs b/examples/src/codec_buffers/server.rs index 433fa0cf7..5d82a1cfc 100644 --- a/examples/src/codec_buffers/server.rs +++ b/examples/src/codec_buffers/server.rs @@ -20,7 +20,6 @@ use small_buf::{ #[derive(Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, diff --git a/examples/src/compression/server.rs b/examples/src/compression/server.rs index f106c3d74..7920df521 100644 --- a/examples/src/compression/server.rs +++ b/examples/src/compression/server.rs @@ -11,7 +11,6 @@ pub mod hello_world { #[derive(Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, diff --git a/examples/src/dynamic/server.rs b/examples/src/dynamic/server.rs index 1e31f18f3..c597ecc4f 100644 --- a/examples/src/dynamic/server.rs +++ b/examples/src/dynamic/server.rs @@ -20,7 +20,6 @@ type EchoResult = Result, Status>; #[derive(Default)] pub struct MyEcho {} -#[tonic::async_trait] impl Echo for MyEcho { async fn unary_echo(&self, request: Request) -> EchoResult { println!("Got an echo request from {:?}", request.remote_addr()); @@ -43,7 +42,6 @@ fn init_echo(args: &[String], builder: &mut RoutesBuilder) { #[derive(Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, diff --git a/examples/src/dynamic_load_balance/server.rs b/examples/src/dynamic_load_balance/server.rs index 1143ca57f..cb959be69 100644 --- a/examples/src/dynamic_load_balance/server.rs +++ b/examples/src/dynamic_load_balance/server.rs @@ -15,7 +15,6 @@ pub struct EchoServer { addr: SocketAddr, } -#[tonic::async_trait] impl pb::echo_server::Echo for EchoServer { async fn unary_echo(&self, request: Request) -> EchoResult { let message = format!("{} (from {})", request.into_inner().message, self.addr); diff --git a/examples/src/grpc-web/server.rs b/examples/src/grpc-web/server.rs index 0da7d0f7a..65324a0d9 100644 --- a/examples/src/grpc-web/server.rs +++ b/examples/src/grpc-web/server.rs @@ -10,7 +10,6 @@ pub mod hello_world { #[derive(Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, diff --git a/examples/src/h2c/server.rs b/examples/src/h2c/server.rs index 3fb97797a..83d7c2e1d 100644 --- a/examples/src/h2c/server.rs +++ b/examples/src/h2c/server.rs @@ -16,7 +16,6 @@ pub mod hello_world { #[derive(Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, diff --git a/examples/src/health/server.rs b/examples/src/health/server.rs index bd425740a..882a7b49a 100644 --- a/examples/src/health/server.rs +++ b/examples/src/health/server.rs @@ -12,7 +12,6 @@ pub mod hello_world { #[derive(Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, diff --git a/examples/src/helloworld/server.rs b/examples/src/helloworld/server.rs index 95b74168a..263bc00de 100644 --- a/examples/src/helloworld/server.rs +++ b/examples/src/helloworld/server.rs @@ -10,7 +10,6 @@ pub mod hello_world { #[derive(Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, diff --git a/examples/src/interceptor/server.rs b/examples/src/interceptor/server.rs index 0061442ef..0db720288 100644 --- a/examples/src/interceptor/server.rs +++ b/examples/src/interceptor/server.rs @@ -10,7 +10,6 @@ pub mod hello_world { #[derive(Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, diff --git a/examples/src/json-codec/server.rs b/examples/src/json-codec/server.rs index 319949091..9f57110a9 100644 --- a/examples/src/json-codec/server.rs +++ b/examples/src/json-codec/server.rs @@ -17,7 +17,6 @@ use hello_world::greeter_server::{Greeter, GreeterServer}; #[derive(Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, diff --git a/examples/src/load_balance/server.rs b/examples/src/load_balance/server.rs index 1143ca57f..cb959be69 100644 --- a/examples/src/load_balance/server.rs +++ b/examples/src/load_balance/server.rs @@ -15,7 +15,6 @@ pub struct EchoServer { addr: SocketAddr, } -#[tonic::async_trait] impl pb::echo_server::Echo for EchoServer { async fn unary_echo(&self, request: Request) -> EchoResult { let message = format!("{} (from {})", request.into_inner().message, self.addr); diff --git a/examples/src/mock/mock.rs b/examples/src/mock/mock.rs index ae943a419..2e0ddb7f0 100644 --- a/examples/src/mock/mock.rs +++ b/examples/src/mock/mock.rs @@ -61,7 +61,6 @@ async fn main() -> Result<(), Box> { #[derive(Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, diff --git a/examples/src/multiplex/server.rs b/examples/src/multiplex/server.rs index 68f05e157..c43be6864 100644 --- a/examples/src/multiplex/server.rs +++ b/examples/src/multiplex/server.rs @@ -37,7 +37,6 @@ async fn main() -> Result<(), Box> { #[derive(Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, @@ -53,7 +52,6 @@ impl Greeter for MyGreeter { #[derive(Default)] pub struct MyEcho {} -#[tonic::async_trait] impl Echo for MyEcho { async fn unary_echo( &self, diff --git a/examples/src/reflection/server.rs b/examples/src/reflection/server.rs index 4bcd5d2d9..66cb74e2f 100644 --- a/examples/src/reflection/server.rs +++ b/examples/src/reflection/server.rs @@ -11,7 +11,6 @@ mod proto { #[derive(Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl proto::greeter_server::Greeter for MyGreeter { async fn say_hello( &self, diff --git a/examples/src/richer-error/server.rs b/examples/src/richer-error/server.rs index 9d390c0ae..91caffe6e 100644 --- a/examples/src/richer-error/server.rs +++ b/examples/src/richer-error/server.rs @@ -11,7 +11,6 @@ pub mod hello_world { #[derive(Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, diff --git a/examples/src/richer-error/server_vec.rs b/examples/src/richer-error/server_vec.rs index f988a117f..e62bbe3f6 100644 --- a/examples/src/richer-error/server_vec.rs +++ b/examples/src/richer-error/server_vec.rs @@ -11,7 +11,6 @@ pub mod hello_world { #[derive(Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, diff --git a/examples/src/routeguide/server.rs b/examples/src/routeguide/server.rs index 2f3538e95..0d24224b0 100644 --- a/examples/src/routeguide/server.rs +++ b/examples/src/routeguide/server.rs @@ -22,7 +22,6 @@ pub struct RouteGuideService { features: Arc>, } -#[tonic::async_trait] impl RouteGuide for RouteGuideService { async fn get_feature(&self, request: Request) -> Result, Status> { println!("GetFeature = {:?}", request); diff --git a/examples/src/streaming/server.rs b/examples/src/streaming/server.rs index 34cdfb5e6..d519aa1da 100644 --- a/examples/src/streaming/server.rs +++ b/examples/src/streaming/server.rs @@ -35,7 +35,6 @@ fn match_for_io_error(err_status: &Status) -> Option<&std::io::Error> { #[derive(Debug)] pub struct EchoServer {} -#[tonic::async_trait] impl pb::echo_server::Echo for EchoServer { async fn unary_echo(&self, _: Request) -> EchoResult { Err(Status::unimplemented("not implemented")) diff --git a/examples/src/tls/server.rs b/examples/src/tls/server.rs index 5d2935fd8..93d33f36a 100644 --- a/examples/src/tls/server.rs +++ b/examples/src/tls/server.rs @@ -16,7 +16,6 @@ type EchoResult = Result, Status>; #[derive(Default)] pub struct EchoServer {} -#[tonic::async_trait] impl pb::echo_server::Echo for EchoServer { async fn unary_echo(&self, request: Request) -> EchoResult { let conn_info = request diff --git a/examples/src/tls_client_auth/server.rs b/examples/src/tls_client_auth/server.rs index 224620523..4d1b42cd1 100644 --- a/examples/src/tls_client_auth/server.rs +++ b/examples/src/tls_client_auth/server.rs @@ -11,7 +11,6 @@ type EchoResult = Result, Status>; #[derive(Default)] pub struct EchoServer {} -#[tonic::async_trait] impl pb::echo_server::Echo for EchoServer { async fn unary_echo(&self, request: Request) -> EchoResult { let certs = request diff --git a/examples/src/tls_rustls/server.rs b/examples/src/tls_rustls/server.rs index 26fe818dd..405532355 100644 --- a/examples/src/tls_rustls/server.rs +++ b/examples/src/tls_rustls/server.rs @@ -103,7 +103,6 @@ type EchoResult = Result, Status>; #[derive(Default)] pub struct EchoServer {} -#[tonic::async_trait] impl pb::echo_server::Echo for EchoServer { async fn unary_echo(&self, request: Request) -> EchoResult { let conn_info = request.extensions().get::>().unwrap(); diff --git a/examples/src/tower/server.rs b/examples/src/tower/server.rs index 9c891c502..4af80f55b 100644 --- a/examples/src/tower/server.rs +++ b/examples/src/tower/server.rs @@ -15,7 +15,6 @@ pub mod hello_world { #[derive(Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, diff --git a/examples/src/tracing/server.rs b/examples/src/tracing/server.rs index a068219a8..9fc9adf48 100644 --- a/examples/src/tracing/server.rs +++ b/examples/src/tracing/server.rs @@ -12,7 +12,6 @@ use hello_world::{ #[derive(Debug, Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { #[tracing::instrument] async fn say_hello( diff --git a/examples/src/uds/server.rs b/examples/src/uds/server.rs index d481d4104..60f97d5bb 100644 --- a/examples/src/uds/server.rs +++ b/examples/src/uds/server.rs @@ -21,7 +21,6 @@ use hello_world::{ #[derive(Default)] pub struct MyGreeter {} -#[tonic::async_trait] impl Greeter for MyGreeter { async fn say_hello( &self, diff --git a/grpc/Cargo.toml b/grpc/Cargo.toml index b27942297..ab65e4280 100644 --- a/grpc/Cargo.toml +++ b/grpc/Cargo.toml @@ -6,6 +6,7 @@ authors = ["gRPC Authors"] license = "Apache-2.0" [dependencies] +async-trait = {version = "0.1.13"} url = "2.5.0" tokio = { version = "1.37.0", features = ["sync"] } -tonic = { version = "0.13.0", path = "../tonic", default-features = false, features = ["codegen"] } +tonic = { version = "0.13.0", path = "../tonic", default-features = false, features = ["codegen"] } \ No newline at end of file diff --git a/grpc/src/client/name_resolution/mod.rs b/grpc/src/client/name_resolution/mod.rs index 05c5cf795..26f0e672a 100644 --- a/grpc/src/client/name_resolution/mod.rs +++ b/grpc/src/client/name_resolution/mod.rs @@ -30,8 +30,8 @@ use std::{ sync::Arc, }; +use async_trait::async_trait; use tokio::sync::Notify; -use tonic::async_trait; use url::Url; use crate::attributes::Attributes; diff --git a/interop/src/server.rs b/interop/src/server.rs index f64297041..f3e4ceae2 100644 --- a/interop/src/server.rs +++ b/interop/src/server.rs @@ -22,7 +22,6 @@ type Streaming = Request>; type Stream = Pin> + Send + 'static>>; type BoxFuture = Pin> + Send + 'static>>; -#[tonic::async_trait] impl pb::test_service_server::TestService for TestService { async fn empty_call(&self, _request: Request) -> Result { Ok(Response::new(Empty {})) @@ -158,7 +157,6 @@ impl pb::test_service_server::TestService for TestService { #[derive(Default)] pub struct UnimplementedService {} -#[tonic::async_trait] impl pb::unimplemented_service_server::UnimplementedService for UnimplementedService { async fn unimplemented_call(&self, _req: Request) -> Result { Err(Status::unimplemented("")) diff --git a/tests/compression/src/lib.rs b/tests/compression/src/lib.rs index 02f729b60..6837f9269 100644 --- a/tests/compression/src/lib.rs +++ b/tests/compression/src/lib.rs @@ -44,7 +44,6 @@ impl Svc { } } -#[tonic::async_trait] impl test_server::Test for Svc { async fn compress_output_unary(&self, _req: Request<()>) -> Result, Status> { let data = [0_u8; UNCOMPRESSED_MIN_BODY_SIZE]; diff --git a/tests/default_stubs/src/lib.rs b/tests/default_stubs/src/lib.rs index bbf98d4ae..accb1b83e 100644 --- a/tests/default_stubs/src/lib.rs +++ b/tests/default_stubs/src/lib.rs @@ -12,7 +12,6 @@ tonic::include_proto!("test_default"); #[derive(Debug, Default)] struct Svc; -#[tonic::async_trait] impl test_server::Test for Svc { type ServerStreamStream = Pin> + Send + 'static>>; type BidirectionalStreamStream = @@ -41,7 +40,6 @@ impl test_server::Test for Svc { } } -#[tonic::async_trait] impl test_default_server::TestDefault for Svc { // Default unimplemented stubs provided here. } diff --git a/tests/integration_tests/tests/client_layer.rs b/tests/integration_tests/tests/client_layer.rs index 6bf60fc50..e1d2a14b7 100644 --- a/tests/integration_tests/tests/client_layer.rs +++ b/tests/integration_tests/tests/client_layer.rs @@ -13,7 +13,6 @@ use tower_http::{set_header::SetRequestHeaderLayer, trace::TraceLayer}; async fn connect_supports_standard_tower_layers() { struct Svc; - #[tonic::async_trait] impl test_server::Test for Svc { async fn unary_call(&self, req: Request) -> Result, Status> { match req.metadata().get("x-test") { diff --git a/tests/integration_tests/tests/complex_tower_middleware.rs b/tests/integration_tests/tests/complex_tower_middleware.rs index d14d6f192..9816ead01 100644 --- a/tests/integration_tests/tests/complex_tower_middleware.rs +++ b/tests/integration_tests/tests/complex_tower_middleware.rs @@ -14,7 +14,6 @@ use tower::{layer::Layer, BoxError, Service}; async fn complex_tower_layers_work() { struct Svc; - #[tonic::async_trait] impl test_server::Test for Svc { async fn unary_call(&self, req: Request) -> Result, Status> { unimplemented!() diff --git a/tests/integration_tests/tests/connect_info.rs b/tests/integration_tests/tests/connect_info.rs index 0671732c4..6560a6c89 100644 --- a/tests/integration_tests/tests/connect_info.rs +++ b/tests/integration_tests/tests/connect_info.rs @@ -13,7 +13,6 @@ use tonic::{ async fn getting_connect_info() { struct Svc; - #[tonic::async_trait] impl test_server::Test for Svc { async fn unary_call(&self, req: Request) -> Result, Status> { assert!(req.local_addr().is_some()); @@ -77,7 +76,6 @@ pub mod unix { struct Svc {} - #[tonic::async_trait] impl test_server::Test for Svc { async fn unary_call(&self, req: Request) -> Result, Status> { let conn_info = req.extensions().get::().unwrap(); diff --git a/tests/integration_tests/tests/connection.rs b/tests/integration_tests/tests/connection.rs index d7d4cd49b..144185ffd 100644 --- a/tests/integration_tests/tests/connection.rs +++ b/tests/integration_tests/tests/connection.rs @@ -9,7 +9,6 @@ use tonic::{ struct Svc(Arc>>>); -#[tonic::async_trait] impl test_server::Test for Svc { async fn unary_call(&self, _: Request) -> Result, Status> { let mut l = self.0.lock().unwrap(); diff --git a/tests/integration_tests/tests/extensions.rs b/tests/integration_tests/tests/extensions.rs index 22ad609d4..ec08c099b 100644 --- a/tests/integration_tests/tests/extensions.rs +++ b/tests/integration_tests/tests/extensions.rs @@ -22,7 +22,6 @@ struct ExtensionValue(i32); async fn setting_extension_from_interceptor() { struct Svc; - #[tonic::async_trait] impl test_server::Test for Svc { async fn unary_call(&self, req: Request) -> Result, Status> { let value = req.extensions().get::().unwrap(); @@ -72,7 +71,6 @@ async fn setting_extension_from_interceptor() { async fn setting_extension_from_tower() { struct Svc; - #[tonic::async_trait] impl test_server::Test for Svc { async fn unary_call(&self, req: Request) -> Result, Status> { let value = req.extensions().get::().unwrap(); diff --git a/tests/integration_tests/tests/http2_keep_alive.rs b/tests/integration_tests/tests/http2_keep_alive.rs index 13b71b6f7..b9851fc9e 100644 --- a/tests/integration_tests/tests/http2_keep_alive.rs +++ b/tests/integration_tests/tests/http2_keep_alive.rs @@ -8,7 +8,6 @@ use tonic::{Request, Response, Status}; struct Svc; -#[tonic::async_trait] impl test_server::Test for Svc { async fn unary_call(&self, _: Request) -> Result, Status> { Ok(Response::new(Output {})) diff --git a/tests/integration_tests/tests/http2_max_header_list_size.rs b/tests/integration_tests/tests/http2_max_header_list_size.rs index 61e31fd50..04413030b 100644 --- a/tests/integration_tests/tests/http2_max_header_list_size.rs +++ b/tests/integration_tests/tests/http2_max_header_list_size.rs @@ -20,7 +20,6 @@ async fn test_http_max_header_list_size_and_long_errors() { "a".repeat(N) } - #[tonic::async_trait] impl test_server::Test for Svc { async fn unary_call(&self, _: Request) -> Result, Status> { Err(Status::internal(long_message())) diff --git a/tests/integration_tests/tests/interceptor.rs b/tests/integration_tests/tests/interceptor.rs index 0e10129a4..1e98fb47b 100644 --- a/tests/integration_tests/tests/interceptor.rs +++ b/tests/integration_tests/tests/interceptor.rs @@ -12,7 +12,6 @@ async fn interceptor_retrieves_grpc_method() { struct Svc; - #[tonic::async_trait] impl Test for Svc { async fn unary_call(&self, _: Request) -> Result, Status> { Ok(Response::new(Output {})) diff --git a/tests/integration_tests/tests/max_message_size.rs b/tests/integration_tests/tests/max_message_size.rs index de6c91f90..b9d67a6df 100644 --- a/tests/integration_tests/tests/max_message_size.rs +++ b/tests/integration_tests/tests/max_message_size.rs @@ -122,7 +122,6 @@ async fn response_stream_limit() { struct Svc; - #[tonic::async_trait] impl test1_server::Test1 for Svc { async fn unary_call(&self, _req: Request) -> Result, Status> { unimplemented!() @@ -276,7 +275,6 @@ async fn max_message_run(case: &TestCase) -> Result<(), Status> { struct Svc(Vec); - #[tonic::async_trait] impl test1_server::Test1 for Svc { async fn unary_call(&self, _req: Request) -> Result, Status> { Ok(Response::new(Output1 { diff --git a/tests/integration_tests/tests/origin.rs b/tests/integration_tests/tests/origin.rs index 291ed47d7..c10967354 100644 --- a/tests/integration_tests/tests/origin.rs +++ b/tests/integration_tests/tests/origin.rs @@ -17,7 +17,6 @@ use tower::Service; async fn writes_origin_header() { struct Svc; - #[tonic::async_trait] impl test_server::Test for Svc { async fn unary_call( &self, diff --git a/tests/integration_tests/tests/routes_builder.rs b/tests/integration_tests/tests/routes_builder.rs index aeb975a50..1f2f2bd1a 100644 --- a/tests/integration_tests/tests/routes_builder.rs +++ b/tests/integration_tests/tests/routes_builder.rs @@ -18,7 +18,6 @@ use tonic::{ async fn multiple_service_using_routes_builder() { struct Svc1; - #[tonic::async_trait] impl test_server::Test for Svc1 { async fn unary_call(&self, _req: Request) -> Result, Status> { Ok(Response::new(Output {})) @@ -27,7 +26,6 @@ async fn multiple_service_using_routes_builder() { struct Svc2; - #[tonic::async_trait] impl test1_server::Test1 for Svc2 { async fn unary_call(&self, request: Request) -> Result, Status> { Ok(Response::new(Output1 { diff --git a/tests/integration_tests/tests/status.rs b/tests/integration_tests/tests/status.rs index d75052b80..92cbd0dfb 100644 --- a/tests/integration_tests/tests/status.rs +++ b/tests/integration_tests/tests/status.rs @@ -22,7 +22,6 @@ use tonic::{ async fn status_with_details() { struct Svc; - #[tonic::async_trait] impl test_server::Test for Svc { async fn unary_call(&self, _: Request) -> Result, Status> { Err(Status::with_details( @@ -80,7 +79,6 @@ async fn status_with_metadata() { struct Svc; - #[tonic::async_trait] impl test_server::Test for Svc { async fn unary_call(&self, _: Request) -> Result, Status> { let mut metadata = MetadataMap::new(); @@ -148,7 +146,6 @@ async fn status_from_server_stream() { struct Svc; - #[tonic::async_trait] impl test_stream_server::TestStream for Svc { type StreamCallStream = Stream; @@ -218,7 +215,6 @@ async fn status_from_server_stream_with_inferred_status() { struct Svc; - #[tonic::async_trait] impl test_stream_server::TestStream for Svc { type StreamCallStream = Stream; @@ -305,7 +301,6 @@ async fn message_and_then_status_from_server_stream() { struct Svc; - #[tonic::async_trait] impl test_stream_server::TestStream for Svc { type StreamCallStream = Stream; diff --git a/tests/integration_tests/tests/streams.rs b/tests/integration_tests/tests/streams.rs index ad773c9f2..f73948561 100644 --- a/tests/integration_tests/tests/streams.rs +++ b/tests/integration_tests/tests/streams.rs @@ -10,7 +10,6 @@ type Stream = std::pin::Pin< async fn status_from_server_stream_with_source() { struct Svc; - #[tonic::async_trait] impl test_stream_server::TestStream for Svc { type StreamCallStream = Stream; diff --git a/tests/integration_tests/tests/timeout.rs b/tests/integration_tests/tests/timeout.rs index 6fb1b885b..cbf96cf4b 100644 --- a/tests/integration_tests/tests/timeout.rs +++ b/tests/integration_tests/tests/timeout.rs @@ -66,7 +66,6 @@ async fn run_service_in_background(latency: Duration, server_timeout: Duration) latency: Duration, } - #[tonic::async_trait] impl test_server::Test for Svc { async fn unary_call(&self, _req: Request) -> Result, Status> { tokio::time::sleep(self.latency).await; diff --git a/tests/integration_tests/tests/user_agent.rs b/tests/integration_tests/tests/user_agent.rs index 5849fd4ff..372014117 100644 --- a/tests/integration_tests/tests/user_agent.rs +++ b/tests/integration_tests/tests/user_agent.rs @@ -10,7 +10,6 @@ use tonic::{ async fn writes_user_agent_header() { struct Svc; - #[tonic::async_trait] impl test_server::Test for Svc { async fn unary_call(&self, req: Request) -> Result, Status> { match req.metadata().get("user-agent") { diff --git a/tests/use_arc_self/src/lib.rs b/tests/use_arc_self/src/lib.rs index 6b12b588e..82f70d08c 100644 --- a/tests/use_arc_self/src/lib.rs +++ b/tests/use_arc_self/src/lib.rs @@ -9,7 +9,6 @@ tonic::include_proto!("test"); #[derive(Debug, Default)] struct Svc; -#[tonic::async_trait] impl test_server::Test for Svc { async fn test_request( self: Arc, diff --git a/tests/web/src/lib.rs b/tests/web/src/lib.rs index 3dcd12d39..b3aaaa3ef 100644 --- a/tests/web/src/lib.rs +++ b/tests/web/src/lib.rs @@ -13,7 +13,6 @@ type BoxStream = Pin> + Send + 'stati pub struct Svc; -#[tonic::async_trait] impl Test for Svc { async fn unary_call(&self, req: Request) -> Result, Status> { let req = req.into_inner(); diff --git a/tonic-build/src/server.rs b/tonic-build/src/server.rs index e2d0aacd9..a8133c437 100644 --- a/tonic-build/src/server.rs +++ b/tonic-build/src/server.rs @@ -220,7 +220,6 @@ fn generate_trait( quote! { #trait_doc - #[async_trait] pub trait #server_trait : std::marker::Send + std::marker::Sync + 'static { #methods } @@ -265,41 +264,41 @@ fn generate_trait_methods( (false, false, true) => { quote! { #method_doc - async fn #name(#self_param, request: tonic::Request<#req_message>) - -> std::result::Result, tonic::Status> { - Err(tonic::Status::unimplemented("Not yet implemented")) + fn #name(#self_param, request: tonic::Request<#req_message>) + -> impl std::future::Future, tonic::Status>> + Send { + async { Err(tonic::Status::unimplemented("Not yet implemented")) } } } } (false, false, false) => { quote! { #method_doc - async fn #name(#self_param, request: tonic::Request<#req_message>) - -> std::result::Result, tonic::Status>; + fn #name(#self_param, request: tonic::Request<#req_message>) + -> impl std::future::Future, tonic::Status>> + Send; } } (true, false, true) => { quote! { #method_doc - async fn #name(#self_param, request: tonic::Request>) - -> std::result::Result, tonic::Status> { - Err(tonic::Status::unimplemented("Not yet implemented")) + fn #name(#self_param, request: tonic::Request>) + -> impl std::future::Future, tonic::Status>> + Send { + async { Err(tonic::Status::unimplemented("Not yet implemented")) } } } } (true, false, false) => { quote! { #method_doc - async fn #name(#self_param, request: tonic::Request>) - -> std::result::Result, tonic::Status>; + fn #name(#self_param, request: tonic::Request>) + -> impl std::future::Future, tonic::Status>> + Send; } } (false, true, true) => { quote! { #method_doc - async fn #name(#self_param, request: tonic::Request<#req_message>) - -> std::result::Result>, tonic::Status> { - Err(tonic::Status::unimplemented("Not yet implemented")) + fn #name(#self_param, request: tonic::Request<#req_message>) + -> impl std::future::Future>, tonic::Status>> + Send { + async { Err(tonic::Status::unimplemented("Not yet implemented")) } } } } @@ -315,16 +314,16 @@ fn generate_trait_methods( type #stream: tonic::codegen::tokio_stream::Stream> + std::marker::Send + 'static; #method_doc - async fn #name(#self_param, request: tonic::Request<#req_message>) - -> std::result::Result, tonic::Status>; + fn #name(#self_param, request: tonic::Request<#req_message>) + -> impl std::future::Future, tonic::Status>> + Send; } } (true, true, true) => { quote! { #method_doc - async fn #name(#self_param, request: tonic::Request>) - -> std::result::Result>, tonic::Status> { - Err(tonic::Status::unimplemented("Not yet implemented")) + fn #name(#self_param, request: tonic::Request>) + -> impl std::future::Future>, tonic::Status>> + Send { + async { Err(tonic::Status::unimplemented("Not yet implemented")) } } } } @@ -340,8 +339,8 @@ fn generate_trait_methods( type #stream: tonic::codegen::tokio_stream::Stream> + std::marker::Send + 'static; #method_doc - async fn #name(#self_param, request: tonic::Request>) - -> std::result::Result, tonic::Status>; + fn #name(#self_param, request: tonic::Request>) + -> impl std::future::Future, tonic::Status>> + Send; } } }; @@ -446,10 +445,12 @@ fn generate_unary( let (request, response) = method.request_response_name(proto_path, compile_well_known_types); - let inner_arg = if use_arc_self { - quote!(inner) + let calling_convention = if use_arc_self { + quote!(::#method_ident(inner, request)) } else { - quote!(&inner) + quote!(async move { + ::#method_ident(&inner, request).await + }) }; quote! { @@ -458,14 +459,10 @@ fn generate_unary( impl tonic::server::UnaryService<#request> for #service_ident { type Response = #response; - type Future = BoxFuture, tonic::Status>; - fn call(&mut self, request: tonic::Request<#request>) -> Self::Future { + fn call(&mut self, request: tonic::Request<#request>) -> impl std::future::Future, tonic::Status>> + Send { let inner = Arc::clone(&self.0); - let fut = async move { - ::#method_ident(#inner_arg, request).await - }; - Box::pin(fut) + #calling_convention } } @@ -486,6 +483,7 @@ fn generate_unary( Ok(res) }; + // This pin is necessary due to tower_service::Service::Future versus RPIT Box::pin(fut) } } @@ -512,10 +510,12 @@ fn generate_server_streaming( quote!(type ResponseStream = BoxStream<#response>) }; - let inner_arg = if use_arc_self { - quote!(inner) + let calling_convention = if use_arc_self { + quote!(::#method_ident(inner, request)) } else { - quote!(&inner) + quote!(async move { + ::#method_ident(&inner, request).await + }) }; quote! { @@ -525,14 +525,10 @@ fn generate_server_streaming( impl tonic::server::ServerStreamingService<#request> for #service_ident { type Response = #response; #response_stream; - type Future = BoxFuture, tonic::Status>; - fn call(&mut self, request: tonic::Request<#request>) -> Self::Future { + fn call(&mut self, request: tonic::Request<#request>) -> impl std::future::Future, tonic::Status>> + Send { let inner = Arc::clone(&self.0); - let fut = async move { - ::#method_ident(#inner_arg, request).await - }; - Box::pin(fut) + #calling_convention } } @@ -570,10 +566,12 @@ fn generate_client_streaming( let (request, response) = method.request_response_name(proto_path, compile_well_known_types); let codec_name = syn::parse_str::(method.codec_path()).unwrap(); - let inner_arg = if use_arc_self { - quote!(inner) + let calling_convention = if use_arc_self { + quote!(::#method_ident(inner, request)) } else { - quote!(&inner) + quote!(async move { + ::#method_ident(&inner, request).await + }) }; quote! { @@ -583,14 +581,10 @@ fn generate_client_streaming( impl tonic::server::ClientStreamingService<#request> for #service_ident { type Response = #response; - type Future = BoxFuture, tonic::Status>; - fn call(&mut self, request: tonic::Request>) -> Self::Future { + fn call(&mut self, request: tonic::Request>) -> impl std::future::Future, tonic::Status>> + Send { let inner = Arc::clone(&self.0); - let fut = async move { - ::#method_ident(#inner_arg, request).await - }; - Box::pin(fut) + #calling_convention } } @@ -637,10 +631,12 @@ fn generate_streaming( quote!(type ResponseStream = BoxStream<#response>) }; - let inner_arg = if use_arc_self { - quote!(inner) + let calling_convention = if use_arc_self { + quote!(::#method_ident(inner, request)) } else { - quote!(&inner) + quote!(async move { + ::#method_ident(&inner, request).await + }) }; quote! { @@ -651,14 +647,10 @@ fn generate_streaming( { type Response = #response; #response_stream; - type Future = BoxFuture, tonic::Status>; - fn call(&mut self, request: tonic::Request>) -> Self::Future { + fn call(&mut self, request: tonic::Request>) -> impl std::future::Future, tonic::Status>> + Send { let inner = Arc::clone(&self.0); - let fut = async move { - ::#method_ident(#inner_arg, request).await - }; - Box::pin(fut) + #calling_convention } } diff --git a/tonic-health/src/generated/grpc_health_v1.rs b/tonic-health/src/generated/grpc_health_v1.rs index 67ec57c98..4c28ad75d 100644 --- a/tonic-health/src/generated/grpc_health_v1.rs +++ b/tonic-health/src/generated/grpc_health_v1.rs @@ -213,17 +213,18 @@ pub mod health_server { )] use tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with HealthServer. - #[async_trait] pub trait Health: std::marker::Send + std::marker::Sync + 'static { /// If the requested service is unknown, the call will fail with status /// NOT_FOUND. - async fn check( + fn check( &self, request: tonic::Request, - ) -> std::result::Result< - tonic::Response, - tonic::Status, - >; + ) -> impl std::future::Future< + Output = std::result::Result< + tonic::Response, + tonic::Status, + >, + > + Send; /// Server streaming response type for the Watch method. type WatchStream: tonic::codegen::tokio_stream::Stream< Item = std::result::Result, @@ -245,10 +246,15 @@ pub mod health_server { /// should assume this method is not supported and should not retry the /// call. If the call terminates with any other status (including OK), /// clients should retry the call with appropriate exponential backoff. - async fn watch( + fn watch( &self, request: tonic::Request, - ) -> std::result::Result, tonic::Status>; + ) -> impl std::future::Future< + Output = std::result::Result< + tonic::Response, + tonic::Status, + >, + > + Send; } #[derive(Debug)] pub struct HealthServer { @@ -334,19 +340,17 @@ pub mod health_server { > tonic::server::UnaryService for CheckSvc { type Response = super::HealthCheckResponse; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; fn call( &mut self, request: tonic::Request, - ) -> Self::Future { + ) -> impl std::future::Future< + Output = std::result::Result< + tonic::Response, + tonic::Status, + >, + > + Send { let inner = Arc::clone(&self.0); - let fut = async move { - ::check(&inner, request).await - }; - Box::pin(fut) + async move { ::check(&inner, request).await } } } let accept_compression_encodings = self.accept_compression_encodings; @@ -380,19 +384,17 @@ pub mod health_server { for WatchSvc { type Response = super::HealthCheckResponse; type ResponseStream = T::WatchStream; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; fn call( &mut self, request: tonic::Request, - ) -> Self::Future { + ) -> impl std::future::Future< + Output = std::result::Result< + tonic::Response, + tonic::Status, + >, + > + Send { let inner = Arc::clone(&self.0); - let fut = async move { - ::watch(&inner, request).await - }; - Box::pin(fut) + async move { ::watch(&inner, request).await } } } let accept_compression_encodings = self.accept_compression_encodings; diff --git a/tonic-health/src/server.rs b/tonic-health/src/server.rs index 1a4d73e7f..bf6a2e6d2 100644 --- a/tonic-health/src/server.rs +++ b/tonic-health/src/server.rs @@ -126,7 +126,6 @@ impl HealthService { } } -#[tonic::async_trait] impl Health for HealthService { async fn check( &self, diff --git a/tonic-reflection/src/generated/grpc_reflection_v1.rs b/tonic-reflection/src/generated/grpc_reflection_v1.rs index 569ee6715..40bf79812 100644 --- a/tonic-reflection/src/generated/grpc_reflection_v1.rs +++ b/tonic-reflection/src/generated/grpc_reflection_v1.rs @@ -270,7 +270,6 @@ pub mod server_reflection_server { )] use tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with ServerReflectionServer. - #[async_trait] pub trait ServerReflection: std::marker::Send + std::marker::Sync + 'static { /// Server streaming response type for the ServerReflectionInfo method. type ServerReflectionInfoStream: tonic::codegen::tokio_stream::Stream< @@ -283,13 +282,15 @@ pub mod server_reflection_server { + 'static; /// The reflection service is structured as a bidirectional stream, ensuring /// all related requests go to a single server. - async fn server_reflection_info( + fn server_reflection_info( &self, request: tonic::Request>, - ) -> std::result::Result< - tonic::Response, - tonic::Status, - >; + ) -> impl std::future::Future< + Output = std::result::Result< + tonic::Response, + tonic::Status, + >, + > + Send; } #[derive(Debug)] pub struct ServerReflectionServer { @@ -376,25 +377,25 @@ pub mod server_reflection_server { for ServerReflectionInfoSvc { type Response = super::ServerReflectionResponse; type ResponseStream = T::ServerReflectionInfoStream; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; fn call( &mut self, request: tonic::Request< tonic::Streaming, >, - ) -> Self::Future { + ) -> impl std::future::Future< + Output = std::result::Result< + tonic::Response, + tonic::Status, + >, + > + Send { let inner = Arc::clone(&self.0); - let fut = async move { + async move { ::server_reflection_info( &inner, request, ) .await - }; - Box::pin(fut) + } } } let accept_compression_encodings = self.accept_compression_encodings; diff --git a/tonic-reflection/src/generated/grpc_reflection_v1alpha.rs b/tonic-reflection/src/generated/grpc_reflection_v1alpha.rs index 685d9b0a1..985c71570 100644 --- a/tonic-reflection/src/generated/grpc_reflection_v1alpha.rs +++ b/tonic-reflection/src/generated/grpc_reflection_v1alpha.rs @@ -270,7 +270,6 @@ pub mod server_reflection_server { )] use tonic::codegen::*; /// Generated trait containing gRPC methods that should be implemented for use with ServerReflectionServer. - #[async_trait] pub trait ServerReflection: std::marker::Send + std::marker::Sync + 'static { /// Server streaming response type for the ServerReflectionInfo method. type ServerReflectionInfoStream: tonic::codegen::tokio_stream::Stream< @@ -283,13 +282,15 @@ pub mod server_reflection_server { + 'static; /// The reflection service is structured as a bidirectional stream, ensuring /// all related requests go to a single server. - async fn server_reflection_info( + fn server_reflection_info( &self, request: tonic::Request>, - ) -> std::result::Result< - tonic::Response, - tonic::Status, - >; + ) -> impl std::future::Future< + Output = std::result::Result< + tonic::Response, + tonic::Status, + >, + > + Send; } #[derive(Debug)] pub struct ServerReflectionServer { @@ -376,25 +377,25 @@ pub mod server_reflection_server { for ServerReflectionInfoSvc { type Response = super::ServerReflectionResponse; type ResponseStream = T::ServerReflectionInfoStream; - type Future = BoxFuture< - tonic::Response, - tonic::Status, - >; fn call( &mut self, request: tonic::Request< tonic::Streaming, >, - ) -> Self::Future { + ) -> impl std::future::Future< + Output = std::result::Result< + tonic::Response, + tonic::Status, + >, + > + Send { let inner = Arc::clone(&self.0); - let fut = async move { + async move { ::server_reflection_info( &inner, request, ) .await - }; - Box::pin(fut) + } } } let accept_compression_encodings = self.accept_compression_encodings; diff --git a/tonic-reflection/src/server/v1.rs b/tonic-reflection/src/server/v1.rs index 6a5054f99..75d899b95 100644 --- a/tonic-reflection/src/server/v1.rs +++ b/tonic-reflection/src/server/v1.rs @@ -19,7 +19,6 @@ pub struct ReflectionService { state: Arc, } -#[tonic::async_trait] impl ServerReflection for ReflectionService { type ServerReflectionInfoStream = ServerReflectionInfoStream; diff --git a/tonic-reflection/src/server/v1alpha.rs b/tonic-reflection/src/server/v1alpha.rs index b21d8d91d..ddb555594 100644 --- a/tonic-reflection/src/server/v1alpha.rs +++ b/tonic-reflection/src/server/v1alpha.rs @@ -19,7 +19,6 @@ pub struct ReflectionService { state: Arc, } -#[tonic::async_trait] impl ServerReflection for ReflectionService { type ServerReflectionInfoStream = ServerReflectionInfoStream; diff --git a/tonic/Cargo.toml b/tonic/Cargo.toml index a9dca6f24..4706fe5cc 100644 --- a/tonic/Cargo.toml +++ b/tonic/Cargo.toml @@ -20,7 +20,7 @@ rust-version = {workspace = true} exclude = ["benches-disabled"] [features] -codegen = ["dep:async-trait"] +codegen = [] gzip = ["dep:flate2"] deflate = ["dep:flate2"] zstd = ["dep:zstd"] @@ -71,9 +71,6 @@ tokio-stream = {version = "0.1.16", default-features = false} # prost prost = {version = "0.13", default-features = false, features = ["std"], optional = true} -# codegen -async-trait = {version = "0.1.13", optional = true} - # transport h2 = {version = "0.4", optional = true} hyper = {version = "1", features = ["http1", "http2"], optional = true} @@ -123,7 +120,6 @@ allowed_external_types = [ "prost::*", "tracing::*", - "async_trait::async_trait", "axum_core::body::Body", "axum_core::response::into_response::IntoResponse", "axum::routing::Router", diff --git a/tonic/src/codegen.rs b/tonic/src/codegen.rs index 216536705..d7a40cacd 100644 --- a/tonic/src/codegen.rs +++ b/tonic/src/codegen.rs @@ -1,6 +1,5 @@ //! Codegen exports used by `tonic-build`. -pub use async_trait::async_trait; pub use tokio_stream; pub use std::future::Future; diff --git a/tonic/src/lib.rs b/tonic/src/lib.rs index 88ac07a86..ea04d0024 100644 --- a/tonic/src/lib.rs +++ b/tonic/src/lib.rs @@ -112,10 +112,6 @@ mod response; mod status; mod util; -/// A re-export of [`async-trait`](https://docs.rs/async-trait) for use with codegen. -#[cfg(feature = "codegen")] -pub use async_trait::async_trait; - #[doc(inline)] pub use codec::Streaming; pub use extensions::GrpcMethod; diff --git a/tonic/src/request.rs b/tonic/src/request.rs index e2d382270..1d6709e86 100644 --- a/tonic/src/request.rs +++ b/tonic/src/request.rs @@ -327,18 +327,16 @@ impl Request { /// And picked up by RPCs: /// /// ```no_run - /// use tonic::{async_trait, Status, Request, Response}; + /// use tonic::{Status, Request, Response}; /// # /// # struct Output {} /// # struct Input; /// # struct MyService; /// # struct MyExtension; - /// # #[async_trait] /// # trait TestService { /// # async fn handler(&self, req: Request) -> Result, Status>; /// # } /// - /// #[async_trait] /// impl TestService for MyService { /// async fn handler(&self, req: Request) -> Result, Status> { /// let value: &MyExtension = req.extensions().get::().unwrap(); diff --git a/tonic/src/server/grpc.rs b/tonic/src/server/grpc.rs index 0b057fcfb..882fc0ab7 100644 --- a/tonic/src/server/grpc.rs +++ b/tonic/src/server/grpc.rs @@ -75,10 +75,8 @@ where /// # fn new(svc: T) -> Self { Self(svc) } /// # fn accept_compressed(self, _: CompressionEncoding) -> Self { self } /// # } - /// # #[tonic::async_trait] /// # trait Example {} /// - /// #[tonic::async_trait] /// impl Example for Svc { /// // ... /// } @@ -106,10 +104,8 @@ where /// # fn new(svc: T) -> Self { Self(svc) } /// # fn send_compressed(self, _: CompressionEncoding) -> Self { self } /// # } - /// # #[tonic::async_trait] /// # trait Example {} /// - /// #[tonic::async_trait] /// impl Example for Svc { /// // ... /// } @@ -134,10 +130,8 @@ where /// # fn new(svc: T) -> Self { Self(svc) } /// # fn max_decoding_message_size(self, _: usize) -> Self { self } /// # } - /// # #[tonic::async_trait] /// # trait Example {} /// - /// #[tonic::async_trait] /// impl Example for Svc { /// // ... /// } @@ -164,10 +158,8 @@ where /// # fn new(svc: T) -> Self { Self(svc) } /// # fn max_encoding_message_size(self, _: usize) -> Self { self } /// # } - /// # #[tonic::async_trait] /// # trait Example {} /// - /// #[tonic::async_trait] /// impl Example for Svc { /// // ... /// } diff --git a/tonic/src/server/service.rs b/tonic/src/server/service.rs index 7fdfc569e..642d5aeee 100644 --- a/tonic/src/server/service.rs +++ b/tonic/src/server/service.rs @@ -11,21 +11,24 @@ pub trait UnaryService { /// Protobuf response message type type Response; - /// Response future - type Future: Future, Status>>; - /// Call the service - fn call(&mut self, request: Request) -> Self::Future; + fn call( + &mut self, + request: Request, + ) -> impl Future, Status>> + Send; } impl UnaryService for T where T: Service, Response = Response, Error = crate::Status>, + >>::Future: Send, { type Response = M2; - type Future = T::Future; - fn call(&mut self, request: Request) -> Self::Future { + fn call( + &mut self, + request: Request, + ) -> impl Future, Status>> + Send { Service::call(self, request) } } @@ -41,23 +44,26 @@ pub trait ServerStreamingService { /// Stream of outbound response messages type ResponseStream: Stream>; - /// Response future - type Future: Future, Status>>; - /// Call the service - fn call(&mut self, request: Request) -> Self::Future; + fn call( + &mut self, + request: Request, + ) -> impl Future, Status>> + Send; } impl ServerStreamingService for T where T: Service, Response = Response, Error = crate::Status>, + >>::Future: Send, S: Stream>, { type Response = M2; type ResponseStream = S; - type Future = T::Future; - fn call(&mut self, request: Request) -> Self::Future { + fn call( + &mut self, + request: Request, + ) -> impl Future, Status>> + Send { Service::call(self, request) } } @@ -70,21 +76,24 @@ pub trait ClientStreamingService { /// Protobuf response message type type Response; - /// Response future - type Future: Future, Status>>; - /// Call the service - fn call(&mut self, request: Request>) -> Self::Future; + fn call( + &mut self, + request: Request>, + ) -> impl Future, Status>> + Send; } impl ClientStreamingService for T where T: Service>, Response = Response, Error = crate::Status>, + >>>::Future: Send, { type Response = M2; - type Future = T::Future; - fn call(&mut self, request: Request>) -> Self::Future { + fn call( + &mut self, + request: Request>, + ) -> impl Future, Status>> + Send { Service::call(self, request) } } @@ -100,23 +109,26 @@ pub trait StreamingService { /// Stream of outbound response messages type ResponseStream: Stream>; - /// Response future - type Future: Future, Status>>; - /// Call the service - fn call(&mut self, request: Request>) -> Self::Future; + fn call( + &mut self, + request: Request>, + ) -> impl Future, Status>> + Send; } impl StreamingService for T where T: Service>, Response = Response, Error = crate::Status>, + >>>::Future: Send, S: Stream>, { type Response = M2; type ResponseStream = S; - type Future = T::Future; - fn call(&mut self, request: Request>) -> Self::Future { + fn call( + &mut self, + request: Request>, + ) -> impl Future, Status>> + Send { Service::call(self, request) } }