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.