Open pnkfelix opened 11 years ago
Nominating; is backwards compatible. I can try and take this on if we decide we want it.
(type aliases would need to preceed all methods)
@cmr said "(type aliases would need to preceed all methods)"
why? To my knowledge there is no such ordering constraint for type aliases within a mod item, so why would an impl item require this?
@pnkfelix yikes, you're right. I think they should be. Why? Because:
#[crate_type="lib"];
mod bar {
fn foo() -> T {
32i
}
type T = int;
}
is crazy.
Why is that less crazy than
fn foo() { bar() }
fn bar() {}
?
I cede.
On Tue, Dec 31, 2013 at 1:05 AM, Huon Wilson notifications@github.comwrote:
Why is that less crazy than
fn foo() { bar() } fn bar() {}
?
— Reply to this email directly or view it on GitHubhttps://github.com/mozilla/rust/issues/8995#issuecomment-31385141 .
assigning P-low priority (is backwards compatible going foward, as cmr said).
Triage: How does this interact with Associated Types? At least a new syntax would probably have to be chosen.
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.)
So, this now seems to be a subissue of #17307.
I will change the title to "implement inherent associated items."
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})
}
}
I'm going to tag this with the tags from https://github.com/rust-lang/rust/issues/8995 since it was closed without this being implemented.
@steveklabnik I think you meant to reference #17307 rather than #8995, which is this issue.
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
}
}
}
@nikomatsakis Is it right to assume that this can't be implemented without lazy normalization?
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.
Any developments on this lately?
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"...
Blocked on https://github.com/rust-lang/rust/issues/60471 (Lazy normalization).
Any updates?
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.
struct
declaration itself because type aliases in a struct
are not allowed.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
For the sake of updating status for people driving by, since it wasn't even linked to this issue at all, the latest progress I believe was made in #82516 which implemented the basics of defining inherent associated types but does not allow their use yet.
Wow this issue is open since 2013. Does anyone know when it's going to make it to stable?
For the sake of updating status for people driving by, since it wasn't even linked to this issue at all, the latest progress I believe was made in #82516 which implemented the basics of defining inherent associated types but does not allow their use yet.
Well it is :) that PR has F-inherent_associated_types
label and this tracking issue listed it in the "Implementation History" section.
Does anyone know when it's going to make it to stable?
It's not yet implemented :(
This feature could use a form of doc(inline)
for rustdoc, so when defining associated types that are only reachable from there, the documentation for the type would still be accessible.
For example, here is rendered documentation for "associated enums" for the C++ API, sf::BlendMode
:
The rendered documentation for the Rust binding, using the experimental associated_types feature:
Ideally, the type definition could be inlined when doc(inline)
attribute is present on the associated type item.
Optionally, there could be an automatic inlining, similar to when re-exports re-export something that is only reachable through that re-export, the docs get inlined without having to do anything special.
Were there any changes made to this in one of last releases?
struct Foo {
bar: Self::Bar,
}
impl Foo {
pub type Bar = usize;
}
used to work a couple of nightly releases ago.
Now it fails to compile with error:
error[E0391]: cycle detected when computing predicates of `Foo`
--> src\main.rs:5:1
|
5 | struct Foo {
| ^^^^^^^^^^
|
note: ...which requires computing predicates of `Foo`...
--> src\main.rs:5:1
|
5 | struct Foo {
| ^^^^^^^^^^
note: ...which requires computing inferred outlives predicates of `Foo`...
--> src\main.rs:5:1
|
5 | struct Foo {
| ^^^^^^^^^^
= note: ...which requires computing the inferred outlives predicates for items in this crate...
note: ...which requires computing type of `Foo::bar`...
--> src\main.rs:6:5
|
6 | bar: Self::Bar,
| ^^^^^^^^^^^^^^
note: ...which requires computing normalized predicates of `Foo`...
--> src\main.rs:5:1
|
5 | struct Foo {
| ^^^^^^^^^^
= note: ...which again requires computing predicates of `Foo`, completing the cycle
note: cycle used when collecting item types in top-level module
I am just curious about the status of this issue. Is someone working on this or has someone made any progress in this space?
There's been a recent series of PRs that work towards fully implementing inherent associated types by @fee1-dead, @cjgillot and me.
I highly suspect that the last one on that list (#105961) broke the code posted above. @peku33, could you please open an issue for the cycle error and tag me? Thanks. Note however that inherent_associated_types
is still an incomplete feature and thus it's likely to break every so often.
Is someone working on this or has someone made any progress in this space?
@flouet-company, I'm assigned to several issues related to IATs and I'm in close contact with some members of T-types in order to properly implement inherent associated types.
I'd just like to say thank you to you three for working on this feature! I know it's not simple, but it's something a lot of people will appreciate when it's eventually completed.
This seems particularly important for resolving 'clippy::type_complexity' when using large types inside parameterized types with multiple arguments.
Normally we'd use a type Foo = Bar<A, B, C>;
but in a generic type, those types may not be accessible except via more type parameters, leading to new complex types.
Keep to hear more about blockers :)
Keep to hear more about blockers
The most recent major blocker is fixing #108491 which is not easy it seems. Basically, you cannot use inherent associated types inside of structs, enums, unions or where clauses (as opposed to function bodies, constants and type aliases) and some function signatures without encountering a cycle error first. According to my current understanding this is due to architectural limitations in the compiler (see this semi-related Zulip topic, cc #22519 the equivalent for trait assoc tys).
Since #109410 got merged, I'm investigating approaches to solve this in a proper way without too much rework.
This is a tracking issue for the "inherent associate type" part of "inherent associated items" part of the RFC 195 "associated items"
About tracking issues
Tracking issues are used to record the overall progress of implementation. They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions. A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature. Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.
Original description
(This code is written in ancient version of Rust, and is not meant to be used directly.)
When developing a type-parametric impl, I found myself writing code somewhat like this:
I cannot make a
type
definition forHashMap<NT, ~[Prod<T,NT>]>
outside of theimpl
because it then those free references toNT
andT
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.)
Steps
Unresolved Questions
Implementation history
82516
103621
104348
105224
105315
105768
105961
109410
110945
111486
114594
118118
118262