Skip to content

Inherent impls for traits #1971

@burdges

Description

@burdges

As written, this code works but the commented out line gives error[E0576]: cannot find method or associated constant meow in trait Foo.

pub trait Foo { }

struct Bar;

impl Foo  {
    pub fn meow() {  println!("Hello World!")  }
}

impl Foo for Bar { }

fn main() {
    Foo::meow();
    // <Bar as Foo>::meow();
}

If we want an inherent-like method meow for every type that satisfying Foo, but do not want clients modifying it, then we need a helper trait.

pub trait ImplFoo { 
    fn meow() {  println!("Bye World!")  }
}

impl<T> ImplFoo for T where T: Foo { }

fn main() {
    Bar::meow();
}

Worse, we need new help traits for every inherent-like block we want to create, so our API gets polluted with several exposed helper traits. Also this Foo::meow() looks kinda iffy.

I'd think inherent impls could simply "work as expected" for traits, so all three call sites would call the original :

impl Foo  {
    pub fn meow() {  println!("Hello World!")  }
}

For visibility purposes, these inherent trait methods could be treated as methods on an invisible wrapper struct that has the same name as the trait Foo:

struct Foo<T: Foo>(T);
impl<T: Foo> Foo<T> {
    pub fn meow() {  println!("Hello World!")  }
}

In this way, if Foo is defined in module A and meow in module B then the visibility of meow can be controlled as you would control the visibility of B::Foo.

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-langRelevant to the language team, which will review and decide on the RFC.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions