Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement inherent associated items (see RFC 195). #8995

Open
pnkfelix opened this issue Sep 5, 2013 · 21 comments
Open

implement inherent associated items (see RFC 195). #8995

pnkfelix opened this issue Sep 5, 2013 · 21 comments

Comments

@pnkfelix
Copy link
Member

@pnkfelix pnkfelix commented Sep 5, 2013

This issue is tracking RFC 195's inherent associated items

Original description follows.

When developing a type-parametric impl, I found myself writing code somewhat like this:

    struct Grammar<T, NT> { ... }

    impl<T:Clone,NT:Eq+Hash+Clone+Primable> Grammar<T,NT> {
        fn to_nt_map(&self) -> HashMap<NT, ~[Prod<T,NT>]>
        {
            type Rules = ~[Prod<T,NT>];
            type NTMap = HashMap<NT, Rules>;        
          ...
        }

        fn from_nt_map(start: &NT, rules: &HashMap<NT, ~[Prod<T,NT>]>)
            -> Grammar<T,NT>
        {
            type Rules = ~[Prod<T,NT>];
            type NTMap = HashMap<NT, Rules>;
          ...
        }

        pub fn eliminate_left_recursion(&self) -> Grammar<T,NT>
        {
          ...
        }

        ...

    }

I cannot make a type definition for HashMap<NT, ~[Prod<T,NT>]> outside of the impl because it then those free references to NT and T would be unbound.

And I cannot put a type definition within the impl, even an impl for a struct such as this (it simply does not parse with the current grammar).

(Being able to put type definitions within impls will probably arise naturally from #5033, when we get around to that. But that is nonetheless a separate issue from this: Associated Types (and Associated Items) are about enabling certain patterns for the user of a trait, while this ticket describes a convenience for the implementor of a struct.)

Implementation History

  • Add a feature gate so they can be declared (but not used): #82516
@emberian
Copy link
Member

@emberian emberian commented Dec 30, 2013

Nominating; is backwards compatible. I can try and take this on if we decide we want it.

@emberian

This comment was marked as off-topic.

@pnkfelix

This comment was marked as off-topic.

@emberian

This comment was marked as off-topic.

@huonw

This comment was marked as off-topic.

@emberian

This comment was marked as off-topic.

@pnkfelix
Copy link
Member Author

@pnkfelix pnkfelix commented Jan 9, 2014

assigning P-low priority (is backwards compatible going foward, as cmr said).

@reem
Copy link
Contributor

@reem reem commented Sep 15, 2014

Triage: How does this interact with Associated Types? At least a new syntax would probably have to be chosen.

@pnkfelix
Copy link
Member Author

@pnkfelix pnkfelix commented Oct 6, 2014

I think that this feature request is actually satisfied by the Associated Items RFC.

In particular, the section "inherent associated items" of RFC 59 implies (to me) that you can write the exact example that I had asked for.

(I did write in the issue description that this feature request is distinct from associated types, but nonetheless, it seems that the author of RFC 59 decided that it was a natural feature to include.)

@pnkfelix
Copy link
Member Author

@pnkfelix pnkfelix commented Oct 6, 2014

So, this now seems to be a subissue of #17307.

I will change the title to "implement inherent associated items."

@pnkfelix pnkfelix changed the title RFC: allow type definition item within impl implement inherent associated items (see RFC 59). Oct 6, 2014
@rohel01
Copy link

@rohel01 rohel01 commented Aug 14, 2015

Hello, I hope this the right place to ask for my request.

Associated types currently only work with traits.
I think they are also useful for structs. Is there a reason for the current limitation ?

pub struct GenericStruct<A, B> {
    fa : A,
    fb : B,
}

struct GenericResult<A, B> {
    fa : A,
    fb : B,
}

impl <A, B> GenericStruct<A, B> {


    // I d like to write
    // type Result = Option<GenericResult<A, B>>;
    // and use it in the code

    fn new(a: A, b : B) -> Option<GenericResult<A, B>> {
        Some(GenericResult {fa: a, fb : b})

    }
}
@steveklabnik
Copy link
Member

@steveklabnik steveklabnik commented Feb 7, 2017

I'm going to tag this with the tags from #8995 since it was closed without this being implemented.

@yodaldevoid
Copy link
Contributor

@yodaldevoid yodaldevoid commented Jan 8, 2018

@steveklabnik I think you meant to reference #17307 rather than #8995, which is this issue.

@tinaun
Copy link
Contributor

@tinaun tinaun commented Jan 22, 2018

note that inherent associated consts work perfectly fine today

#[derive(Debug)]
struct Vector {
    x: f32,
    y: f32,
    z: f32,
}

impl Vector {
    const ZERO: Self = Vector { x: 0.0, y: 0.0, z: 0.0 };
    
    fn new(x: f32, y: f32, z: f32) -> Self {
        Vector {
            x, y, z
        }
    }
}
@eddyb
Copy link
Member

@eddyb eddyb commented Aug 20, 2018

@nikomatsakis Is it right to assume that this can't be implemented without lazy normalization?

@varkor
Copy link
Member

@varkor varkor commented Jan 8, 2019

It would be good to link to this issue in the error message for https://doc.rust-lang.org/nightly/error-index.html#E0202, as it's not immediately clear that this is supposed to be supported.

@alexreg
Copy link
Contributor

@alexreg alexreg commented Jan 28, 2019

Any developments on this lately?

@pnkfelix pnkfelix changed the title implement inherent associated items (see RFC 59). implement inherent associated items (see RFC 195). Jan 31, 2019
@ColonelThirtyTwo
Copy link

@ColonelThirtyTwo ColonelThirtyTwo commented May 4, 2019

Ran into this limitation today. A simplified example of what I'm trying to do:

trait GenericBackend {
    type ParentObject: GenericParentObject<Self>;
    type ChildObject: GenericChildObject<Self>;
    fn parent() -> Self::ParentObject;
}
trait GenericParentObject<Backend: GenericBackend> {
    fn get_children(&self) -> Vec<Backend::ChildObject>;
}
trait GenericChildObject<Backend: GenericBackend> {
}

Defining the traits works, but trying to impl them leads to an error referencing this issue.

Would like to see this implemented!

Nevermind. What I was trying to do works. I just put "impl MyStruct" instead of "impl MyTrait for MyStruct"...

@petrochenkov
Copy link
Contributor

@petrochenkov petrochenkov commented May 4, 2019

Blocked on #60471 (Lazy normalization).

QazerLab added a commit to QazerLab/commrate that referenced this issue Oct 27, 2019
Collapse PreFilters and PostFilters into the single type and
implementation using the associated type (Descriptor) for distinguishing
between commit evaluation stages and to group filters into chains
per single stage.

The calling code may be simplified even more as soon as associated types
will be allowed in inherent implementations:

rust-lang/rust#8995
@ZaMaZaN4iK
Copy link

@ZaMaZaN4iK ZaMaZaN4iK commented Sep 6, 2020

Any updates?

@garbageslam
Copy link

@garbageslam garbageslam commented Sep 15, 2020

It would be great to get this in some form, it can make generic programming a lot easier.

Suppose I have a generic struct, and I need to implement several functions on it which all refer to the same "complex" type in their return parameters or arguments, and the type depends on generic parameters. This is a pretty common situation. Naturally I'd like to give that type a nice name and avoid typing it repeatedly.

But, there is no where for that declaration to go if it depends on the generic parameters of the struct.

  • It cannot go in the struct declaration itself because type aliases in a struct are not allowed.
  • It cannot go in the inherent impl, because of this issue.
  • It cannot even be a type alias defined in a function body, "because it depends on an outer parameter"

It seems I have to either
(1) Make an entirely new trait just for this, and make my type an associated type of that trait
(2) Use a macro
(3) Just give up and type it out repeatedly

It's frustrating because in other languages there are better ways

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet