Для меня это выглядит как особенность алгоритма вывода типов, и, вероятно, нет более глубокой причины для этого, за исключением того, что текущий алгоритм вывода работает так, как он.Не существует формальной спецификации того, когда вывод типа работает, а когда нет.Если вы столкнулись с ситуацией, которую механизм вывода типов не может обработать, вам нужно добавить аннотации типов или переписать код таким образом, чтобы компилятор мог правильно выводить типы, и это именно то, что вам нужно сделать здесь.
Каждая функция в Rust имеет свой отдельный тип элемента функции , который не может быть напрямую назван синтаксисом, но отображается как, например, fn() -> u32 {foo}
в сообщениях об ошибках.Существует специальное принуждение, которое преобразует типы элементов функции с идентичными сигнатурами в соответствующий тип указателя функции, если они встречаются в разных ветвях match
, в разных ветвях if
или в разных элементах массива.Это принуждение отличается от других принуждений, так как оно происходит не только в явно типизированном контексте («узлы принуждения»), и эта специальная обработка является вероятной причиной этой идиосинкразии.
Специальное принуждение инициируетсяпривязка
let tmp = [foo, bar];
, поэтому тип tmp
полностью определяется как [fn() -> u32; 2]
.Однако, кажется, что специальное приведение не срабатывает достаточно рано в алгоритме вывода типов при записи
let b = box [foo, bar] as Box<[_]>;
Компилятор сначала предполагает, что тип элемента массива - это тип его первого элемента, и, очевидно, при попыткеЧтобы определить, что здесь обозначает _
, компилятор все еще не обновил это понятие - согласно сообщению об ошибке, _
выводится как fn() -> u32 {foo}
здесь.Интересно, что компилятор уже правильно определил полный тип box [foo, bar]
при печати сообщения об ошибке, поэтому поведение действительно довольно странное.Полное объяснение может быть дано только при подробном рассмотрении исходных текстов компилятора.
Механизм решателя типов Rust часто не может справиться с ситуациями, которые теоретически он должен решать. меловой движок Niko Matsakis призван обеспечить общее решение для всех этих случаев в какой-то момент в будущем, но я не знаю, каков статус и сроки этого проекта.