Skip to content

Commit

Permalink
Annotate types that impl Future with #[must_use].
Browse files Browse the repository at this point in the history
These types do nothing unless polled / .awaited.
Annotating them with #[must_use] helps prevent a common class of coding errors.

Fixes google#368.
  • Loading branch information
tikue committed Jun 6, 2022
1 parent 2594ea8 commit dc12bd0
Show file tree
Hide file tree
Showing 12 changed files with 135 additions and 0 deletions.
1 change: 1 addition & 0 deletions tarpc/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ where

/// Handles the lifecycle of requests, writing requests to the wire, managing cancellations,
/// and dispatching responses to the appropriate channel.
#[must_use]
#[pin_project]
#[derive(Debug)]
pub struct RequestDispatch<Req, Resp, C> {
Expand Down
1 change: 1 addition & 0 deletions tarpc/src/serde_transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ pub mod tcp {
}

/// A connection Future that also exposes the length-delimited framing config.
#[must_use]
#[pin_project]
pub struct Connect<T, Item, SinkItem, CodecFn> {
#[pin]
Expand Down
2 changes: 2 additions & 0 deletions tarpc/src/server/tokio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::pin::Pin;
/// A future that drives the server by [spawning](tokio::spawn) a [`TokioChannelExecutor`](TokioChannelExecutor)
/// for each new channel. Returned by
/// [`Incoming::execute`](crate::server::incoming::Incoming::execute).
#[must_use]
#[pin_project]
#[derive(Debug)]
pub struct TokioServerExecutor<T, S> {
Expand All @@ -23,6 +24,7 @@ impl<T, S> TokioServerExecutor<T, S> {
/// A future that drives the server by [spawning](tokio::spawn) each [response
/// handler](super::InFlightRequest::execute) on tokio's default executor. Returned by
/// [`Channel::execute`](crate::server::Channel::execute).
#[must_use]
#[pin_project]
#[derive(Debug)]
pub struct TokioChannelExecutor<T, S> {
Expand Down
4 changes: 4 additions & 0 deletions tarpc/tests/compile_fail.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@
fn ui() {
let t = trybuild::TestCases::new();
t.compile_fail("tests/compile_fail/*.rs");
#[cfg(feature = "tokio1")]
t.compile_fail("tests/compile_fail/tokio/*.rs");
#[cfg(all(feature = "serde-transport", feature = "tcp"))]
t.compile_fail("tests/compile_fail/serde_transport/*.rs");
}
15 changes: 15 additions & 0 deletions tarpc/tests/compile_fail/must_use_request_dispatch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use tarpc::client;

#[tarpc::service]
trait World {
async fn hello(name: String) -> String;
}

fn main() {
let (client_transport, _) = tarpc::transport::channel::unbounded();

#[deny(unused_must_use)]
{
WorldClient::new(client::Config::default(), client_transport).dispatch;
}
}
11 changes: 11 additions & 0 deletions tarpc/tests/compile_fail/must_use_request_dispatch.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error: unused `RequestDispatch` that must be used
--> tests/compile_fail/must_use_request_dispatch.rs:13:9
|
13 | WorldClient::new(client::Config::default(), client_transport).dispatch;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> tests/compile_fail/must_use_request_dispatch.rs:11:12
|
11 | #[deny(unused_must_use)]
| ^^^^^^^^^^^^^^^
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use tarpc::serde_transport;
use tokio_serde::formats::Json;

fn main() {
#[deny(unused_must_use)]
{
serde_transport::tcp::connect::<_, (), (), _, _>("0.0.0.0:0", Json::default);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error: unused `Connect` that must be used
--> tests/compile_fail/serde_transport/must_use_tcp_connect.rs:7:9
|
7 | serde_transport::tcp::connect::<_, (), (), _, _>("0.0.0.0:0", Json::default);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> tests/compile_fail/serde_transport/must_use_tcp_connect.rs:5:12
|
5 | #[deny(unused_must_use)]
| ^^^^^^^^^^^^^^^
29 changes: 29 additions & 0 deletions tarpc/tests/compile_fail/tokio/must_use_channel_executor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use tarpc::{
context,
server::{self, Channel},
};

#[tarpc::service]
trait World {
async fn hello(name: String) -> String;
}

#[derive(Clone)]
struct HelloServer;

#[tarpc::server]
impl World for HelloServer {
async fn hello(self, _: context::Context, name: String) -> String {
format!("Hello, {name}!")
}
}

fn main() {
let (_, server_transport) = tarpc::transport::channel::unbounded();
let server = server::BaseChannel::with_defaults(server_transport);

#[deny(unused_must_use)]
{
server.execute(HelloServer.serve());
}
}
11 changes: 11 additions & 0 deletions tarpc/tests/compile_fail/tokio/must_use_channel_executor.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error: unused `TokioChannelExecutor` that must be used
--> tests/compile_fail/tokio/must_use_channel_executor.rs:27:9
|
27 | server.execute(HelloServer.serve());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> tests/compile_fail/tokio/must_use_channel_executor.rs:25:12
|
25 | #[deny(unused_must_use)]
| ^^^^^^^^^^^^^^^
30 changes: 30 additions & 0 deletions tarpc/tests/compile_fail/tokio/must_use_server_executor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use futures::stream::once;
use tarpc::{
context,
server::{self, incoming::Incoming},
};

#[tarpc::service]
trait World {
async fn hello(name: String) -> String;
}

#[derive(Clone)]
struct HelloServer;

#[tarpc::server]
impl World for HelloServer {
async fn hello(self, _: context::Context, name: String) -> String {
format!("Hello, {name}!")
}
}

fn main() {
let (_, server_transport) = tarpc::transport::channel::unbounded();
let server = once(async move { server::BaseChannel::with_defaults(server_transport) });

#[deny(unused_must_use)]
{
server.execute(HelloServer.serve());
}
}
11 changes: 11 additions & 0 deletions tarpc/tests/compile_fail/tokio/must_use_server_executor.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error: unused `TokioServerExecutor` that must be used
--> tests/compile_fail/tokio/must_use_server_executor.rs:28:9
|
28 | server.execute(HelloServer.serve());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> tests/compile_fail/tokio/must_use_server_executor.rs:26:12
|
26 | #[deny(unused_must_use)]
| ^^^^^^^^^^^^^^^

0 comments on commit dc12bd0

Please sign in to comment.