Skip to content

Commit ba1849d

Browse files
committed
rustc: move most of lifetime elision to resolve_lifetimes.
1 parent bbc3414 commit ba1849d

13 files changed

+703
-602
lines changed

src/librustc/diagnostics.rs

+63
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,69 @@ struct ListNode {
327327
This works because `Box` is a pointer, so its size is well-known.
328328
"##,
329329

330+
E0106: r##"
331+
This error indicates that a lifetime is missing from a type. If it is an error
332+
inside a function signature, the problem may be with failing to adhere to the
333+
lifetime elision rules (see below).
334+
335+
Here are some simple examples of where you'll run into this error:
336+
337+
```compile_fail,E0106
338+
struct Foo { x: &bool } // error
339+
struct Foo<'a> { x: &'a bool } // correct
340+
341+
enum Bar { A(u8), B(&bool), } // error
342+
enum Bar<'a> { A(u8), B(&'a bool), } // correct
343+
344+
type MyStr = &str; // error
345+
type MyStr<'a> = &'a str; // correct
346+
```
347+
348+
Lifetime elision is a special, limited kind of inference for lifetimes in
349+
function signatures which allows you to leave out lifetimes in certain cases.
350+
For more background on lifetime elision see [the book][book-le].
351+
352+
The lifetime elision rules require that any function signature with an elided
353+
output lifetime must either have
354+
355+
- exactly one input lifetime
356+
- or, multiple input lifetimes, but the function must also be a method with a
357+
`&self` or `&mut self` receiver
358+
359+
In the first case, the output lifetime is inferred to be the same as the unique
360+
input lifetime. In the second case, the lifetime is instead inferred to be the
361+
same as the lifetime on `&self` or `&mut self`.
362+
363+
Here are some examples of elision errors:
364+
365+
```compile_fail,E0106
366+
// error, no input lifetimes
367+
fn foo() -> &str { }
368+
369+
// error, `x` and `y` have distinct lifetimes inferred
370+
fn bar(x: &str, y: &str) -> &str { }
371+
372+
// error, `y`'s lifetime is inferred to be distinct from `x`'s
373+
fn baz<'a>(x: &'a str, y: &str) -> &str { }
374+
```
375+
376+
Here's an example that is currently an error, but may work in a future version
377+
of Rust:
378+
379+
```compile_fail,E0106
380+
struct Foo<'a>(&'a str);
381+
382+
trait Quux { }
383+
impl Quux for Foo { }
384+
```
385+
386+
Lifetime elision in implementation headers was part of the lifetime elision
387+
RFC. It is, however, [currently unimplemented][iss15872].
388+
389+
[book-le]: https://doc.rust-lang.org/nightly/book/lifetimes.html#lifetime-elision
390+
[iss15872]: https://github.com/rust-lang/rust/issues/15872
391+
"##,
392+
330393
E0109: r##"
331394
You tried to give a type parameter to a type which doesn't need it. Erroneous
332395
code example:

src/librustc/hir/lowering.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -314,9 +314,10 @@ impl<'a> LoweringContext<'a> {
314314
TyKind::Slice(ref ty) => hir::TySlice(self.lower_ty(ty)),
315315
TyKind::Ptr(ref mt) => hir::TyPtr(self.lower_mt(mt)),
316316
TyKind::Rptr(ref region, ref mt) => {
317+
let span = Span { hi: t.span.lo, ..t.span };
317318
let lifetime = match *region {
318319
Some(ref lt) => self.lower_lifetime(lt),
319-
None => self.elided_lifetime(t.span)
320+
None => self.elided_lifetime(span)
320321
};
321322
hir::TyRptr(lifetime, self.lower_mt(mt))
322323
}

0 commit comments

Comments
 (0)