Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improperly reported compilation errors when using async_trait #91

Closed
cjhopman opened this issue Apr 7, 2020 · 3 comments
Closed

Improperly reported compilation errors when using async_trait #91

cjhopman opened this issue Apr 7, 2020 · 3 comments

Comments

@cjhopman
Copy link

cjhopman commented Apr 7, 2020

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
@dtolnay
Copy link
Owner

dtolnay commented Apr 7, 2020

Both of these are a consequence of this compiler bug: rust-lang/rust#43081. It would be better not to nest attribute macro invocations on items until that is fixed.

@Aaron1011
Copy link

This will be fixed by rust-lang/rust#72306

@dtolnay
Copy link
Owner

dtolnay commented May 22, 2020

Confirmed fixed in rustc master. The error from the above repro looks like:

error[E0422]: cannot find struct, variant or union type `Unknown` in this scope
  --> src/main.rs:42:17
   |
42 |                 Unknown{}.foo()
   |                 ^^^^^^^ not found in this scope
   |
help: consider importing one of these items
   |
2  | use core::fmt::rt::v1::Alignment::Unknown;
   |
2  | use std::fmt::rt::v1::Alignment::Unknown;
   |

error[E0107]: wrong number of type arguments: expected 2, found 1
  --> src/main.rs:36:26
   |
36 |             type Value = Result<Vec<()>>;
   |                          ^^^^^^^^^^^^^^^ expected 2 type arguments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants