-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
RFC: Tuple struct construction with Self(v1, v2, ..)
#2302
Conversation
Self(v1, v2, ..)
The proposal unearths another unexpected limitation. A type alias for a tuple struct can not be used with tuple struct init syntax right now (without struct FooBar(u8);
type BarFoo = FooBar;
impl Default for BarFoo {
fn default() -> Self {
// Self(42) // proposed in rfc
BarFoo(42) // does not compile
// expected function, found type alias `BarFoo`
// BarFoo { 0: 42 } // works
}
} |
I think that limitation isn't possible to get around without bc-breaks tho simply because EDIT: perhaps the break wouldn't be all that extensive so it could be lumped into the next epoch..? Personally I think we should improve what we can here =) |
I think epochs could and should be used to deprecate any existing harmful name collisions, like |
Linking RFC #1506. |
text/0000-tuple-struct-self-ctor.md
Outdated
impl Default for TheAnswer { | ||
fn default() -> Self { Self(42) } | ||
} | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If tuple structs are supported, then unit structs can be supported in the same way:
struct TheAnswer;
impl Default for TheAnswer {
fn default() -> Self { Self }
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered it initially but didn't for some reason I can't remember. I can add that to the RFC if you like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are three forms of instantiation (to use the word slightly fuzzily): Self { }
, Self()
and Self
. Self { }
already works. You’ve proposed adding Self()
for consistency. It doesn’t seem to me that it fixes consistency properly unless Self
is also made to work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chris-morgan Sure, I'll change the RFC accordingly Soon™.
Previous discussion: https://internals.rust-lang.org/t/initialization-syntax-for-self-tuple-structs/5389 |
text/0000-tuple-struct-self-ctor.md
Outdated
``` | ||
|
||
the compiler will desugar the application by substituting `Self(v0, v1, ..)` | ||
for `Self { 0: v0, 1: v1, .. }` and then continue on from there. The compiler |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This desugaring is not entirely equivalent to what constructors of tuple struct can do. In
struct S(u8);
S
in value namespace is a constructor function and it can be used in all contexts where a fn(u8) -> S { ... }
is accepted, not only direct calls S(arg)
.
(S)(0u8); // OK
opt_u8.map(S); // OK
(Self)(0u8); // Not OK, not a direct call
opt_u8.map(Self); // Not OK, not a direct call
Ideally, Self
should be a first-class "function alias" and refer to the constructor function (with appropriate generic parameter substitutions).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Self
should be a first-class "function alias"
Or a "const alias" for unit structs. "Value alias", in general.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's strictly more powerful I guess, so I could change the desugaring to go in this direction if we want to support that. Do we want to support that? Why / why not?
By analogy with #2300 (comment), it's interesting to list what
Inconsistencies:
Future compatibility:
|
@rfcbot fcp merge |
Team member @withoutboats has proposed to merge this. The next step is review by the rest of the tagged teams: No concerns currently listed. Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
I'm happy as long as we think this is backwards compatible and works. (@petrochenkov -- do you?) |
I'm not 100% sure that Currently a struct and its constructor are almost entirely independent items, i.e. you can turn a tuple struct into a braced struct + a separate With name-based resolution you can potentially resolve On the other hand, maybe making structs and their constructors "separable" is not an important goal. |
This is interesting. You're saying that right now going from this: pub struct Foo(pub u8); To this: pub struct Foo { bar: u8 }
pub fn Foo(bar: u8) -> Foo { Foo { bar } } Would not be a breaking change. But this RFC would make it a breaking change because anyone who used the constructor as |
Well, it's still a breaking change because |
@scottmcm #![feature(const_fn)]
const fn Foo() -> u8 {
10
}
const C: u8 = Foo();
fn main() {
match 10u8 {
C => println!("match!"),
_ => println!("not match!"),
}
} , we just need to accept non-tuple-struct calls directly in pattern positions. The question is whether we should go in this direction, or "separability" of structs and their constructors is not an important property. |
@petrochenkov How do const functions help there? Wouldn't we need to be able to solve const functions backwards for that to work? e.g. |
Sounds like "pattern synonyms" / "pattern aliases" / "custom patterns". |
If its not a non-breaking change today then I'm not very concerned about this RFC changing that personally. |
No, it would substitute the body of |
@petrochenkov I don't think that's the case after miri integration (cc @oli-obk). |
Ok, I guess if we solve the much bigger pattern problem, we'll be able to come up with some solution for |
Similarly to #2300, I have a concern here that |
Is there a reason we can't project |
@rfcbot fcp merge The companion RFC has been merged, having addressed @nrc's concerns. I believe this should be merged as well. |
Team member @aturon has proposed to merge this. The next step is review by the rest of the tagged teams: No concerns currently listed. Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
I think this is what we should do (#2302 (comment)). |
@petrochenkov So iirc the consensus from the last lang team meeting was that permitting As you are more familiar with the alternate proposed desugaring would you be willing to update the RFC with a PR against my branch? (Note: as written, the RFC also supports |
…nit structs, change reference explanation, etc. + consequence changes.
Fix RFC 2302 to support unit structs, fn pointers, and use value namespace instead for exprs
Patched the RFC to support unit structs and use the value namespace ( |
text/0000-tuple-struct-self-ctor.md
Outdated
``` | ||
pat : ... // <-- The original grammar of `pat` prior to this RFC. | ||
| SELF '(' ')' | ||
| SELF '(' pat_tup ')' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The grammar doesn't change, technically, it's still PATH ( ... )
and Self
is already a valid path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the entire ## Grammar
section can be removed then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aight; removed it :)
LGTM. |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
The final comment period, with a disposition to merge, as per the review above, is now complete. |
Huzzah! This RFC is merged! Tracking issue: rust-lang/rust#51994 |
Rendered
Tracking issue
Tuple
struct
s can now be constructed and pattern matched withSelf(v1, v2, ..)
. A simple example:Similarly, unit structs can also be constructed and pattern matched with
Self
.