Associated function not found when implementing trait

I am trying to implement the clap::FromArgMatches on a custom enum (MyEnum). When I implement the from_arg_matches function on the enum (int the impl MyEnum block) everything compiles and I can call the function. However, if I change the impl MyEnum statement to an impl clap::FromArgMatches for MyEnum I receive the error variant or associated item not found when trying to call the function.

Any idea as to why this is occurring?

Here is an MRE.

use clap;

#[derive(Debug)]
enum Demo {
    Name(String),
}

// impl Demo {  // works
impl clap::FromArgMatches for Demo {  // error: no variant of associated item found
    fn from_arg_matches(matches: &clap::ArgMatches) -> Result<Self, clap::error::Error> {
        eprintln!("{:#?}", matches);
        Ok(Demo::Name(String::from("test@test.com")))
    }

    fn update_from_arg_matches(
        &mut self,
        matches: &clap::ArgMatches,
    ) -> Result<(), clap::error::Error> {
        eprintln!("{:#?}", matches);
        Ok(())
    }
}

fn main() {
    let matches = clap::Command::new("Test from_arg_matches")
        .arg(clap::Arg::new("user_id_email").default_value("test@test.com"))
        .get_matches();

    let d = Demo::from_arg_matches(&matches);
    eprintln!("{:?}", d);
}

When calling a trait's function, the it must be either qualified by the name of the trait,

let d: Demo = clap::FromArgMatches::from_arg_matches(&matches).unwrap();

or the trait must be in scope (defined in the same module, or brought into scope with use):

use clap::FromArgMatches;
let d: Demo = Demo::from_arg_matches(&matches).unwrap();

This rule of Rust exists so that a trait's mere existence in a crate cannot add new items to namespaces elsewhere, thus potentially breaking previous valid code “at a distance”; only traits that are brought into scope can affect name resolution.

(By the way, use clap; is redundant and does nothing — clap is already in scope. uses that have no :: in them anywhere are almost always unnecessary. One way to look at use is that it “shortens paths”: if you have foo in scope then use foo::bar; lets you write bar in place of foo::bar. But the thing on the left must always be already in scope.)

1 Like

Ahhh, that was it, thank you, and great explanation.

And thank you for the use advice as well.

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.