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

Clarify the relationships between various kinds of structs and variants #1506

Merged
merged 2 commits into from Aug 12, 2016

Conversation

Projects
None yet
@petrochenkov
Copy link
Contributor

petrochenkov commented Feb 22, 2016

Provide a simple model describing three kinds of structs and variants and their relationships + some small language extensions following from this model.

Rendered

cc rust-lang/rust#31757 (comment)


As a basic struct, a unit struct can participate in struct expressions `US{}`, including FRU
`US{..s}` and in struct patterns `US{}`/`US{..}`. In both cases the path `US` of the expression
or pattern is looked up in the type namespace.

This comment has been minimized.

@arielb1

arielb1 Feb 22, 2016

Contributor

A unit struct/variant pattern is a struct/variant pattern, not a constant pattern, and therefore is exhaustive.

This comment has been minimized.

@petrochenkov

petrochenkov Feb 22, 2016

Author Contributor

There's a "Note 1" below (I could expand it though).

Fields of a braced struct can be accessed with dot syntax `s.field1`.

Note: struct *variants* are currently defined in the value namespace in addition to type namespace,
there are no particular reasons for this and this is probably temporary.

This comment has been minimized.

@arielb1

arielb1 Feb 22, 2016

Contributor

Do these have any use?

This comment has been minimized.

@petrochenkov

petrochenkov Feb 22, 2016

Author Contributor

No. (Not now at least.)
See rust-lang/rust#30882 (comment)


New: Permit tuple structs and tuple variants with 0 fields. This restriction is artificial and can
be lifted trivially. Macro writers dealing with tuple structs/variants will be happy to get rid of
this one special case.

This comment has been minimized.

@oli-obk

oli-obk Feb 22, 2016

Contributor

examples of crates that had to implement workarounds because of this limitation?

This comment has been minimized.

@petrochenkov

petrochenkov Feb 22, 2016

Author Contributor

I have an anecdotal evidence from @DanielKeep but no concrete examples so far.

This comment has been minimized.

@durka

durka Feb 22, 2016

Contributor

A more subtle question might be crates that are broken, but haven't noticed yet, because nobody tried to make it generate a struct with no fields.

@ubsan

This comment has been minimized.

Copy link
Contributor

ubsan commented Feb 22, 2016

I really like these ideas. If they're not taken up by Rust, I may steal them for my own language :)

Some improvements
Mention type aliases
Mention differences between unit structs / tuple struct constructors and `const` / `fn` items.
Add more use cases for `TS{0: expr}`/`TS{0: pat}`

@petrochenkov petrochenkov force-pushed the petrochenkov:adtkinds branch from dfbf8cb to 433edd9 Feb 28, 2016

@alexcrichton alexcrichton added the T-lang label Mar 7, 2016

Fields of a braced struct can be accessed with dot syntax `s.field1`.

Note: struct *variants* are currently defined in the value namespace in addition to type namespace,
there are no particular reasons for this and this is probably temporary.

This comment has been minimized.

@nrc

nrc Apr 27, 2016

Member

I guess this is because regular variants are in both namespaces and braced variants are a mistake. However, if we one day get named fields for functions, then I guess we could use struct names as ctor functions, so it might be useful. Too bad that ship has sailed for regular structs.

and a constant with the same name<sup>Note 1</sup>

```
const US: US = US{};

This comment has been minimized.

@nrc

nrc Apr 27, 2016

Member

c.f., an actual braced struct with zero fields, which is not in the value namespace

This comment has been minimized.

@durka

durka Apr 27, 2016

Contributor

I think that's the point. An empty struct-defined-with-without-braces is like an empty struct-defined-with-braces, plus a const like this.


Everything related to braced structs and unit structs is already implemented.

New: Permit tuple structs and tuple variants with 0 fields. This restriction is artificial and can

This comment has been minimized.

@nrc

nrc Apr 27, 2016

Member

Could you expand on the exact semantics here, I assume there is no interoperability between the different kinds of zero-sized structs. Whereas, a unit struct can be thought of as a single constant object, I would think of zero-field tuple structs generating a potentially infinite number of unique instances, but I can't think of how this makes an actual difference in code.

This comment has been minimized.

@durka

durka Apr 27, 2016

Contributor

a unit struct can be thought of as a single constant object, I would think of zero-field tuple structs generating a potentially infinite number of unique instances

Can you expand on your intuition here?

This comment has been minimized.

@petrochenkov

petrochenkov Apr 27, 2016

Author Contributor

struct TS(); is roughly equivalent to

struct TS {
}

 fn TS() -> TS {
     TS{}
 }

, it's described in the section about tuple structs above.

This also means that `S{..}` patterns can be used to match structures and variants of any kind.
The desire to have such "match everything" patterns is sometimes expressed given
that number of fields in structures and variants can change from zero to non-zero and back during
development.

This comment has been minimized.

@nrc

nrc Apr 27, 2016

Member

This is definitely desirable.

for braces structs (`ExprStruct`/`PatKind::Struct`), tuple structs
(`ExprCall`/`PatKind::TupleStruct`) and unit structs (`ExprPath`/`PatKind::Path`). With proposed
changes `#[derive]` could simplify its logic and always generate braced forms for expressions and
patterns.

This comment has been minimized.

@nrc

nrc Apr 27, 2016

Member

This makes me uncomfortable since it weakens the correspondence between the declaration, pattern, and creation syntaxes. And makes the bracing more fuzzy, where we've been trying to be stricter. Since the only motivation is in procedural macros, I wonder if there is a solution using clever libraries or tooling, rather than changing the language?

@petrochenkov

This comment has been minimized.

Copy link
Contributor Author

petrochenkov commented Jul 31, 2016

Implementation: rust-lang/rust#35138

@petrochenkov

This comment has been minimized.

Copy link
Contributor Author

petrochenkov commented Jul 31, 2016

Note that everything the implementation does (modulo tests and feature gates) is removing non-fatal errors and accepting a new grammar production in the parser, i.e. the RFC only legitimizes things that already work internally.

function calls, but the compiler reserves the right to make observable improvements to them based
on the additional knowledge, that `TS` is a constructor.

Note 1: the automatically assigned field names are quite interesting, they are not identifiers

This comment has been minimized.

@Mark-Simulacrum

Mark-Simulacrum Jul 31, 2016

Member

This note doesn't appear to be used in the above section.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Aug 8, 2016

Hear ye, hear ye! This RFC is now entering final comment period. In the most recent meeting, @nrc and I (the only two in attendance) both felt inclined to accept (though no final decision has been reached).

In general, the feeling is that this RFC is not needed in any strict sense, though enabling Foo { .. } as a generic "variant check" pattern is pretty useful. It does seem to generally move {} vs () into a more strict relationship, which seems useful, though potentially more confusing (perhaps a stricter separation is clearer?).

@vitiral

This comment has been minimized.

Copy link

vitiral commented Aug 11, 2016

I think making the model easier to understand and more consistent (and without breaking anything) is worth it in its own right. Making macros simpler is pretty awesome too.

The only worry is that there is some future feature that would need this syntax. On the other hand, this RFC makes a pretty clear case that such new syntax would be confusing and non intuitive.

I'm 👍

@vitiral

This comment has been minimized.

Copy link

vitiral commented Aug 11, 2016

Also, making TupleStruct just shorthand for NamedStruct but with numeric names makes a lot of sense imo. Not having to do NS(_, _, c, _) is nice as well.

@vitiral

This comment has been minimized.

Copy link

vitiral commented Aug 11, 2016

I'm not sure I totally understand the "pattern matching a function" definition though. You can't pattern match to a function, so it is really confusing. I would change that description to something more accurate with how things actually work

@ubsan

This comment has been minimized.

Copy link
Contributor

ubsan commented Aug 11, 2016

I think this is a great change. I agree it's not necessary, but it also seems "good", without much, if any, downside.

@nrc nrc removed the I-nominated label Aug 11, 2016

@aturon

This comment has been minimized.

Copy link
Member

aturon commented Aug 11, 2016

I'm very much in favor as well. This is exactly the mental model I want, and I'd love to get rid of the various pedantic restrictions we have today.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Aug 12, 2016

Huzzah! The @rust-lang/lang team has decided to accept this RFC.

@nikomatsakis nikomatsakis referenced this pull request Aug 12, 2016

Closed

Tracking issue for "clarified ADT kinds" (RFC 1506) #35626

2 of 2 tasks complete
@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Aug 12, 2016

Tracking issue: rust-lang/rust#35626

If you'd like to keep following the development of this feature, please subscribe to that issue, thanks! :)

@nikomatsakis nikomatsakis merged commit 433edd9 into rust-lang:master Aug 12, 2016

@petrochenkov petrochenkov deleted the petrochenkov:adtkinds branch Sep 21, 2016

@farodin91 farodin91 referenced this pull request Jul 21, 2017

Closed

Support rust 1.19 #1491

5 of 5 tasks complete

@debris debris referenced this pull request Jul 24, 2017

Merged

rlp_derive #6125

@Frederik-Baetens

This comment has been minimized.

Copy link

Frederik-Baetens commented Dec 27, 2018

Hello, sorry to bother you with this, but the rendered proposal link is broken, I think it should be:

https://github.com/rust-lang/rfcs/blob/master/text/1506-adt-kinds.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.