Skip to content

Commit 7a2ce51

Browse files
authored
Merge pull request #2421 from Centril/rfc/unreservations-2018
RFC: Keyword unreservations (pure, sizeof, alignof, offsetof)
2 parents e518d9d + 17bc1e7 commit 7a2ce51

File tree

1 file changed

+311
-0
lines changed

1 file changed

+311
-0
lines changed

text/2421-unreservations-2018.md

Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
- Feature Name: `unreservations`
2+
- Start Date: 2018-04-26
3+
- RFC PR: [rust-lang/rfcs#2421](https://github.com/rust-lang/rfcs/pull/2421)
4+
- Rust Issue: [rust-lang/rust#51115](https://github.com/rust-lang/rust/issues/51115)
5+
6+
# Summary
7+
[summary]: #summary
8+
9+
We unreserve:
10+
+ `pure`
11+
+ `sizeof`
12+
+ `alignof`
13+
+ `offsetof`
14+
15+
# Motivation
16+
[motivation]: #motivation
17+
18+
We are currently not using any of the reserved keywords listed in the [summary]
19+
for anything in the language at the moment. We also have no intention of using
20+
the keywords for anything in the future, and as such, we want to unreserve them
21+
so that rustaceans can use them as identifiers.
22+
23+
# Guide-level explanation
24+
[guide-level-explanation]: #guide-level-explanation
25+
26+
See the [reference-level-explanation].
27+
28+
# Reference-level explanation
29+
[reference-level-explanation]: #reference-level-explanation
30+
31+
[list of reserved keywords]: https://doc.rust-lang.org/book/second-edition/appendix-01-keywords.html#keywords-currently-in-use
32+
33+
The keywords listed below are removed from the
34+
[list of reserved keywords] and are longer reserved such that they can be
35+
used as general identifiers. This is done immediately and on edition 2015.
36+
37+
The keywords to unreserve are:
38+
+ `pure`
39+
+ `sizeof`
40+
+ `alignof`
41+
+ `offsetof`
42+
43+
# Drawbacks
44+
[drawbacks]: #drawbacks
45+
46+
The only drawback is that we're not able to use each listed word as a keyword
47+
in the future, without a reservation in a new edition, if we realize that we
48+
made a mistake.
49+
50+
See the rationale for potential risks with each keyword.
51+
52+
# Rationale and alternatives
53+
[alternatives]: #alternatives
54+
55+
There's only one alternative: Not unreserving all listed / some keywords.
56+
57+
Not unreserving a keyword would make the word unavailable for use as an
58+
identifier.
59+
60+
## General policy around unreservations
61+
62+
This RFC establishes a general rationale and policy for keyword unreservation:
63+
*If we are not using a keyword for anything in the language, and we are sure
64+
that we have no intention of using the keyword in the future, then it is
65+
permissible to unreserve a keyword and it is motivated.
66+
Additionally, if there is a desire for a keyword to be used as an identifier,
67+
this can in some cases outweigh very hypothetical and speculative language features.*
68+
69+
## Rationale for `pure`
70+
71+
This keyword used to be used for `pure fn`, that is: as an effect.
72+
73+
[applicative]: http://hackage.haskell.org/package/base-4.11.1.0/docs/Control-Applicative.html#t:Applicative
74+
75+
When *generic associated types* (GATs) lands, it is likely that people would
76+
like to use this in their [applicative functor][applicative] and monad libraries,
77+
which speaks in favour of unreserving `pure`. This use case explicitly mentioned by [`@ubsan`](https://github.com/ubsan/) who requested that the keyword be unreserved for this purpose.
78+
79+
### Potential drawbacks
80+
81+
Examples / The reasons why we might want to keep `pure` reserved are:
82+
83+
#### 1. Effects
84+
85+
```rust
86+
pure fn foo(x: Type) -> Type {
87+
...
88+
}
89+
```
90+
91+
Here, `pure` denotes a deterministic function -- but we already have `const`
92+
for more or less the same, and it is unlikely that we would introduce an effect
93+
(or restriction thereof) that is essentially `const fn` but not entirely.
94+
So this use case is unlikely to happen.
95+
96+
#### 2. Explicit *`Ok`-wrapping*
97+
98+
```rust
99+
fn foo() -> Result<i32, Error> {
100+
if bar() {
101+
pure 0;
102+
}
103+
...
104+
}
105+
```
106+
107+
desugars into:
108+
109+
```rust
110+
fn foo() -> Result<i32, Error> {
111+
if bar() {
112+
return Try::from_ok(0);
113+
}
114+
...
115+
}
116+
```
117+
118+
[Applicative laws]: https://en.wikibooks.org/wiki/Haskell/Applicative_functors#Applicative_functor_laws
119+
120+
While you might think that Haskell developers would be in favour of this,
121+
that does not seem to be the case. Haskell developers over at
122+
`#haskell @ freenode` were not particularly in favour of this use as `pure`
123+
in this context as `pure` does not respect the [Applicative laws].
124+
The desugaring is also not particularly obvious when `pure` is used.
125+
If we did add sugar for explicit `Ok`-wrapping, we'd probably go with something
126+
other than `pure`.
127+
128+
#### Summary
129+
130+
In both 1. and 2., `pure` can be contextual.
131+
We also don't think that the drawbacks are significant for `pure`.
132+
133+
## Rationale for `sizeof`, `alignof`, and `offsetof`
134+
135+
We already have [`std::mem::size_of`](https://doc.rust-lang.org/nightly/std/mem/fn.size_of.html) and similar which
136+
are `const fn`s or can be. In the case of `offsetof`, we would instead use
137+
a macro `offset_of!`.
138+
139+
A reason why we might want to keep these reserved is that they already exist in
140+
the standard library, and so we might not want anyone to define these functions,
141+
not because we will use them ourselves, but because it would be confusing,
142+
and so the error messages could be improved saying
143+
*"go look at `std::mem::size_of` instead"*. However, we believe it is better
144+
to allow users the freedom to use these keywords instead.
145+
146+
# Prior art
147+
[prior-art]: #prior-art
148+
149+
Not applicable.
150+
151+
# Unresolved questions
152+
[unresolved]: #unresolved-questions
153+
154+
There are none.
155+
All reservations we will do should be resolved before merging the RFC.
156+
157+
# Appendix
158+
[appendix]: #appendix
159+
160+
## Reserved keywords we probably don't want to unreserve
161+
162+
The following keywords are used in the nightly compiler and we are sure
163+
that we want to keep them:
164+
165+
- `yield` - Generators
166+
- `macro` - Macros 2.0
167+
168+
Additionally, there are known potential use cases / RFCs for:
169+
170+
- `become` - We might want this for guaranteed tail calls.
171+
See [the postponed RFC](https://github.com/rust-lang/rfcs/pull/1888).
172+
173+
- `typeof` - We might want this for hypothetical usages such as:
174+
```rust
175+
fn foo(x: impl Bar, y: typeof(x)) { .. }
176+
```
177+
178+
- `do` - We might want this for two uses:
179+
1. `do { .. } while cond;` loops.
180+
2. Haskell style do notation: `let az' = do { x <- ax; y <- ay(x); az };`.
181+
182+
- `abstract` - We might/would like this for:
183+
```rust
184+
abstract type Foo: Copy + Debug + .. ;
185+
```
186+
187+
- `override` - This could possibly used for:
188+
+ OOP inheritance -- unlikely that we'll get such features.
189+
190+
+ specialization -- we do not annotate specialization on the overriding impl
191+
but rather say that the base impl is specializable with `default`,
192+
wherefore `override` does not make much sense.
193+
194+
+ delegation -- this usage was proposed in the delegations pre-RFC:
195+
196+
```rust
197+
impl TR for S {
198+
delegate * to f;
199+
200+
#[override(from="f")]
201+
fn foo(&self) -> u32 {
202+
42
203+
}
204+
}
205+
```
206+
207+
which we could rewrite as:
208+
209+
```rust
210+
impl TR for S {
211+
delegate * to f;
212+
213+
override(from f) fn foo(&self) -> u32 {
214+
42
215+
}
216+
}
217+
```
218+
219+
## Possible future unreservations
220+
221+
### `unsized`
222+
223+
This would be a modifier on types, but we already have `<T: ?Sized>` and we
224+
could have `T: !Sized` so there seems to be no need for keeping `unsized`.
225+
226+
However, `unsized type` or `unsized struct` might be a desirable syntax for
227+
declaring a *dynamically sized type (DST)* or completely unsized type.
228+
Therefore, we will hold off on unreserving `unsized` until we have a better
229+
ideas of how custom DSTs will work and it's clear we don't need `unsized`
230+
as a keyword.
231+
232+
### `priv`
233+
234+
Here, `priv` is a privacy / visibility modifier on things like fields, and items.
235+
An example:
236+
237+
```rust
238+
priv struct Foo;
239+
pub struct Bar {
240+
priv baz: u8
241+
}
242+
```
243+
244+
Since fields are already private by default, `priv` would only be an extra
245+
hint that users can use to be more explicit, but serves no other purpose.
246+
Note however that `enum` variants are not private by default.
247+
Neither are items in `trait`s. Annotating items as `priv` in traits could
248+
potentially be useful for internal `fn`s used in provided `fn` implementations.
249+
However, we could possibly use `pub(self)` instead of `priv`.
250+
251+
252+
Permitting `priv` could also be confusing for readers. Consider for example:
253+
254+
```rust
255+
pub struct Foo {
256+
priv bar: T,
257+
baz: U,
258+
}
259+
```
260+
261+
An unsuspecting reader can get the impression that `bar` is private but `baz`
262+
is public. We could of course lint against this mixing, but it does not seem
263+
worth the complexity.
264+
265+
However, right now (2018-04-26), there is a lot of movement around the module
266+
system. So we would like to wait and discuss unreserving this keyword at some
267+
later time.
268+
269+
### `box`
270+
271+
We use this in nightly for box patterns.
272+
We might want to unreserve this eventually however.
273+
274+
### `virtual`
275+
276+
This annotation would be for something like virtual functions (see `dyn`).
277+
However, we already have `dyn`, so why would we need `virtual`?
278+
Assuming the following makes sense semantically (which we do not care about here),
279+
we could easily write:
280+
281+
```rust
282+
dyn fn foo(..) -> whatever { .. }
283+
```
284+
285+
instead of:
286+
287+
```rust
288+
virtual fn foo(..) -> whatever { .. }
289+
```
290+
291+
However, there might be some use case related to specialization.
292+
After specialization is stable, we would like to revisit unreservation of
293+
`virtual`.
294+
295+
### `final`
296+
297+
The `final` keyword is currently reserved. It is used in Java to mean two
298+
separate things:
299+
1. "you can't extend (inheritance) this `class`",
300+
2. "you can't mutate this variable",
301+
which we already have for `let` bindings by default.
302+
303+
A possible use for `final` for us might be for [`Frozen` ](https://internals.rust-lang.org/t/forever-immutable-owned-values/6807).
304+
However, `Frozen` does not have many known uses other than for users who want
305+
to be more strict about things. The word `final` might not be what Java users
306+
would expect it to mean in this context, so it's probably not a good keyword
307+
for `Frozen`.
308+
309+
However, there might be some use case related to specialization.
310+
After specialization is stable, we would like to revisit unreservation of
311+
`final`.

0 commit comments

Comments
 (0)