From cd09180fcf29d72d8a0477c5ac179f1f53bf573c Mon Sep 17 00:00:00 2001 From: Young-Flash <871946895@qq.com> Date: Mon, 27 Nov 2023 22:32:06 +0800 Subject: [PATCH] Site updated: 2023-11-27 22:32:05 --- .../index.html" | 6 +-- categories/index.html | 48 +++++++++---------- local-search.xml | 2 +- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git "a/2023/11/27/\346\216\222\346\237\245\344\270\200\344\270\252 Rust Analyzer \345\217\221\347\211\210\345\220\216\345\207\272\347\216\260\347\232\204 bug/index.html" "b/2023/11/27/\346\216\222\346\237\245\344\270\200\344\270\252 Rust Analyzer \345\217\221\347\211\210\345\220\216\345\207\272\347\216\260\347\232\204 bug/index.html" index 95f2c41..d61fa8b 100644 --- "a/2023/11/27/\346\216\222\346\237\245\344\270\200\344\270\252 Rust Analyzer \345\217\221\347\211\210\345\220\216\345\207\272\347\216\260\347\232\204 bug/index.html" +++ "b/2023/11/27/\346\216\222\346\237\245\344\270\200\344\270\252 Rust Analyzer \345\217\221\347\211\210\345\220\216\345\207\272\347\216\260\347\232\204 bug/index.html" @@ -193,7 +193,7 @@ - 653 字 + 643 字 @@ -245,9 +245,9 @@

定 一番浏览下来,发现了这个新增的 crates/ide-diagnostics/src/handlers/trait_impl_missing_assoc_item.rs,从名字上看就很可疑,然后仔细浏览这个文件,发现正是他的问题。这个文件所在的 PR 增加了一个新的 diagnostic,使得 RA 可以检测出用户在为 struct impl trait 的时候哪些 associate item 没有实现。

解决问题

-

这个 PR 是这样检测未在 impl 体中实现的 associate item 的,对于 AssocItemId::ConstId(_) => true, 的处理是直接返回 true,也就是默认为必须在 impl 体中实现而漏掉了在 trait 的定义中可能有为这个 const item 设置默认值的情况。知道了问题所在,剩下的就比较好解决了,直接将针对 const item 的处理修改为 Const::from(id).value(db).is_none(),也就是判断这一项有没有设置了默认值,如果有的话就不必作为 required_items 从而引发错误的 diagnostic

+

这个 PR 是这样检测未在 impl 体中实现的 associate item 的,对于 AssocItemId::ConstId(_) => true, 的处理是直接返回 true,也就是默认为必须在 impl 体中实现而漏掉了在 trait 的定义中可能有为这个 const item 设置默认值的情况。知道了问题所在,剩下的就比较好解决了,将针对 const item 的处理修改为 Const::from(id).value(db).is_none(),也就是判断这一项有没有设置了默认值,如果有的话就不必作为 required_items 从而引发错误的 diagnostic

1
2
3
4
5
let required_items = items.iter().filter(|&(_, assoc)| match *assoc {
AssocItemId::FunctionId(it) => !db.function_data(it).has_body(),
AssocItemId::ConstId(_) => true,
AssocItemId::TypeAliasId(it) => db.type_alias_data(it).type_ref.is_none(),
});
-

接着再为这个小 fix 增加一个验证的 test,跑一遍 cargo test 确保所有测试都没问题之后就可以提 PR 修复了:fix: handle default constant values in trait_impl_missing_assoc_item diagnostic

+

接着再为这个小 fix 增加一个验证的 test,跑一遍 cargo test 确保所有测试都没问题之后就可以提 PR 修复了

1
2
3
4
5
6
7
8
9
10
11
12
    #[test]
fn trait_with_default_value() {
check_diagnostics(
r#"
trait Marker {
const FLAG: bool = false;
}
struct Foo;
impl Marker for Foo {}
"#,
)
}

最后

Rust Analyzer 会自动发 nightly releases,这样看来频繁发版还是有好处的,相邻版本之间的 diff 不会太大,发版后引发的 bug 才比较好定位,要是版本之间的 diff 上千个文件我可能就不会一个个去看了哈哈哈

diff --git a/categories/index.html b/categories/index.html index 71fef84..c2b07be 100644 --- a/categories/index.html +++ b/categories/index.html @@ -190,7 +190,7 @@
发现问题

前些天有用户反馈了一个 Rust Analyzer 的 issue,说的是在升级到最新版的 RA 后出现了之前没出现的 bug:当一个 trait 的 associate item 提供了默认实现时,struct impl 这个 trait 时如果不提供实现则 RA 会报错如下,而实际上这在 Rust 中是合法的。

1
2
3
4
5
trait Marker {
const FLAG: bool = false;
}
struct Foo;
impl Marker for Foo {} // <--- error: not all trait items implemented, missing: `const FLAG`

定位问题

这是一个在最新版中才出现的错误,说明是在这一版中才引入的而不是陈年老 bug。于是我在 GitHub 上 compare 这一版的 commit 和上一版本的 commit,这中间有 84 个 Files changed, 不算多。

一番浏览下来,发现了这个新增的 crates/ide-diagnostics/src/handlers/trait_impl_missing_assoc_item.rs,从名字上看就很可疑,然后仔细浏览这个文件,发现正是他的问题。这个文件所在的 PR 增加了一个新的 diagnostic,使得 RA 可以检测出用户在为 struct impl trait 的时候哪些 associate item 没有实现。

解决问题

这个 PR 是这样检测未在 impl 体中实现的 associate item 的,对于 AssocItemId::ConstId(_) => true, 的处理是直接返回 true,也就是默认为必须在 impl 体中实现而漏掉了在 trait 的定义中可能有为这个 const item 设置默认值的情况。知道了问题所在,剩下的就比较好解决了,直接将针对 const item 的处理修改为 Const::from(id).value(db).is_none(),也就是判断这一项有没有设置了默认值,如果有的话就不必作为 required_items 从而引发错误的 diagnostic

1
2
3
4
5
let required_items = items.iter().filter(|&(_, assoc)| match *assoc {
AssocItemId::FunctionId(it) => !db.function_data(it).has_body(),
AssocItemId::ConstId(_) => true,
AssocItemId::TypeAliasId(it) => db.type_alias_data(it).type_ref.is_none(),
});

接着再为这个小 fix 增加一个验证的 test,跑一遍 cargo test 确保所有测试都没问题之后就可以提 PR 修复了:fix: handle default constant values in trait_impl_missing_assoc_item diagnostic

1
2
3
4
5
6
7
8
9
10
11
12
    #[test]
fn trait_with_default_value() {
check_diagnostics(
r#"
trait Marker {
const FLAG: bool = false;
}
struct Foo;
impl Marker for Foo {}
"#,
)
}

最后

Rust Analyzer 会自动发 nightly releases,这样看来频繁发版还是有好处的,相邻版本之间的 diff 不会太大,发版后引发的 bug 才比较好定位,要是版本之间的 diff 上千个文件我可能就不会一个个去看了哈哈哈

参考

]]> + 发现问题

前些天有用户反馈了一个 Rust Analyzer 的 issue,说的是在升级到最新版的 RA 后出现了之前没出现的 bug:当一个 trait 的 associate item 提供了默认实现时,struct impl 这个 trait 时如果不提供实现则 RA 会报错如下,而实际上这在 Rust 中是合法的。

1
2
3
4
5
trait Marker {
const FLAG: bool = false;
}
struct Foo;
impl Marker for Foo {} // <--- error: not all trait items implemented, missing: `const FLAG`

定位问题

这是一个在最新版中才出现的错误,说明是在这一版中才引入的而不是陈年老 bug。于是我在 GitHub 上 compare 这一版的 commit 和上一版本的 commit,这中间有 84 个 Files changed, 不算多。

一番浏览下来,发现了这个新增的 crates/ide-diagnostics/src/handlers/trait_impl_missing_assoc_item.rs,从名字上看就很可疑,然后仔细浏览这个文件,发现正是他的问题。这个文件所在的 PR 增加了一个新的 diagnostic,使得 RA 可以检测出用户在为 struct impl trait 的时候哪些 associate item 没有实现。

解决问题

这个 PR 是这样检测未在 impl 体中实现的 associate item 的,对于 AssocItemId::ConstId(_) => true, 的处理是直接返回 true,也就是默认为必须在 impl 体中实现而漏掉了在 trait 的定义中可能有为这个 const item 设置默认值的情况。知道了问题所在,剩下的就比较好解决了,将针对 const item 的处理修改为 Const::from(id).value(db).is_none(),也就是判断这一项有没有设置了默认值,如果有的话就不必作为 required_items 从而引发错误的 diagnostic

1
2
3
4
5
let required_items = items.iter().filter(|&(_, assoc)| match *assoc {
AssocItemId::FunctionId(it) => !db.function_data(it).has_body(),
AssocItemId::ConstId(_) => true,
AssocItemId::TypeAliasId(it) => db.type_alias_data(it).type_ref.is_none(),
});

接着再为这个小 fix 增加一个验证的 test,跑一遍 cargo test 确保所有测试都没问题之后就可以提 PR 修复了

1
2
3
4
5
6
7
8
9
10
11
12
    #[test]
fn trait_with_default_value() {
check_diagnostics(
r#"
trait Marker {
const FLAG: bool = false;
}
struct Foo;
impl Marker for Foo {}
"#,
)
}

最后

Rust Analyzer 会自动发 nightly releases,这样看来频繁发版还是有好处的,相邻版本之间的 diff 不会太大,发版后引发的 bug 才比较好定位,要是版本之间的 diff 上千个文件我可能就不会一个个去看了哈哈哈

参考

]]>