2015-06-12 7 views
11

Update: questo è un vecchio bug solved a 1,12espressione della corrispondenza che cade attraverso?


Ecco qualche modello artificioso, ma semplice corrispondenza esempio (demo):

fn main() { 
    let x = 'a'; 

    match x { 
      'a'...'b' if false => { 
       println!("one"); 
      }, 

      'a' => { 
       println!("two"); 
      }, 

      'a'...'b' => { 
       println!("three"); 
      }, 

      _ => panic!("what?") 
    } 
} 

quando l'eseguo, ottengo three come output. Perché sta succedendo? Il secondo ramo non dovrebbe coincidere prima?

+0

Oooh, sembra un bug. Se si commenta * o * corrisponde arm con un '...', corrisponde a "due", anche se si commenta il braccio di corrispondenza ** dopo ** i "due". Pura speculazione, mi chiedo se c'è qualche ottimizzazione errata che sta coalizzando le due gamme insieme e facendole sparare per prime. Mmm, si, se cambi il primo intervallo in '' a '...' c'', poi "due" corrispondenze ... – Shepmaster

+0

Ho aperto un [bug report] (https://github.com)/ruggine lang/ruggine/temi/26251). – rvidal

risposta

4

Guardare il LLVM IR in Debug, è già imperfetto, quindi questo è sicuramente un bug in rustc; useremo l'IR sotto indicato per verificare cosa sta succedendo.

Quindi, %x viene assegnato 'a' (97 in ASCII) e %10 viene assegnato il risultato di x >= 'a' and x <= 'b'; se questo è vero, andiamo a match_case, altrimenti a compare_next. match_case reindirizza a cond, che reindirizza a case_body2 che stampa "three".

In teoria, avremmo voluto andare a case_body1 (stampa "two"), da cond7, da match_case4, da compare_next. Ma compare_next viene raggiunto solo se x non è in ['a', 'b'] secondo l'IR.

Questo chiaramente sembra un bug.

; Function Attrs: uwtable 
define internal void @_ZN4main20h4f7b0d7962de19d8eaaE() unnamed_addr #0 { 
entry-block: 
    %x = alloca i32 
    ; [...] 
    store i32 97, i32* %x 
    %7 = load i32* %x, !range !0 
    %8 = icmp uge i32 %7, 97 
    %9 = icmp ule i32 %7, 98 
    %10 = and i1 %8, %9 
    br i1 %10, label %match_case, label %compare_next 

case_body:          ; preds = %next6, %next 
    ; println!("one") 
    br label %case_body8 

case_body1:          ; preds = %cond7 
    ; println!("two") 
    br label %case_body10 

case_body2:          ; preds = %cond 
    ; println!("three") 
    br label %case_body15 

case_body3:          ; preds = %match_else 
    ; panic!("what") 
    unreachable 

match_else:          ; preds = %compare_next5 
    br label %case_body3 

match_case:          ; preds = %entry-block 
    br i1 true, label %cond, label %next 

compare_next:          ; preds = %entry-block 
    %16 = icmp eq i32 %7, 97 
    br i1 %16, label %match_case4, label %compare_next5 

next:            ; preds = %match_case 
    br label %case_body 

cond:            ; preds = %match_case 
    br label %case_body2 

match_case4:          ; preds = %compare_next 
    br i1 true, label %cond7, label %next6 

; [...] 

cond7:           ; preds = %match_case4 
    br label %case_body1 

; [...] 
} 
Problemi correlati