Trait bound on struct and constructor

Greetings,

I am attempting to create a struct, and its constructor, both being generic trait bounded:

use std::path::Path;
use std::fmt::Debug;

pub struct Foo<P>
where
    P: AsRef<Path>,
{
    file_path: P,
}

impl<P> Foo<P>
where
    P: AsRef<Path> + Debug,
{
    fn bar(
        &self,
    ) { 
        println!("{:?}", self.file_path)
    }   

    fn new<P>(
        file_path: P,
    ) -> Self {
        Self {
            file_path,
        }   
    }   
}

fn main(
) {
    let foo = Foo {
        file_path: "/etc/passwd",
    };  
    foo.bar();
}

If I comment out the "new" function, the code compiles. If I leave it as-is, then I get:

   Compiling pathbuf_struct v0.1.0 (/home/mzagrabe/git/internal/rust/projects/pathbuf_struct)
error[E0403]: the name `P` is already used for a generic parameter in this item's generic parameters
  --> src/main.rs:21:12
   |
11 | impl<P> Foo<P>
   |      - first use of `P`
...
21 |     fn new<P>(
   |            ^ already used

error[E0308]: mismatched types
  --> src/main.rs:25:13
   |
11 | impl<P> Foo<P>
   |      - expected type parameter
...
21 |     fn new<P>(
   |            - found type parameter
...
25 |             file_path,
   |             ^^^^^^^^^ expected type parameter `P`, found a different type parameter `P`
   |
   = note: expected type parameter `P` (type parameter `P`)
              found type parameter `P` (type parameter `P`)
   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters

Some errors have detailed explanations: E0308, E0403.
For more information about an error, try `rustc --explain E0308`.
error: could not compile `pathbuf_struct` due to 2 previous errors

I've tried a few different incantations and permutations for the constructor signature, but I don't quite understand the generic and trait bound constraints.

Does anyone have suggestions about what to do, or where to look?

Thanks!

-m

The error says exactly what the problem is here.

Do you really want a different type parameter on new? Or did you want the same one that's in Self?

Hi @scottmcm,

The same. I suppose I thought by naming it the same, I was using the same generic type.

How do I use the same type as in Self?

Nope, by declaring it again (<P>) you're declaring a new generic type.

If you don't want another one, don't declare it again: fn new(file_path: P) -> Self {.

Huzzah! Thanks @scottmcm ! That did the trick.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.