В последнем сообщении упоминалось, как возник код ошибки 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 declaration
fn 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 и возвращаемом типе. А пока до свидания :). Спасибо за чтение.