Open
Description
Given the following code:
I had a trait that was originally defined like this:
pub trait LoadSources {
fn def_file_for_type<P, T>(&mut self, path: P) -> Result<(), Box<dyn Error>>
where
P: AsRef<Path>,
T: File;
}
T
is a type parameter that is used to pass a function pointer into implementations of this trait.
Users of this API call it like this:
interp.def_file_for_type::<_, SecureRandomFile>("securerandom.rb")?;
I was trying to remove the P
type parameter to allow for a bit nicer of a turbofish without the anonymous placeholder so I redefined the trait to look like:
pub trait LoadSources {
fn def_file_for_type<T>(&mut self, path: impl AsRef<Path>) -> Result<(), Box<dyn Error>>
where
T: File;
}
I attempted to compile this before refactoring callers.
Full program below.
Playground link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=49b4d1c31975f80c7cc2f3c1f8a06933
use std::error::Error;
use std::path::Path;
pub trait File {}
pub trait LoadSources {
fn def_file_for_type<T>(&mut self, path: impl AsRef<Path>) -> Result<(), Box<dyn Error>>
where
T: File;
}
struct Interp {}
impl LoadSources for Interp {
fn def_file_for_type<T>(&mut self, path: impl AsRef<Path>) -> Result<(), Box<dyn Error>>
where
T: File
{
todo!()
}
}
pub struct SecureRandomFile {}
impl File for SecureRandomFile {}
pub fn main() {
let mut interp = Interp {};
interp.def_file_for_type::<_, SecureRandomFile>("securerandom.rb").unwrap();
}
The current output is:
Compiling playground v0.0.1 (/playground)
error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position
--> src/main.rs:29:32
|
29 | interp.def_file_for_type::<_, SecureRandomFile>("securerandom.rb").unwrap();
| ^ ^^^^^^^^^^^^^^^^ explicit generic argument not allowed
| |
| explicit generic argument not allowed
|
= note: see issue #83701 <https://github.com/rust-lang/rust/issues/83701> for more information
error[E0308]: mismatched types
--> src/main.rs:29:53
|
29 | interp.def_file_for_type::<_, SecureRandomFile>("securerandom.rb").unwrap();
| ^^^^^^^^^^^^^^^^^ expected struct `SecureRandomFile`, found `&str`
error[E0277]: the trait bound `SecureRandomFile: AsRef<Path>` is not satisfied
--> src/main.rs:29:53
|
29 | interp.def_file_for_type::<_, SecureRandomFile>("securerandom.rb").unwrap();
| ----------------- ^^^^^^^^^^^^^^^^^ the trait `AsRef<Path>` is not implemented for `SecureRandomFile`
| |
| required by a bound introduced by this call
|
note: required by a bound in `LoadSources::def_file_for_type`
--> src/main.rs:7:51
|
7 | fn def_file_for_type<T>(&mut self, path: impl AsRef<Path>) -> Result<(), Box<dyn Error>>
| ^^^^^^^^^^^ required by this bound in `LoadSources::def_file_for_type`
Some errors have detailed explanations: E0277, E0308, E0632.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `playground` due to 3 previous errors
Ideally the output should look like:
There are two errors here:
- Can't use explicit type argument when impl trait is used. This one is present but comes first and cargo ouput puts it out of the scrollback in my terminal.
- I'm using two named generic types when the function only has 1. This does not appear in the error output. Instead I get a lot of confusing things around type mismatches. I can't figure out what rustc is trying to tell me.