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::{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::pat_util::*;
|
||||||
use middle::ty::*;
|
use middle::ty::*;
|
||||||
use middle::ty;
|
use middle::ty;
|
||||||
@ -102,6 +102,27 @@ pub fn check_arms(cx: &MatchCheckCtxt, arms: &[arm]) {
|
|||||||
let mut seen = ~[];
|
let mut seen = ~[];
|
||||||
for arms.iter().advance |arm| {
|
for arms.iter().advance |arm| {
|
||||||
for arm.pats.iter().advance |pat| {
|
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];
|
let v = ~[*pat];
|
||||||
match is_useful(cx, &seen, v) {
|
match is_useful(cx, &seen, v) {
|
||||||
not_useful => {
|
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