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

Confusing error message when attempting to use a context selector without a context #389

Open
jmrgibson opened this issue Aug 1, 2023 · 1 comment
Labels
enhancement New feature or request found in the field A user of SNAFU found this when trying to use it help wanted Extra attention is needed

Comments

@jmrgibson
Copy link

jmrgibson commented Aug 1, 2023

When attempting to use a generated context selector in a macro like ensure! that doesn't provide a context, the error message is quite confusing if the context selector has fields like "source".

For example

use snafu::prelude::*;

#[derive(Debug, Snafu)]
pub enum Error {
    Foo {
        source: std::io::Error,  // this is the problematic line
        id: usize,
    }
}

fn main() {
    ensure!(1 == 1, FooSnafu{id: 10})
}

gives the error message

error[E0599]: no method named `fail` found for struct `FooSnafu` in the current scope
  --> src/main.rs:12:5
   |
3  | #[derive(Debug, Snafu)]
   |                 ----- method `fail` not found for this struct
...
12 |     ensure!(1 == 1, FooSnafu{id: 10})
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ method not found in `FooSnafu<{integer}>`
   |
   = note: this error originates in the macro `ensure` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0599`.
error: could not compile `snafu-error-example` due to previous error
@shepmaster shepmaster added enhancement New feature or request help wanted Extra attention is needed found in the field A user of SNAFU found this when trying to use it labels Aug 1, 2023
@shepmaster
Copy link
Owner

Hmm. I'm honestly not very sure what we could do to improve this case. The ensure macro basically expands to $selector.fail() and thus you get the error seen.

It's possible that a combination of two things could help:

If those two things existed, the macro could be changed to expand to TheBuildTrait::fail($selector) and we could put #[diagnostic::on_unimplemented] on TheBuildTrait. That might allow us to have an error like "fail is only available for context selectors that do not have a source".

If you had seen something along those lines added to the error you already got, do you think it would have helped?

error[E0599]: no method named `fail` found for struct `FooSnafu` in the current scope
  --> src/main.rs:12:5
   |
3  | #[derive(Debug, Snafu)]
   |                 ----- method `fail` not found for this struct
...
12 |     ensure!(1 == 1, FooSnafu{id: 10})
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ method not found in `FooSnafu<{integer}>`
   |
   = help: the trait `TheBuildTrait` is not implemented for context selectors that do not have a source

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request found in the field A user of SNAFU found this when trying to use it help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants