如何在给定类型和名称的编译器中查找方法?

llo*_*giq 9 lint rust

我有一个发出警告的棉绒x.len() == 0,建议x.is_empty()改用.但是,如果x没有is_empty(self: &Self)方法,我想摆脱误报.

因此开始寻求从rustc内部查找方法.

第一步,让x我匹配nodeExpr,以ExprMethodCall(ref method, _, ref args)(和确信,args.len() == 1method.node.as_str() == "len"),只是用&*args[0],我会请expr从现在开始.

下一步,获取类型x:这可以很容易地使用rustc::middle::ty::expr_ty(cx.tcx, expr).请注意,这是一个rustc::middle::ty::Ty(而不是一个syntax::ast::Ty,这导致一些混乱).

要查找的方法中,ctxt.impl_itemsctxt.trait_item_def_ids看起来前途无量,所以我得到DefId了我喜欢的类型与rustc::middle::ty::ty::ty_to_def_id(ty)和尝试得到的ID.但是,这种方法存在一些问题:

对于

let x = [1, 2];
x.len() == 2 // <- lookee here
Run Code Online (Sandbox Code Playgroud)

我根本就没有DefId.这是可以的,因为ty_vec在这种情况下我们有一个,并且std::vec::Vec已知有两个len()is_empty().

好消息是,对于ctxt.trait_item_def_ids 具有is_empty方法的特征,它具有合适的条目.唉,对于以下示例:

struct One;
impl One { fn is_empty(self: &Self) -> bool { false } }
Run Code Online (Sandbox Code Playgroud)

我没有TraitOrItemId任何impl项目,这有点不幸.有人可以帮我找到我的impl物品吗?

llo*_*giq 4

我得到了它!问题是我试图获取类型的 DefId ,而不是impl. 通过查看,cx.tcx.inherent_impls.get(id)我得到了一个DefIds 的 vec 来表示固有的实现,然后我可以通过impl_items我已经实现的查找来查询它。

\n\n

查看rust-clippy/src/len_zero.rs 的示例实现。编辑:请注意,实现是O(N),其中N是该类型的方法数量(直接impl或通过特征) \xe2\x80\x93 也许 rustc 有一天会允许更快的查找......

\n