В последнем сообщении упоминалось, как возник код ошибки E0611. В этом посте речь пойдет о частях языка, которые мы не рассматриваем в коде ошибки, таких как черты и замыкания, а также о дальнейших изменениях дизайна в коде ошибки.
Во-первых, мы называем его E0621, так как E0620 - это наивысший код ошибки до сих пор.
Часовой мозговой штурм закончился очень интересными случаями. До сих пор мы рассматривали только бесплатные функции, такие как foo(), и функции в трейтах.
Подробнее о чертах…
trait Foo {
fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32;
- consider changing the type of `x` to &'a i32
Проблема с выдачей ошибки означает, что нам также нужно изменить все соответствующие ей импы. Давайте посмотрим на эти два случая,
impl Foo for () { // here, we implement the same signature as the trait declarationfn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 { if x > y { x } else { y } } }
В приведенном выше случае сигнатура признака может быть виновата, т.е. в ней отсутствует объявление времени жизни. Тело функции тоже может быть виновато, т.е. fn должна возвращать только y. В таких случаях неясно, какая из двух является реальной проблемой, и изменение объявления impl означает также изменение свойства. Следовательно, мы предполагаем, что автор мог забыть добавить 'a к подписи.
trait Bar { fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32; }impl Bar for () { // here, we implement a less strict signature than the trait. // This is allowed in Rust.fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 { if x > y { x } else { y } } }
Вызывало беспокойство то, нужно ли рассматривать такие случаи для E0621.. Давайте посмотрим на другой пример.
Impl Items
В случае Impl Items код ошибки касается только Inherent Impls, например
struct Foo {field: i32}impl Foo {fn foo<'a>(&'a self, x: &i32) -> &'a i32 {if true { &self.field } else { x }}
что дает нам

Приведенный ниже фрагмент кода выполняет проверку за нас.
Some(hir_map::NodeImplItem(..)) => {
let container_id = self.tcx
.associated_item(anonymous_region_binding_scope)
.container
.id();
if self.tcx.impl_trait_ref(container_id).is_some() {
// checks whether the ImplItem is implementing a Trait
return None;
}
}
Кроме того, на данный момент не обрабатываются случаи, когда анонимный регион находится в self.
fn foo2<'a>(&self, x: &'a i32) -> &'a i32 {if true { &self.field } else { x }}
Во-первых, для него неправильное форматирование. Во-вторых, у нас может быть случай, подобный приведенному ниже, когда функция self.field не возвращает, и, следовательно, нам не нужно беспокоиться о его времени жизни. Анонимному региону соответствует только возвращаемый тип.
fn foo<'a>(&self, x: &'a i32) -> &i32 {---- consider changing to `&'a i32`x }
Случаи, когда анонимная область находится в возвращаемом типе, в настоящее время также не обрабатываются.
В следующем посте будут проверяться элементы Impl и многое другое в анонимных регионах в self и возвращаемом типе. А пока до свидания :). Спасибо за чтение.