Skip to content

Commit fbf5eef

Browse files
committed
Anonymous/placeholder lifetime "'_".
1 parent b4907b5 commit fbf5eef

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

text/0000-anon-lifetime.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
- Feature Name: anon_lifetime
2+
- Start Date: 2015-06-26
3+
- RFC PR: (leave this empty)
4+
- Rust Issue: (leave this empty)
5+
6+
# Summary
7+
8+
Allow using an undeclared '_ wherever an explicit lifetime can be used, but is
9+
optional, such as function argument/return types and any path inside a function.
10+
11+
# Motivation
12+
13+
During the addition of 'tcx in the compiler (denoting the lifetime of the
14+
arenas used to allocate all the type-system information in the compiler,
15+
via the type context aka `ty::ctxt` aka `tcx`), I had attempted to replace
16+
`&'a ty::ctxt<'tcx>` with a clean `TyCx<'a, 'tcx>` wrapper.
17+
When both `'a` and `'tcx` are either present or missing, it works very well,
18+
but the common case is `&ty::ctxt<'tcx>`, which cannot be represented by
19+
`TyCx<'a, 'tcx>` without adding a new explicit lifetime parameter (`'a`)
20+
to the appropriate function or impl block.
21+
22+
I've recently done this as part of rust-lang/rust#26575, but it wasn't easy
23+
or pretty and any attempts at adding another lifetime to `TyCx` (necessary
24+
for splitting type contexts for performance and possibly parallelism in the
25+
future) would result in more noise at almost every use site of `TyCx`.
26+
27+
# Detailed design
28+
29+
In `resolve_lifetime`: if the lifetime to be resolved matches `"'_"`, store
30+
`DefAnonRegion` as the resolution result.
31+
Small caveat: this check has to be done only if the lifetime has not been
32+
already resolved, because `'_` is a legal lifetime in stable Rust, e.g.:
33+
```rust
34+
fn foo<'_, T>(xs: &'_ [T]) -> &'_ T { &xs[0] }
35+
```
36+
37+
In `typeck::astconv`: if a lifetime has been resolved to `DefAnonRegion`,
38+
return the same region that would be used for `'a` if omitted in `&'a T`.
39+
40+
Example:
41+
```rust
42+
struct Context<'a, 'left: 'a, 'right: 'a> {
43+
left: &'a Inner<'left>,
44+
right: &'a Inner<'right>,
45+
}
46+
fn left<'a, 'left>(cx: Context<'a, 'left, '_>) -> &'a Inner<'left> {
47+
cx.left
48+
}
49+
fn right<'a, 'right>(cx: Context<'a, '_, 'right>) -> &'a Inner<'right> {
50+
cx.left
51+
}
52+
```
53+
54+
# Drawbacks
55+
56+
It might be confusing that `'_` *only* has special semantics attached to it
57+
if it's not declared. It's possible `'_` shouldn't have ever made it into
58+
stable Rust, and it could be removed as no uses are expected in the wild.
59+
It could also be linted against - or the new semantics could be opt-in even
60+
in stable Rust, if we add a mechanism for that.
61+
62+
# Alternatives
63+
64+
Do nothing and suffer the pain of a few hundred unnecessary explicit lifetimes.
65+
66+
# Unresolved questions
67+
68+
What to do with the existing `'_`?
69+
Can a feature-gated implementation be merged if it's not observable in stable?

0 commit comments

Comments
 (0)