Skip to content

Calling trait function declared with both explicit generics and impl Trait gives confusing errors #94836

Description

@lopopolo

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.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions