auto merge of #8029 : emillon/rust/issue-6804, r=cmr
Hi, As noted in #6804, a pattern that contains `NaN` will never match because `NaN != NaN`. This adds a warning for such a case. The first commit handles the basic case and the second one generalizes it to more complex patterns using `walk_pat`.
This commit is contained in:
commit
b1f5b1ba5f
@ -10,7 +10,7 @@
|
||||
|
||||
|
||||
use middle::const_eval::{compare_const_vals, lookup_const_by_id};
|
||||
use middle::const_eval::{eval_const_expr, const_val, const_bool};
|
||||
use middle::const_eval::{eval_const_expr, const_val, const_bool, const_float};
|
||||
use middle::pat_util::*;
|
||||
use middle::ty::*;
|
||||
use middle::ty;
|
||||
@ -102,6 +102,27 @@ pub fn check_arms(cx: &MatchCheckCtxt, arms: &[arm]) {
|
||||
let mut seen = ~[];
|
||||
for arms.iter().advance |arm| {
|
||||
for arm.pats.iter().advance |pat| {
|
||||
|
||||
// Check that we do not match against a static NaN (#6804)
|
||||
let pat_matches_nan: &fn(@pat) -> bool = |p| {
|
||||
match cx.tcx.def_map.find(&p.id) {
|
||||
Some(&def_static(did, false)) => {
|
||||
let const_expr = lookup_const_by_id(cx.tcx, did).get();
|
||||
match eval_const_expr(cx.tcx, const_expr) {
|
||||
const_float(f) if f.is_NaN() => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
_ => false
|
||||
}
|
||||
};
|
||||
for walk_pat(*pat) |p| {
|
||||
if pat_matches_nan(p) {
|
||||
cx.tcx.sess.span_warn(p.span, "unmatchable NaN in pattern, \
|
||||
use the is_NaN method in a guard instead");
|
||||
}
|
||||
}
|
||||
|
||||
let v = ~[*pat];
|
||||
match is_useful(cx, &seen, v) {
|
||||
not_useful => {
|
||||
|
21
src/test/compile-fail/issue-6804.rs
Normal file
21
src/test/compile-fail/issue-6804.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// Matching against NaN should result in a warning
|
||||
|
||||
use std::float::NaN;
|
||||
|
||||
fn main() {
|
||||
let x = NaN;
|
||||
match x {
|
||||
NaN => {},
|
||||
_ => {},
|
||||
};
|
||||
//~^^^ WARNING unmatchable NaN in pattern, use the is_NaN method in a guard instead
|
||||
match [x, 1.0] {
|
||||
[NaN, _] => {},
|
||||
_ => {},
|
||||
};
|
||||
//~^^^ WARNING unmatchable NaN in pattern, use the is_NaN method in a guard instead
|
||||
}
|
||||
|
||||
// At least one error is needed so that compilation fails
|
||||
#[static_assert]
|
||||
static b: bool = false; //~ ERROR static assertion failed
|
Loading…
Reference in New Issue
Block a user