Description
Note: not sure if this is a compiler bug or an async_trait bug.
This code reports an error incorrectly:
#[macro_use]
use async_trait::async_trait; // 0.1.24
use std::path::*;
struct DiceCtx();
impl DiceCtx {
async fn compute<T: Key>(&self, v: &T) -> <T as Key>::Value {
todo!()
}
}
#[async_trait]
trait InterpreterFileOps {
async fn read_dir(&self, path: &Path) -> Result<(), ()>;
}
#[async_trait]
trait Key {
type Value;
async fn compute(&self, ctx: &DiceCtx) -> Self::Value;
}
struct DiceInterpreterFileOps(DiceCtx);
#[async_trait]
impl InterpreterFileOps for DiceInterpreterFileOps {
async fn read_dir(&self, path: &Path) -> Result<(), ()> {
struct ReadDirKey(PathBuf);
#[async_trait]
impl Key for ReadDirKey {
type Value = Result<Vec<()>>;
// This correctly reports the error
// type Value = Result<(Vec<()>)>;
async fn compute(&self, ctx: &DiceCtx) -> Self::Value {
Unknown{}.foo()
}
}
self.0.compute(&ReadDirKey(path.to_owned())).await
}
}
Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f5fbf51f00d3755d6bc3a025e75f3d30
It reports the error as:
Compiling playground v0.0.1 (/playground)
error[E0422]: cannot find struct, variant or union type `Unknown` in this scope
--> src/lib.rs:34:9
|
34 | #[async_trait]
| ^^^^^^^^^^^^^^ not found in this scope
|
help: possible candidates are found in other modules, you can import them into scope
|
Note that it marks the macro invocation itself. Making the change that is commented (i.e. adding a redundant ()
around Vec<()>
will make it report the error correctly:
error[E0422]: cannot find struct, variant or union type `Unknown` in this scope
--> src/lib.rs:42:17
|
42 | Unknown{}.foo()
| ^^^^^^^ not found in this scope
|
help: possible candidates are found in other modules, you can import them into scope
|
It does this even worse for some other errors. If you replace that Unknown{}.foo()
with todo!()
(https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=95645128b3ff65057921bbd952f0005b) you'll get this error:
error[E0107]: wrong number of type arguments: expected 2, found 1
error: aborting due to previous error
That doesn't even point to the async_trait use at all (which makes it quite difficult to diagnose).
Again, adding the ()
around Vec<()>
fixes the reporting:
error[E0107]: wrong number of type arguments: expected 2, found 1
--> src/lib.rs:36:26
|
36 | type Value = Result<(Vec<()>)>;
| ^^^^^^^^^^^^^^^^^ expected 2 type arguments
error: aborting due to previous error