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

Poor error suggestion from failure to use trait #44

Closed
jnqnfe opened this issue Nov 25, 2020 · 2 comments
Closed

Poor error suggestion from failure to use trait #44

jnqnfe opened this issue Nov 25, 2020 · 2 comments

Comments

@jnqnfe
Copy link

jnqnfe commented Nov 25, 2020

This is probably an issue best suited for rustc itself rather than this crate, but I wanted to start here in case there's anything to be done for your crate to improve things...

I'm just now implementing use of this crate in one of mine (thanks btw!), and I forgot initially to add a use num_traits::FromPrimitive; line in the file, since the instructions for this crate failed to remind me of the need :p

The error message that resulted (using rustc v1.47) was:

error[E0599]: no variant or associated item named `from_i32` found for enum `capi::pa_port_available_t` in the current scope
   --> pulse-binding/src/context/introspect.rs:351:48
    |
351 |                 available: def::PortAvailable::from_i32(src.available).unwrap(),
    |                                                ^^^^^^^^ variant or associated item not found in `capi::pa_port_available_t`
    |
    = help: items from traits can only be used if the trait is in scope
    = note: the following trait is implemented but not in scope; perhaps add a `use` for it:
            `use crate::channelmap::_IMPL_NUM_ToPrimitive_FOR_Position::_num_traits::FromPrimitive;`

That use suggestion is obviously not the most helpful.

It is similar to what was noticed in issue #27, though it that case it was referencing an external crate. Here it's referencing... well, I guess something generated by the macros via the derive... within my own crate... though for a completely different module than the one containing the type I'm calling the method on (crate::def::PortAvailable). I have derived the trait on multiple enums throughout the crate, including within the channelmap module, and interestingly I think that module comes first alphabetically...

It's also not ideal that it's referencing capi::pa_port_available_t as the type the method is not found for, which is the original type from the 'sys' crate (aliased as capi) which this binding crate is re-exporting as def::PortAvailable. Which brings up the point that for this type, the derive is actually applied to it within the 'sys' crate, if that detail is at all important.

@cuviper
Copy link
Member

cuviper commented Nov 30, 2020

    = note: the following trait is implemented but not in scope; perhaps add a `use` for it:
            `use crate::channelmap::_IMPL_NUM_ToPrimitive_FOR_Position::_num_traits::FromPrimitive;`

This should be filed as a compiler bug -- _IMPL_NUM_ToPrimitive_FOR_Position is a private const generated by the derivation. Constants are not a valid path prefix regardless of publicity, so that suggestion makes no sense at all. I don't know how easy it would be for the compiler to find a path that is accessible to you though.

One way you can get around this is explicitly naming the crate (#35), #[num_traits = "num_traits"], which basically assumes that crate is in the extern prelude (no extern crate needed) and that the name is not shadowed locally. This is almost always true, but not assumed by the derivation.

It's also not ideal that it's referencing capi::pa_port_available_t as the type the method is not found for, which is the original type from the 'sys' crate (aliased as capi) which this binding crate is re-exporting as def::PortAvailable.

This may also be a compiler issue, but I'm less sure that anything can be changed here. Whether that's a type alias or a renamed use, they're all the exact same type to the compiler, and the original name would be canonical. If you really want to hide that from end users, you'd need a newtype wrapper like struct PortAvailable(capi::pa_port_available_t);.

@jnqnfe
Copy link
Author

jnqnfe commented Nov 30, 2020

Ok, thanks, I'll try to remember to pass it along as a compiler bug shortly, very busy just at the moment though. :)

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

No branches or pull requests

2 participants