owned this note
owned this note
Published
Linked with GitHub
# Edition 2018 Planning: Keywords Reservations
## Full list of reserved keywords
See https://doc.rust-lang.org/book/second-edition/appendix-01-keywords.html#keywords-currently-in-use
## Full list of keywords to consider
### Matching
+ `ìs` -- pattern matching as an expression `<expr> is <pat>`
+ `when` -- corresponds to `match` but instead for conditions
+ `with` -- dependent pattern matching?
+ `guard` -- `let .. else`
### Errors
+ `throw`, synonyms: `fail`, `raise`
+ `pass`, synonyms: `wrap`, `pure`, `ok`
+ `except`
+ `throws` -- `T throws E` return types
+ `finally` -- finally in Java
+ `try` / `catch` -- `try { .. }` -- RFC: https://github.com/rust-lang/rfcs/pull/2388
### Data types
+ `union` -- `union` types in Rust, currently contextual
+ `data` -- fusion of `enum` and `struct`
+ `class` -- either type classes in Haskell or OOP classes
### Effects - Polymorphism
+ `effect`, synonyms: `eff`, `context`, `capability`
+ `handler` -- effect handlers (Idris)
### Effects - Particular effects
+ `impure` -- the impurity effect, same as `!const`
+ `panic` -- the panic effect
+ `total` -- the totality effect
+ `trusted` -- the trusted effect (think `unsafe trait`)
#### Effects - Async
+ `async` -- the `async fn` effect
+ `await` -- `await!(foo)`
### Privacy
+ `friend` -- the C++ visibility modifier
### Traits / Inheritance
+ `dyn` -- for dynamic trait types `Box<dyn Trait>`
+ `meta` -- meta traits
+ `extends` -- extending traits or inheritance
+ `instance` -- synonym for trait `impl`s
### General Type system
+ `lifetime` -- associated lifetimes?
+ `exists`, `existential` -- existential quantification / types
+ `out` -- out references
+ `in` -- in references
+ `uninit` -- uninitialized references
+ `empty` -- empty references
+ `take` -- take references
+ `place` -- place references
### Misc
+ `from` -- desugars to `From::from`
+ `auto` -- inferred type
+ `operator` -- operator overloading in C++
+ `volatile` -- see `ptr::volatile_read`, etc.
+ `def` -- instead of `fn` or `let` bindings
+ `derive`, `deriving` -- instead of `#[derive(..)]`
### Logic
+ `and` -- synonym of `&&`
+ `or` -- synonym of `||`
+ `not` -- synonym of `!`
## Indepth review
### `throw` / `fail` / `raise` *[FIXME: reserve one of these?]*
- **Drawbacks:** To some, a drawback here is that this puts us firmly within the category of languages which talk about exceptions. To others, this is good. And then there's the usual drawbacks of reservations wrt. breakage.
- **Used in std:**
- `throw`: *No*
- `fail`: *No*
- `raise`: *No*
- **Used as crate?**
- `throw`: *Yes*, no rev deps
- `fail`: *Yes*, some rev deps -- whole tree belongs to same user
- `raise`: *No*
- **Risk of breakage:**
- `throw`: *Low*, `neon` is the only crate ([sourcegraph](https://sourcegraph.com/search?q=repogroup:crates+case:yes++%5Cb%28%28let%7Cconst%7Ctype%7C%29%5Cs%2Bwhen%5Cs%2B%3D%7C%28fn%7Cimpl%7Cmod%7Cstruct%7Cenum%7Cunion%7Ctrait%29%5Cs%2Bwhen%29%5Cb+max:400))
- `fail`: *Middle*, this breaks `peresil`, `tokio-rustls`, `eventual`, `libz-sys`, `gcc-rs`, `curl-rust`, `cmake-rs`, `cc-rs`, `meta`, `combine`, `audio-video-metadata` but these are mostly tests ([sourcegraph](https://sourcegraph.com/search?q=repogroup:crates+case:yes++\b((let|const|type|)\s%2Bfail\s%2B%3D|(fn|impl|mod|struct|enum|union|trait)\s%2Bfail)\b+max:400))
- `raise`: *High*, this breaks `rust-sdl2`, `ruru`, `gdk`, `nix`, `libc` (libc is problematic!) ([sourcegraph](https://sourcegraph.com/search?q=repogroup:crates+case:yes++\b((let|const|type|)\s%2Braise\s%2B%3D|(fn|impl|mod|struct|enum|union|trait)\s%2Braise)\b+max:400))
- **Can be contextual?** *yes, probably*
- **Can be done in a macro?** *yes*, `throw/fail/raise!(expr);`
#### Review
The `throw` / `fail` / `raise` expressions would be used as:
```rust
if cond {
fail foo;
}
```
which would be essentially be sugar for:
```rust
if cond {
return Try::from_err(From::from(foo));
}
```
or more strictly speaking (to work with `try { .. }`):
```rust
if cond {
Try::from_err(foo)?;
}
```
The fact that this can easily be a macro defined as:
```rust
macro_rules! raise {
($error: expr) => {
Try::from_err($error)?
}
}
```
should be considered a drawback. However, the expression `throw foo` is more ergonomic than `throw!(foo)` due to the lack of parenthesis in the former.
The `fail` version has seemingly been more popular in discussions (and is used in Haskell, see `MonadFail`), but `throw` is commonly used in popular languages that do have `try { .. } catch { .. }`
#### Discussion
- nmatsakis: pretty strong +1 to this one. This was popular in the thread and there is a clear need.
- scottmcm: does `Try::from_err($error)?` infer enough things? Feels like the Ok type in a result is unconstrained, for example. And I'm not convinced that error-conversion (in the `?`) is valuable for this.
- scottmcm: maybe `bail`, like `failure::bail!`
### `is` *[won't reserve]*
- **Drawbacks:** Inverted matching order, unclear if we want general bool-valued pattern matching, will break some code most notably in libstd.
- **Used in std:** *Yes*, `Any::is`, `Error::is`
- **Used as crate?** *No*
- **Risk of breakage:** High, especially wrt. libstd. This will also break notable traits such as `hamcrest`, `nalgebra`, `ndarray`, `glib`, `rocket` [rocket is unstable] ([sourcegraph](https://sourcegraph.com/search?q=repogroup:crates+case:yes++%5Cb%28%28let%7Cconst%7Ctype%7C%29%5Cs%2Bis%5Cs%2B%3D%7C%28fn%29%5Cs%2Bis%29%5Cb+max:400))
- **Can be contextual?** *Yes, probably*
- **Can be done in a macro?** *No*
#### Review
See: https://github.com/rust-lang/rfcs/pull/2260#issuecomment-353780537 for the usage.
The `is` keyword would be called the `is` operator and used as follows:
```rust
let matched: bool = EXPR is PAT;
if EXPR is PAT &&
EXPR is PAT ||
EXPR is PAT {
EXPR
}
```
where `EXPR`s are expressions and `PAT` are patterns.
This `EXPR is PAT` form is the inverted order of `let PAT = EXPR`, which we use in other places, so the form could be considered inconsistent with what we already have (even if `if let PAT = EXPR` is considered bad). We could also possibly reuse `match` as `EXPR match PAT`.
The benefit of `EXPR is PAT` would be that it reads really well (for fluent English speakers and in many other IE languages).
Petrochenkov has written a PoC implementation and discussed it here: https://github.com/rust-lang/rfcs/pull/2260#issuecomment-367158854
From their comment it did not seem like they actually needed a keyword which is backed up by: https://github.com/petrochenkov/rust/blob/6349f22c0438f03da7f1efd7a1d112bfa0e25f22/src/libsyntax_pos/symbol.rs#L329
#### Discussion
- nmatsakis: I wonder to what extent this could be added as contextual keyword; "juxtaposed" identifiers usually work out ok, except for `::foo` paths (which I think will be deprecated in Rust 2018 anyway)
- centril: yes, i think it could be contextual.
### `when` *[won't reserve]*
- **Drawbacks:** FIXME
- **Used in std:** *No*
- **Used as crate?** *No*
- **Risk of breakage:** *Very low* ([sourcegraph](https://sourcegraph.com/search?q=repogroup:crates+case:yes++%5Cb%28%28let%7Cconst%7Ctype%7C%29%5Cs%2Bwhen%5Cs%2B%3D%7C%28fn%7Cimpl%7Cmod%7Cstruct%7Cenum%7Cunion%7Ctrait%29%5Cs%2Bwhen%29%5Cb+max:400) - only one real breakage there)
- **Can be contextual?** No
- **Can be done in a macro?** *probably?*
#### Review
See: https://github.com/rust-lang/rfcs/pull/2260#issuecomment-353795943
This would give us multi-way `if`s as in:
```rust
let name = meta.name();
when {
set.is_some() =>
error::set_again(name),
meta is &NameValue(_, Lit::Int(val, ty)) &&
val <= u32::MAX as u64 &&
is_unsigned(ty) =>
*set = Some(val as u32),
else =>
error::weight_malformed(name),
}
```
It is not clear whether this adds significant value to what we already have (`match`, `if else `) and whether this is a problem that needs solving. We should also be wary of too much proliferation in control flow features in the language even if the meaning of `when` in this context is intuitive.
#### Discussion
### `with` *[won't reserve]*
- **Drawbacks:** Unclear usage
- **Used in std:** *Yes*, `LocalKey::with`
- **Used as crate?** *Yes*, but *"This is a dummy package that will never have any content."*
- **Risk of breakage:** High due to std breakage, ([sourcegraph](https://sourcegraph.com/search?q=repogroup:crates+case:yes++%5Cb%28%28let%7Cconst%7Ctype%7C%29%5Cs%2Bwith%5Cs%2B%3D%7C%28fn%7Cimpl%7Cmod%7Cstruct%7Cenum%7Cunion%7Ctrait%29%5Cs%2Bwith%29%5Cb+max:400)
- **Can be contextual?** *Yes, probably*
- **Can be done in a macro?** *No?*
#### Review
It could be used for some sort of dependent pattern matching or `with` bounds as in: https://github.com/ticki/rfcs/blob/pi-types-ext-1/text/0000-with-bounds-in-pi-types.md but `where` could probably be used for that, and it would most likely work as a contextual keyword.
Furthermore, the name is common and it would break a method in libstd.
In summary there is not a lot of motivation for a reservation here.
#### Discussion
- nmatsakis: For what? This is a pretty common method name. (Update: [used 24 times in crates.io](https://sourcegraph.com/search?q=repogroup:crates+max:200+%5Cbfn%5Cs%2Bwith%5Cb))
- centril: oh neat, ill use that thing for the other proposed keywords ;)
- centril: isn't `_with` the usual idiom? i.e: not just `with`?
- centril: this was proposed in RFC 2260 iirc by @matklad
- nmatsakis: can you link?
- centril: https://github.com/rust-lang/rfcs/pull/2260
- centril: ill find the specific place, sec.
- centril: oh no, sorry, this was `when`, not `with`
- centril: https://github.com/rust-lang/rfcs/pull/2260#issuecomment-353795943
- nmatsakis: and I suppose yes it is usually `with_foo`...
### `guard` *[won't reserve]*
- **Drawbacks:** FIXME
- **Used in std:** *No*
- **Used as crate?** *Yes* -- but the crate does exactly what the lang feature would do...
- **Risk of breakage:** High, this breaks public APIs of `rocket` and `scopeguard` ([sourcegraph](https://sourcegraph.com/search?q=repogroup:crates+case:yes++%5Cb%28%28let%7Cconst%7Ctype%7C%29%5Cs%2Bguard%5Cs%2B%3D%7C%28fn%7Cimpl%7Cmod%7Cstruct%7Cenum%7Cunion%7Ctrait%29%5Cs%2Bguard%29%5Cb+max:400))
- **Can be contextual?** FIXME
- **Can be done in a macro?** *FIXME*
#### Review
FIXME
#### Discussion
- nmatsakis: I am pretty strongly opposed to adding a `guard` keyword for this purpose. I would not be inclined to reserve it.
- centril: particular reasons I can use as rationale?
- nmatsakis: the use case is too obscure to merit a new keyword; the meaning of guard is not especially obvious, and in fact the precedent is different. e.g., in D there is a special syntax for the equivalent of `let _x = foo` -- a dtor that runs for side-effects. Given that we call those "guards" I would expect `guard` to have something to do with that. (D uses `scope` for that though, but it calls them "scope guards")
- centril: roger! (and agree personally)
- centril: I also unlike the non-generality of `guard`...
- nmatsakis: yep, and anyway `else` just feels so right for this =)
- centril: +1 -- do notation please :P
- joshtriplett: Too many other usages to reserve, let's not
### `pass` / `wrap` / `pure` / `ok` *[FIXME]*
- **Drawbacks:** FIXME
- **Used in std:**
- `pass`: *No*
- `wrap`: *No*
- `pure`: *Reserved!*
- `ok`: *Yes*, `Result::ok`
- **Used as crate?**
- `pass`: *Yes*, no rev deps
- `wrap`: *Yes*, no rev deps
- `pure`: *Reserved!*
- `ok`: *No*
- **Risk of breakage:**
- `pass`: *Low*, breaks public APIs of `gfx-rs` (notable trait, but only one breakage), `rust-mysql-simple` ([sourcegraph](https://sourcegraph.com/search?q=repogroup:crates+case:yes++%5Cb%28%28let%7Cconst%7Ctype%7C%29%5Cs%2Bpass%5Cs%2B%3D%7C%28fn%7Cimpl%7Cmod%7Cstruct%7Cenum%7Cunion%7Ctrait%29%5Cs%2Bpass%29%5Cb+max:400))
- `wrap`: *Middle*, breaks some public APIs ([sourcegraph](https://sourcegraph.com/search?q=repogroup:crates+case:yes++%5Cb%28%28let%7Cconst%7Ctype%7C%29%5Cs%2Bwrap%5Cs%2B%3D%7C%28fn%7Cimpl%7Cmod%7Cstruct%7Cenum%7Cunion%7Ctrait%29%5Cs%2Bwrap%29%5Cb+max:400))
- `pure`: *Reserved!*
- `ok`: *High*, due to central std breakage (and some public APIs, [sourcegraph](https://sourcegraph.com/search?q=repogroup:crates+case:yes++\b((let|const|type|)\s%2Bok\s%2B%3D|(fn|impl|mod|struct|enum|union|trait)\s%2Bwrap)\b+max:400))
- **Can be contextual?** This would conflict with `<keyword> { .. }` expressions, so probably not?
- **Can be done in a macro?** *Yes*
#### Review
FIXME: argument by symmetry.
#### Discussion
- nmatsakis: I don't think that this merits a keyword -- the purpose was to change `Ok(22)` to `pass 22`, I don't think it achieves any of the goals we were going for with ok-wrapping (which is to make it feel unintrusive). Sort of a compromise satisfying nobody sort of thing.
- scottmcm: +1
- centril: can also most likely be contextual or a macro.
### `except` *[won't reserve]*
- **Drawbacks:** Unknown use cases
- **Used in std:** *No*
- **Used as crate?** *No*
- **Risk of breakage:** *Very low* ([sourcegraph](https://sourcegraph.com/search?q=repogroup:crates+case:yes++\b((let|const|type|)\s%2Bok\s%2B%3D|(fn|impl|mod|struct|enum|union|trait)\s%2Bwrap)\b+max:400))
- **Can be contextual?** *unknown*
- **Can be done in a macro?** *unknown*
#### Review
We currently don't know what this would be used for. Speculative reservations should at minimum have some good use case in mind, for this reason alone, we should not reserve this keyword.
#### Discussion
- nmatsakis: what is this for?
- centril: no idea... the person who proposed it didn't explain :P
### `throws` *[won't reserve]*
- **Drawbacks:** FIXME
- **Used in std:** *No*
- **Used as crate?** *Yes*, no rev deps
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** *Yes, but probably not ergonomically*
#### Review
#### Discussion
- nmatsakis: I wouldn't be inclined to add this. I don't think that particular formulation was very popular, and I would personally prefer to stick with writing `Result<T, E>` types out in full (so that you can also write `Option<T>`)
- centril: agreed +10000
### `finally` *[won't reserve]*
- **Drawbacks:** FIXME
- **Used in std:** *No*
- **Used as crate?** *Yes*, but the lang feature would supercede the crate. The crate requires nightly.
- **Risk of breakage:** FIXME
- **Can be contextual?** No.
- **Can be done in a macro?** *Probably?*
#### Review
This would mostly be used as `try { .. } catch { .. } finally { .. }` where it does not need to be keyword, but `finally { .. }` alone must be a keyword, but we already have destructors...
#### Discussion
- nmatsakis: we have destructors -- I don't feel a strong need, but maybe others do?
### `try` / `catch` *[FIXME]*
See: https://github.com/rust-lang/rfcs/pull/2388
### `union` *[won't reserve]*
- **Drawbacks:** FIXME
- **Used in std:** *Yes*, `HashSet/BTreeSet::union`
- **Used as crate?** *No*
- **Risk of breakage:** FIXME
- **Can be contextual?** It seems so.
- **Can be done in a macro?** *N/A*
#### Review
FIXME
#### Discussion
- nmatsakis: I am inclined to make this a true keyword to make struct and enum.
- centril: used in std as identifier.
- nmatsakis: we have raw identifiers. =) But maybe it's not worth it.
- centril: probably not imo... what's the gain from making it non-contextual? (ill read the RFC and check...)
- nmatsakis: I can't think of any really. Maybe we can make struct and enum contextual instead. =)
- centril: yeah
- nmatsakis: though I feel like I thought of something
### `data` *[won't reserve]*
- **Drawbacks:** FIXME
- **Used in std:** *No* (unstable: `TraitObject.data` field)
- **Used as crate?** *No*
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** *FIXME*
#### Review
#### Discussion
- nmatsakis: not inclined personally =) I disagree this was a mistake. :P
- centril: Personally I think this is one of the Rust 1.0 mistakes; we should have just had `data` -- but adding `data` now in any case is just making things more complicated instead of less. So we should live with this.
### `class` *[won't reserve]*
- **Drawbacks:** FIXME
- **Used in std:** *No*
- **Used as crate?** *No*
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** *FIXME*
#### Review
#### Discussion
- nmatsakis: not gonna happen. I personally would love to model OOP better! But I don't think we're going to do it via a class keyword for a variety of reasons.
- centril: Personally, I'm not a huge fan of OOP; and entirely agree with not reserving `class`.
### `effect` / `eff` / `capability` / *[FIXME]*
- **Drawbacks:** FIXME
- **Used in std:** *FIXME*
- `effect`: No
- `eff`: No
- `capability`: No
- **Used as crate?** *FIXME*
- `effect`: No
- `eff`: No
- `capability`: No
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** *FIXME*
#### Review
#### Discussion
- nmatsakis: I don't think we're anywhere close to a proposal here, and in any case I'd be skeptical of adding a lot of syntax (vs, say, attributes).
- centril: yep; and could probably be contextual because it would only be used for explicit quantification.
### `handler` *[FIXME]*
- **Drawbacks:** FIXME
- **Used in std:** *No*
- **Used as crate?** *No*
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** *FIXME*
#### Review
#### Discussion
- nmatsakis: see `effect` above. =)
### `impure` / `unconst` *[won't reserve]*
- **Drawbacks:** FIXME
- **Used in std:** *FIXME*
- `impure`: No
- `unconst`: No
- **Used as crate?** *FIXME*
- `impure`: No
- `unconst`: No
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** *FIXME*
#### Review
#### Discussion
- nmatsakis: see `effect` above. =)
- centril: just use `!const`...
### `total` *[FIXME]*
- **Drawbacks:** FIXME
- **Used in std:** *No*
- **Used as crate?** *No*
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** *FIXME*
#### Review
#### Discussion
- nmatsakis: see `effect` above. =)
### `panic` *[FIXME]*
- **Drawbacks:** FIXME
- **Used in std:** *Yes*, mod `std::panic`, macro `panic!`, unstable: `core::pankicking::panic`
- **Used as crate?** *No*, version 0.0.0 and no rev deps
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** *FIXME*
#### Review
#### Discussion
- nmatsakis: see `effect` above. =)
### `trusted` *[FIXME]*
- **Drawbacks:** FIXME
- **Used in std:** *No*
- **Used as crate?** *No*
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** *FIXME*
#### Review
+ `trusted` -- the trusted effect (think `unsafe trait`)
#### Discussion
- nmatsakis: this won't happen for Rust 2018, but I do think we may want to revamp how we declare unsafe code at some point. but we don't know what it should look like so I'm not inclined to just reserve random words until then. =)
- centril: speculatively reserve?
- nmatsakis: I guess it's a judgement call. `trusted` is not really *random*, it's sort of the obvious replacement. Still, I'm not sure.
### `async` *[FIXME]*
- **Drawbacks:** FIXME
- **Used in std:** *No*
- **Used as crate?** *Yes*, version 0.0.2 and seemingly no docs / repo, no rev deps
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** *FIXME*
#### Review
#### Discussion
- nmatsakis: this is looking pretty likely to me =)
- centril: I kinda dislike the non-generality of `async` as a non-effect and not doing it via do notation, but... you could generalize later.
### `await` *[FIXME]*
- **Drawbacks:** FIXME
- **Used in std:** *No*
- **Used as crate?** *Yes*, version 0.0.0 -- experimental / proposal-crate
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** *FIXME*
#### Review
#### Discussion
- nmatsakis: this is looking pretty likely to me =)
- centril: I kinda dislike the non-generality of `async` as a non-effect and not doing it via do notation, but... you could generalize later.
### `friend` *[won't reserve]*
- **Drawbacks:** FIXME
- **Used in std:** *No*
- **Used as crate?** *No*
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** *FIXME*
#### Review
#### Discussion
- nmatsakis: if anything, I expect our visibility system to be moving in the direction of **simpler** -- i.e., private vs pub vs crate. Not adding more knobs.
### `dyn` *[FIXME]*
- **Drawbacks:** FIXME
- **Used in std:** *No*
- **Used as crate?** *No*
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** *FIXME*
#### Review
#### Discussion
- nmatsakis: we could make this a true keyword, but I'm not sure we *have* to -- I think the only case it matters is `dyn :: foo` and we expect to deprecate `::Foo` as a leading path, right? (Making their only one reasonable interpretation.) Seems like we should wait a bit and see what happens there? But I'm not opposed.
- rpjohnst: we may still need `::foo` to disambiguate, but it does look like it will be significantly less common even than it already is.
- centril: not sure where the module discussion landed... was to long a discussion ;)
### `meta` *[FIXME]*
- **Drawbacks:** FIXME
- **Used in std:** *No*
- **Used as crate?** *Yes*, no rev deps
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** *FIXME*
#### Review
#### Discussion
- nmatsakis: I don't know that we are close enough here -- I don't even know what a meta trait is :)
- centril: Yeah;
- centril: also probably contextual.
- centril: https://gist.github.com/withoutboats/8b0eb3012203244bcf3a4e1a4be8819c
### `extends` *[won't reserve]*
- **Drawbacks:** FIXME
- **Used in std:** *No* (note: `extend` without the s is used)
- **Used as crate?** *No*
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** *FIXME*
#### Review
#### Discussion
- nmatsakis: haven't seen much here? I don't consider this very likely
- centril: agree.
### `instance` *[won't reserve]*
- **Drawbacks:** FIXME
- **Used in std:** *No*
- **Used as crate?** *No*
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** *FIXME*
#### Review
#### Discussion
- nmatsakis: why?
- centril: idk, someone proposed it on the internals thread :P
### `lifetime` / `lt` *[FIXME]*
- **Drawbacks:** FIXME
- **Used in std:** *FIXME*
- `lifetime`: *No*
- `lt`: *Yes*, `PartialOrd::lt` ==> **massive** problem.
- **Used as crate?** *FIXME*
- `lifetime`: *No*
- `lt`: *No*
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** *FIXME*
#### Review
#### Discussion
- nmatsakis: is this not already reserved? oh well. In theory there is an accepted RFC for them =)
- centril: I was totally surprised, but it is not reserved.
- centril: yeah, the associated items RFC.
### `exist` / `exists` / `existential` *[FIXME]*
- **Drawbacks:** FIXME
- **Used in std:** *FIXME*
- `exist`: *No*,
- `exists`: *Yes*,
- `existential`: *No*
- **Used as crate?** *FIXME*
- `exist`: *No*,
- `exists`: *No*,
- `existential`: *No*
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** *FIXME*
#### Review
#### Discussion
- nmatsakis: I don't know what the use case is here. I mean I know what existential quant is =)
- centril: GADTs and stuff
- centril: use `for<T>` instead as in Haskell ?
### `out` *[won't reserve]*
- **Drawbacks:** FIXME
- **Used in std:** *No*
- **Used as crate?** *Yes*, but it seems unused and has no link to a repository.
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** No
#### Review
FIXME
#### Discussion
- nmatsakis: I'm not inclined to add a bevvy of new keywords in this area. If we did anything at all, it seems far off, and I'd hope we can do a more library-based approach like `Pin`.
### `uninit` *[won't reserve]*
See `out`.
- **Drawbacks:** FIXME
- **Used in std:** *Yes but __unstable__* (`core_intrinsics`)
- **Used as crate?** *No*
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** No
### `empty` *[won't reserve]*
See `out`.
- **Drawbacks:** The high amount of breakage does not seem worth it.
- **Used in std:** *Yes* (2 times: stable, 1 time: unstable)
- **Used as crate?** *Yes* -- but with no rev deps
- **Risk of breakage:** High
- **Can be contextual?** FIXME
- **Can be done in a macro?** No
### `take` *[won't reserve]*
See `out`.
- **Drawbacks:** The high amount of breakage does not seem worth it.
- **Used in std:** *Yes* (6 times)
- **Used as crate?** *Yes* -- a widely used crate, with many reverse dependency (transitive closure)
- **Risk of breakage:** High
- **Can be contextual?** FIXME
- **Can be done in a macro?** No
### `place` *[won't reserve]*
See `out`.
- **Drawbacks:** FIXME
- **Used in std:** *No*
- **Used as crate?** *No*
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** No
### `from` *[won't reserve]*
- **Drawbacks:** This is used in the `From` trait and would cause *massive* breakage!
- **Used in std:** *Yes*
- **Used as crate?** *Yes*, https://crates.io/crates/from -- which has 0 rev deps
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** Yes, but not with the same syntax.
#### Review
This would introduce the keyword `expr from type` which would desugar into `<type as From>::from(expr)`. Since making `from` a keyword this would break one of the most important keywords in the language, it is probably a bad idea. If we want to introduce `from` expressions, it should be done with a contextual keyword if possible. Even then, it might be better to just allow users to do `use From::from`, which is more general.
#### Discussion
- nmatsakis: I'd rather just support `use From::from`. The fact that we don't is a bug in my book.
- centril: I've been thinking of an RFC "free the associated functions" along exactly those lines.
### `auto` *[won't reserve]*
- **Drawbacks:** We already have no-action-needed type-inference and `let x : _ = .. ;`. Thus, we are in no need of `auto`.
- **Used in std:** *No*
- **Used as crate?** *Yes*, https://crates.io/crates/auto -- which has 0 rev deps
- **Risk of breakage:** FIXME
- **Can be contextual?** Probably *(?)*
- **Can be done in a macro?** Yes: `auto!()` or possibly `auto!`.
#### Review
Here, `auto` is used in C++ for "infer this type". In Rust, we can either just use a normal `let` binding with no typing judgement on the binding, or simply use `_` as the magic type "infer it". Thus, it is unlikely that we would introduce this particular keyword as there would be no gain.
#### Discussion
- nmatsakis: we've been using `_` for this...?
- centril: yep.
### `operator` *[won't reserve]*
- **Drawbacks:** We already have traits for operator overloading.
- **Used in std:** *No*
- **Used as crate?** *No*
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** Unlikely.
#### Review
In this case `operator` is used in C++ for operator overloading. Rust already uses traits such as `Add` to achieve the same effect.
We **might** want to allow custom operators (as in Haskell) at some point, but that is unlikely and highly speculative. In any case, we would probably not use `operator` for that purpose if we would do it. Therefore, there's little current incentive to reserve this.
#### Discussion
- nmatsakis: we've been using traits for this...?
- centril: yeah;
- centril: we **might** want to do custom operators a la Haskell? (probably not), but still then not that syntax..?
- nmatsakis: pretty speculative =)
### `volatile` *[won't reserve]*
- **Drawbacks:** We already have `let` or `fn` depending on context.
- **Used in std:** *No*
- **Used as crate?** *Yes*, with 2 reverse deps (no transitive rev deps)
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** FIXME
#### Review
See: `ptr::volatile_read` and friend(s).
#### Discussion
- nmatsakis: this would go on fields or something? I'm sort of inclined to keep the current "access-based" rules that we have and leverage a `Volatile<T>` type or something instead -- at worst it could be a lang item
### `def` *[won't reserve]*
- **Drawbacks:** We already have `let` or `fn` depending on context.
- **Used in std:** *No*
- **Used as crate?** *No*
- **Risk of breakage:** FIXME
- **Can be contextual?** FIXME
- **Can be done in a macro?** FIXME
#### Review
It is unclear what this keyword would do and it has not been proposed anywhere to centril's knowledge (which is a reason enough to not reserve this). It might mean `let` and it might mean `fn` -- but we already have those, so we wouldn't want to introduce redundancy for that.
#### Discussion
- nmatsakis: ...?
- centril: I'm also ??? on this.
### `derive` *[won't reserve]*
- **Drawbacks:** We already have `#[derive(..)]`.
- **Used in std:** *No*
- **Used as crate?** *Yes* (but it has zero reverse dependencies)
- **Risk of breakage:** Low -- it's a fairly specific name. FIXME: needs evidence
- **Can be contextual?** Yes.
- **Can be done in a macro?** Probably
#### Review
The reasoning is that for `deriving` with the exception of participles.
#### Discussion
- nmatsakis: we explicitly chose to use attributes, I prefer that
### `deriving` *[won't reserve]*
- **Drawbacks:** We already have `#[derive(..)]` and we decided not use participles before.
- **Used in std:** *No*
- **Used as crate?** *No*
- **Risk of breakage:** Low -- it's a fairly specific name.
- **Can be contextual?** Yes.
- **Can be done in a macro?** Probably
#### Review
[RFC 534]: https://github.com/rust-lang/rfcs/blob/master/text/0534-deriving2derive.md
In [RFC 534] we decided to move to `derive` instead of `deriving`, but even then, it was still an attribute.
Reasons for making this reserved is if we want to have the form:
```rust
struct Foo
deriving (Copy, Clony, ..);
```
The benefit of this would be that we wouldn't have to rely on attribute grammar. This grammar might not allow more general trait paths, including angle brackets and everything that can be inside of those. However, even then, `deriving` is contextual, and so it does not need to be a general keyword.
### `and`, `or`, `not` *[won't reserve]*
- **Drawbacks:** We already have `&&`, `||`, `!`.
- **Used in std?** *Yes*, all are used. Examples: [`and`], [`or`], [`not`]
- **Used as crate?** *Yes on `or`*. No on the others.
- **Risk of breakage:** High
- **Can be contextual?** Probably.
- **Can be done in a macro?** Most likely by desugaring to the existing forms.
[`not`]: https://doc.rust-lang.org/nightly/std/ops/trait.Not.html#tymethod.not
[`and`]: https://doc.rust-lang.org/nightly/std/option/enum.Option.html#method.and
[`or`]: https://doc.rust-lang.org/nightly/std/option/enum.Option.html#method.or
#### Review
Examples of usage:
```rust
let cond = p and not q or r;
// or with parens:
let cond = (p and (not q)) or r;
```
would today be written:
```rust
let cond = p && !q || r;
```
In favor of adding these keywords is that users of python might like it. However, [*The Zen of Python*](https://www.python.org/dev/peps/pep-0020/) also has the credo:
> There should be one-- and preferably only one --obvious way to do it.
Therefore, users of python may in fact not appreciate this addition.
The language is also made more complex by this but no expressivity or ergonomics gains are really made.
#### Discussion
- nmatsakis: +1 *(editor's note: on not reserving)*