Вывод времени жизни Rust в ограниченном impl с параметром времени жизни завершается неудачей, но настройка ограничений разрешает ошибку - PullRequest
0 голосов
/ 21 февраля 2020

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

trait Converts<T> {
    fn convert(&mut self, from: T);
}

trait CompoundConversion<C> {
    fn convert(&self, to: &mut C);
}

struct TestThunk<'a> {
    test: &'a Test,
}

impl<'a, C> CompoundConversion<C> for TestThunk<'a> 
    where C: Converts<String> + Converts<isize>
{
    fn convert(&self, to: &mut C) {
        to.convert(self.test.name.to_owned());
        to.convert(self.test.id);
    }
}

struct Test {
    name: String,
    id: isize,
}

impl Test {
    fn thunk<'a>(&'a self) -> TestThunk<'a> {
        TestThunk {
            test: self
        }
    }
}

// Produces an error:
impl<'a, C> CompoundConversion<C> for Test 
    where TestThunk<'a>: CompoundConversion<C>
{
    fn convert(&self, to: &mut C) {
        self.thunk().convert(to)
    }
}

Я думаю, что это не работает, потому что 'a выводится быть действительным в течение времени жизни значения Test, а не просто вызова метода.

Что меня действительно смущает, так это то, что изменение ограничений немного исправляет это.

// Works:
impl<C> CompoundConversion<C> for Test 
    where C: Converts<String> + Converts<isize>
{
    fn convert(&self, to: &mut C) {
        self.thunk().convert(to)
    }
}

Playground

Это построение без каких-либо проблемы, но код не делает ничего другого. Насколько я могу судить, эти два набора ограничений должны быть функционально идентичными, но очевидно, что наличие параметра времени жизни в первом примере имеет какое-то значение. Когда явный параметр удален, компилятор, по-видимому, выводит срок службы, который работает, но я понятия не имею, смогу ли я помочь ему сделать это и для первого примера.

Что именно приводит к сбою первого примера, несмотря на то, что ограничение, которое фактически одинаково (но без параметра времени жизни), работает нормально?

Есть ли способ заставить первый пример работать, не прибегая к дублированию ограничений Converts на обоих Test ' s и TestThunk это означает?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...