Rust HRTB идентичен, но компилятор говорит, что один тип более общий, чем другой.

Следующий код полностью аннотирован:

fn enter<'a, F, R>(x: &'a i32, func: F) -> R
where
    F: for<'b> FnOnce(&'b i32) -> R,
{
    func(x)
}

fn identity<'a>(x: &'a i32) -> &'a i32 {
    x
}

fn main() {
    let x = &42;
    enter(x, identity);
}

Компилятор сообщает об ошибке при компиляции:

error[E0308]: mismatched types
  --> src/main.rs:14:5
   |
14 |     enter(x, identity);
   |     ^^^^^^^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected trait `for<'b> FnOnce<(&'b i32,)>`
              found trait `for<'a> FnOnce<(&'a i32,)>`
note: the lifetime requirement is introduced here
  --> src/main.rs:3:35
   |
3  |     F: for<'b> FnOnce(&'b i32) -> R,
   |                                   ^

For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to previous error

Тем не менее, общий -> R кажется виновником остановки компиляции, но я не знаю, почему.

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

Связанный:

Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Калькулятор CGPA 12 для семестра
Калькулятор CGPA 12 для семестра
Чтобы запустить этот код и рассчитать CGPA, необходимо сохранить код как HTML-файл, а затем открыть его в веб-браузере. Для этого выполните следующие...
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
О тренинге HTML JavaScript :HTML (язык гипертекстовой разметки) и CSS (каскадные таблицы стилей) - две основные технологии для создания веб-страниц....
Как собрать/развернуть часть вашего приложения Angular
Как собрать/развернуть часть вашего приложения Angular
Вам когда-нибудь требовалось собрать/развернуть только часть вашего приложения Angular или, возможно, скрыть некоторые маршруты в определенных средах?
Запуск PHP на IIS без использования программы установки веб-платформы
Запуск PHP на IIS без использования программы установки веб-платформы
Установщик веб-платформы, предлагаемый компанией Microsoft, перестанет работать 31 декабря 2022 года. Его закрытие привело к тому, что мы не можем...
Оптимизация React Context шаг за шагом в 4 примерах
Оптимизация React Context шаг за шагом в 4 примерах
При использовании компонентов React в сочетании с Context вы можете оптимизировать рендеринг, обернув ваш компонент React в React.memo сразу после...
1
0
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Нет это не так. Когда R объявляется, 'b находится вне контекста, поэтому не может зависеть от него (это один из способов взглянуть на это, есть и другие).

Это необходимо для того, чтобы такие API, как std::thread::LocalKey::with(), были надежными: если бы R было разрешено содержать время жизни (неявное в случае with()), ссылки на локальный поток могли бы избежать замыкание и with(), а затем используются в разных потоках, вызывая UB.

Насколько мне известно, нет никакого способа иметь общий тип возвращаемого значения и разрешить ему ссылаться на параметры.

Другие вопросы по теме