Skip to content

Commit 9c533e8

Browse files
author
QuineDot
committed
Explanation for unintuitive associated const lifetime elision behavior (rust-lang/rust#115010)
1 parent df80779 commit 9c533e8

File tree

1 file changed

+18
-9
lines changed

1 file changed

+18
-9
lines changed

src/dyn-elision-trait-bounds.md

+18-9
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,14 @@ const S_CH: PhantomData<Box<dyn Halfie<'static, 'static> + 'static>> = CH;
477477
const S_CD: PhantomData<Box<dyn Double<'static, 'static> + 'static>> = CD;
478478
```
479479

480-
In a context where non-`'static` lifetimes can be named, those lifetimes
481-
act like early-bound lifetimes in function signatures.
480+
However, from Rust 1.64 forward, associated `const`s were allowed to use general
481+
elided lifetimes and the wildcard lifetime (as opposed to only elided
482+
trait object lifetimes). [This was an accidental stabilization which
483+
will probably be removed or modified.](https://github.com/rust-lang/rust/issues/115010)
484+
485+
In the meanwhile, elided lifetimes act like independent lifetime
486+
variables on the `impl` block. Those in turn act like early-bound
487+
lifetimes in function signatures.
482488
```rust
483489
#use core::marker::PhantomData;
484490
#trait Single<'a>: 'a + Send + Sync {}
@@ -491,7 +497,8 @@ impl<'a, 'b> L<'a, 'b> {
491497
const S_CS: PhantomData<Box<dyn Single<'a> + 'a>> = Self::CS;
492498
}
493499
```
494-
Elided lifetimes are still inferred to be `'static`...
500+
501+
Elided lifetimes can be inferred to be `'static` elsewhere...
495502
```rust
496503
#use core::marker::PhantomData;
497504
#trait Single<'a>: 'a + Send + Sync {}
@@ -504,9 +511,9 @@ impl<'a, 'b> L<'a, 'b> {
504511
const S_SCS: PhantomData<Box<dyn Single<'static> + 'static>> = Self::SCS;
505512
}
506513
```
507-
*...however,* this inference only seems to take effect after the
508-
definition itself for elided trait object lifetimes, as demonstrated
509-
by cases such as this being ambiguous:
514+
515+
*...however,* it's really a free variable. Therefore, cases such
516+
as this are considered ambiguous:
510517
```rust
511518
#use core::marker::PhantomData;
512519
#trait Double<'a, 'b>: 'a + 'b + Send + Sync {}
@@ -515,9 +522,9 @@ impl<'a, 'b> L<'a, 'b> {
515522
const EBCD: PhantomData<Box<dyn Double<'a, '_>>> = PhantomData;
516523
}
517524
```
518-
...and cases such this saying that the reference lifetime is longer
519-
than the trait object, even when they have the same anonymous
520-
lifetime:
525+
...and cases such this are considered to be a borrow check violation,
526+
as there are no outlives relationships between the anonymously
527+
introduced lifetime parameters:
521528
```rust
522529
#use core::marker::PhantomData;
523530
#trait Single<'a>: 'a + Send + Sync {}
@@ -527,6 +534,8 @@ impl<'a, 'b, 'r> R<'a, 'b, 'r> where 'a: 'r, 'b: 'r {
527534
const RECS: PhantomData<&'r dyn Single<'_>> = PhantomData;
528535
}
529536
```
537+
(There is no implicit bound due to nesting the lifetimes because
538+
the nesting occurs in the body of the `impl` block and not the header.)
530539

531540
### `impl` headers
532541

0 commit comments

Comments
 (0)