выражение лица спички проваливается?
Обновление: это старая ошибка решена в 1.12
Вот какой-то надуманный, но простой пример соответствия шаблону (демо):
fn main() {
let x = 'a';
match x {
'a'...'b' if false => {
println!("one");
},
'a' => {
println!("two");
},
'a'...'b' => {
println!("three");
},
_ => panic!("what?")
}
}
Когда я запускаю его, я получаю three
в качестве вывода. Почему это происходит? Разве вторая ветвь не должна соответствовать первой?
1 ответ:
Глядя на LLVM IR в Debug, он уже испорчен, так что это определенно ошибка в
rustc
; мы будем использовать кураторскую ИК ниже, чтобы проверить, что происходит.Таким образом,
В теории мы хотели бы перейти к%x
присваивается 'a' (97 в ASCII), а%10
присваивается результатx >= 'a' and x <= 'b'
; Если это верно, мы переходим кmatch_case
, иначе кcompare_next
.match_case
перенаправление наcond
, которое перенаправляет наcase_body2
, которое печатает"three"
.case_body1
(печать"two"
), отcond7
, отmatch_case4
, отcompare_next
. Ноcompare_next
достигается только в том случае, еслиx
не находится в['a', 'b']
согласно ИК.Это явно похоже на ошибку.
; 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 ; [...] }