Skip to content

Commit

Permalink
clarify interaction with elisions
Browse files Browse the repository at this point in the history
  • Loading branch information
llogiq committed May 24, 2016
1 parent 93b685e commit 2526483
Showing 1 changed file with 39 additions and 9 deletions.
48 changes: 39 additions & 9 deletions text/0000-static.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ causes substantial rightwards drift, which makes it hard to format the code
to be visually appealing.

For example, having a `'static` default for lifetimes would turn this:
```
```rust
static my_awesome_tables: &'static [&'static HashMap<Cow<'static, str>, u32>] = ..
```
into this:
```
```rust
static my_awesome_table: &[&HashMap<Cow<str>, u32>] = ..
```

Expand All @@ -34,13 +34,14 @@ elision for function signatures will work as it does now (see example below).

The same default that RFC #599 sets up for trait object is to be used for
statics and const declarations. In those declarations, the compiler will assume
`'static` when a lifetime is not explicitly given in both refs and generics.
`'static` when a lifetime is not explicitly given in all reference lifetimes,
including reference lifetimes obtained via generic substitution.

Note that this RFC does not forbid writing the lifetimes, it only sets a
default when no is given. Thus the change will not cause any breakage and is
thus backwards-compatible. It's also very unlikely that implementing this RFC
will restrict our design space for `static` and `const` definitions down the
road.
therefore backwards-compatible. It's also very unlikely that implementing this
RFC will restrict our design space for `static` and `const` definitions down
the road.

The `'static` default does *not* override lifetime elision in function
signatures, but work alongside it:
Expand All @@ -50,16 +51,40 @@ static foo: fn(&u32) -> &u32 = ...; // for<'a> fn(&'a u32) -> &'a u32
static bar: &Fn(&u32) -> &u32 = ...; // &'static for<'a> Fn(&'a u32) -> &'a u32
```

With generics, it will work as anywhere else. Notably, writing out the lifetime
With generics, it will work as anywhere else, also differentiating between
function lifetimes and reference lifetimes. Notably, writing out the lifetime
is still possible.

```
trait SomeObject<'a> { ... }
```rust
trait SomeObject<'a> { .. }
static foo: &SomeObject = ...; // &'static SomeObject<'static>
static bar: &for<'a> SomeObject<'a> = ...; // &'static for<'a> SomeObject<'a>
static baz: &'static [u8] = ...;

struct SomeStruct<'a, 'b> {
foo: &'a Foo,
bar: &'a Bar,
f: for<'b> Fn(&'b Foo) -> &'b Bar
}

static blub: &SomeStruct = ...; // &'static SomeStruct<'static, 'b> for any 'b
```

It will still be an error to omit lifetimes in function types *not* eligible
for elision, e.g.

```rust
static blobb: FnMut(&Foo, &Bar) -> &Baz = ...; //~ ERROR: missing lifetimes for
//^ &Foo, &Bar, &Baz
```

This ensures that the really hairy cases that need the full type documented
aren't unduly abbreviated.

It should also be noted that since statics and constants have no `self` type,
elision will only work with distinct input lifetimes or one input+output
lifetime.

# Drawbacks
[drawbacks]: #drawbacks

Expand All @@ -74,6 +99,11 @@ writing macros if they have many resources.
* Write the aforementioned macro. This is inferior in terms of UX. Depending on
the implementation it may or may not be possible to default lifetimes in
generics.
* Make all non-elided lifetimes `'static`. This has the drawback of creating
hard-to-spot errors (that would also probably occur in the wrong place) and
confusing users.
* Make all non-declared lifetimes `'static`. This would not be backwards
compatible due to interference with lifetime elision.
* Infer types for statics. The absence of types makes it harder to reason about
the code, so even if type inference for statics was to be implemented,
defaulting lifetimes would have the benefit of pulling the cost-benefit
Expand Down

0 comments on commit 2526483

Please sign in to comment.