2015-06-01 11 views
9

Ho una lanolina che avvisa su x.len() == 0, suggerendo di usare invece x.is_empty(). Tuttavia, volevo eliminare i falsi positivi se x non ha il metodo is_empty(self: &Self).Come cercare un metodo all'interno del compilatore dato il tipo e un nome?

Inizia così la ricerca dei metodi dall'interno di rugc.

Primo passo, ottenere il x: ho abbinato il node di un Expr-ExprMethodCall(ref method, _, ref args) (e fatto in modo che args.len() == 1 e method.node.as_str() == "len") e appena usato &*args[0], che chiamerò expr da ora in poi.

Passaggio successivo, ottenere il tipo di x: Questo può essere fatto facilmente utilizzando rustc::middle::ty::expr_ty(cx.tcx, expr). Si noti che questo è un rustc::middle::ty::Ty (e non uno syntax::ast::Ty, che ha portato ad una certa confusione).

Per cercare i metodi, il ctxt.impl_items e ctxt.trait_item_def_ids sembrava promettente, in modo da ottenere la DefId per il mio tipo con rustc::middle::ty::ty::ty_to_def_id(ty) e cercare di ottenere gli ID. Tuttavia, questo approccio ha alcuni problemi:

Per

let x = [1, 2]; 
x.len() == 2 // <- lookee here 

ho semplicemente non ho DefId. Va bene però, perché in questo caso abbiamo un ty_vec e std::vec::Vec ha entrambi len() e is_empty().

Il buon messaggio è che il ctxt.trait_item_def_idsha una voce adatta per un tratto con un metodo is_empty. Ahimè, per il seguente esempio:

struct One; 
impl One { fn is_empty(self: &Self) -> bool { false } } 

Io non ho ricevuto TraitOrItemId per qualsiasi elemento impl, che è un po 'sfortunato. Qualcuno può privy a rustc aiutarmi a trovare i miei articoli impl?

risposta

4

Ho capito! Il problema era che cercavo di ottenere un DefId per il tipo , non per lo impl. Passando attraverso cx.tcx.inherent_impls.get(id) mi ha dato un vec di DefId s per impls inerente, che potrei quindi interrogare tramite la ricerca impl_items che ho già implementato.

Cerca in rust-clippy/src/len_zero.rs per un'implementazione di esempio. Edit: Si noti che l'implementazione è O (N) dove N è il numero di metodi di tipo (sia diretta impl o di tratti) - forse rustc sarà un giorno consentire una ricerca più veloce ...

Problemi correlati