2016-07-11 30 views
12

stavo scrivendo Rust plug-lint quando ho scoperto che la ruggine utilizza tipi diversi per rappresentare le else (Expr) Parti poi (Block) e di un if dichiarazione sia libsyntax::ast::ExprKind e librustc::hir::Expr_.Perché l'AST di Rust if-else usa tipi diversi per allora e per il resto?

Ho bisogno che entrambi abbiano tipi comuni.

Devo usare solo una corrispondenza esplicita su hir::Expr_::ExprBlock, oppure la parte potrebbe essere qualcos'altro, e ho bisogno di fare un confronto più intelligente?

Da the source:

// ... 
pub enum Expr_ { 
    // ... 
    /// An `if` block, with an optional else block 
    /// 
    /// `if expr { block } else { expr }` 
    ExprIf(P<Expr>, P<Block>, Option<P<Expr>>), 
    // ... 
} 
// ... 
+2

Direi che è perché devi _ utilizzare un blocco (quindi un '{/ * codice * /}') dopo un 'if', ma puoi omettere le parentesi dopo un' else'. Quindi puoi scrivere 'if foo() {bar(); } else baz(); 'ma non puoi scrivere' se foo() bar() else baz() '. – musicmatze

+1

@musicmatze è molto sbagliato. La ruggine NON consente esplicitamente di lasciare le parentesi dopo un altro. Altrimenti siamo di nuovo nell'inferno. –

+0

@ker ah, okay. Non lo sapevo, quindi grazie per avermi corretto! – musicmatze

risposta

7

Questo è così possiamo distinguere

if x { 
    foo(); 
} else if y { 
    bar(); 
} 

da

if x { 
    foo(); 
} else { // note the block 
    if y { 
     bar(); 
    } 
} 

Il primo ha un ExprIf nel nodo della altrove Expr mentre la il secondo ha un ExprBlock contenente come ingle ExprIf -expression.

+5

Potresti fornire esempi di codice (pseudo) su come ognuno dei due casi apparirebbe come "ExprIf"? – Shepmaster

+1

@Shepmaster, il primo è 'ExprIf (_, Block (...), Some (ExprIf (...)))', e il secondo è 'ExprIf (_, Block (...), Some (Block (..., ExprIf (...), ...))) '. – Cpud36

Problemi correlati