Необходимость указания времени жизни в Rust когда компилятор может вывести время жизни сам

Почему этот код вызывает ошибку:

const MSG: &str = "Hello";

fn one_of(_first: &str, _second: &str) -> &str {
    MSG
}

Задал это вопрос своему железному другу (gpt-4-1106-preview) и он ответил:

Код вызывает ошибку, потому что Rust не может гарантировать, что строка, на которую ссылается MSG, будет жить достаточно долго, чтобы безопасно использовать возвращаемую ссылку из функции one_of

Ну, ладно, допустим, тогда почему эта функция НЕ вызывает ошибку:

const MSG: &str = "Hello";

fn one(_first: &str) -> &str {
    MSG
}

Мой друг ответил:

Когда функция one объявлена без явного указания времени жизни для возвращаемой ссылки, компилятор использует вывод времени жизни и видит, что возвращаемое значение MSG имеет статическое время жизни. В результате компилятор считает, что функция возвращает ссылку со статическим временем жизни, и этот вывод совместим с временем жизни входного параметра (который в данном случае игнорируется, так как не используется для определения времени жизни возвращаемого значения).

на мое резонное возражение:

но ведь и вслучае one_of компилятор может автоматически присвоить функции статическое время жизни, как и в случае one, почему все, что ты сказал по поводу one недействительно в случае с функцией one_of?

Мой друг окончательно сломался, начал извиняться "за путаницу", и заявил, что обе функции не должны вызывать ошибку (хотя, это не так).

Требуется помощь биологических нейросетей, то есть вас, уважаемые кожаные и костистые друзья! Объясните сабж


Ответы (1 шт):

Автор решения: Kalashnikov Alexander

Когда функция возвращает ссылку, компилятор должен знать её время жизни. Под "знать" понимается "определить время жизни ссылки по сигнатуре функции" без исследования тела функции. Во имя сохранения труда программистов в Rust придумали правила неявного выведения времени жизни возвращаемого значения.

В данном случае функция получает на вход две разных ссылки, компилятор не решается определить, к времени жизни какой из них нужно привязать время жизни возвращаемой ссылки. Требуется подсказать ему, например так:

fn one_of<'a>(_first: &'a str, _second: &'a str) -> &'a str {
    MSG
}
→ Ссылка