Как я могу заставить Impit Trait использовать соответствующее время жизни для изменяемой ссылки на значение с другим временем жизни в нем? - PullRequest
0 голосов
/ 27 мая 2018

У меня есть структура с временем жизни:

struct HasLifetime<'a>( /* ... */ );

Существует реализация черты Foo:

impl<'a, 'b: 'a> Foo for &'a mut HasLifetime<'b> { }

Я хочу реализовать следующую функцию:

fn bar_to_foo<'a, 'b: 'a>(bar: &'a mut Lifetime<'b>) -> impl Foo {
    bar
}

Это не скомпилируется, потому что возвращенный impl действителен только для 'a.Однако, указав impl Foo + 'a, вы получите:

error[E0909]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
 --> src/main.rs:7:60
  |
7 | fn bar_to_foo<'a, 'b: 'a>(bar: &'a mut HasLifetime<'b>) -> impl Trait + 'a {
  |                                                            ^^^^^^^^^^^^^^^
  |
note: hidden type `&'a mut HasLifetime<'b>` captures the lifetime 'b as defined on the function body at 7:1
 --> src/main.rs:7:1
  |
7 | fn bar_to_foo<'a, 'b: 'a>(bar: &'a mut HasLifetime<'b>) -> impl Trait + 'a {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Компиляция, по-видимому эквивалентная функции с объектом в штучной упаковке:

fn bar_to_foo<'a, 'b: 'a>(bar: &'a mut Lifetime<'b>) -> Box<Foo + 'a> {
    Box::new(bar)
}

Как определить bar_to_foo с помощью impl Trait?

ссылка на игровую площадку

1 Ответ

0 голосов
/ 27 мая 2018

Вы должны указать, что возвращаемое значение построено на нескольких временах жизни.Однако вы не можете использовать несколько границ времени жизни с impl Trait, и попытка сделать это не приводит к полезному сообщению об ошибке .

Существует прием, который вы можете использовать, который включает в себя создание фиктивной черты, имеющей параметр времени жизни:

trait Captures<'a> {}
impl<'a, T: ?Sized> Captures<'a> for T {}

fn bar_to_foo<'a, 'b: 'a>(bar: &'a mut HasLifetime<'b>) -> impl Trait + Captures<'b> + 'a {
    bar
}

К счастью, это происходит только тогда, когда «скрытое» время жизни инвариантно , что происходит потому, что ссылкаизменяемые.

...