2015-06-01 34 views
9

我有一個皮棉在x.len() == 0上發出警告,建議使用x.is_empty()來代替。但是,如果x沒有is_empty(self: &Self)方法,我想擺脫誤報。如何在編譯器內查找給定類型和名稱的方法?

因此開始尋求從rustc內部查找方法。

第一步,得到x:我的相匹配,以ExprExprMethodCall(ref method, _, ref args)node(及確信,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 

我根本沒有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 } } 

我沒有TraitOrItemId任何IMPL項目,這是一個有點可惜。有人可以通過rustc幫助我找到我的impl物品嗎?

回答

4

我明白了!問題是我試圖獲得類型的DefId,而不是impl。經過cx.tcx.inherent_impls.get(id)給了我一個DefId的vec內在impls,然後我可以通過我已經實現的impl_items查詢來查詢。

查看rust-clippy/src/len_zero.rs獲取示例實現。編輯:請注意,實現O(N)其中ñ是的(無論是直接impl或性狀)類型的方法的數量 - 也許rustc有一天會允許更快的查找...

相關問題