Skip to content

Commit 4406391

Browse files
committed
Fix bug in matching on floating-point ranges
1 parent 0fb52fb commit 4406391

File tree

8 files changed

+35
-56
lines changed

8 files changed

+35
-56
lines changed

src/librustc_mir/hair/pattern/_match.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -812,8 +812,17 @@ impl<'tcx> IntRange<'tcx> {
812812
fn from_ctor(tcx: TyCtxt<'_, 'tcx, 'tcx>,
813813
ctor: &Constructor<'tcx>)
814814
-> Option<IntRange<'tcx>> {
815+
// Floating-point ranges are permitted and we don't want
816+
// to consider them when constructing integer ranges.
817+
fn is_integral<'tcx>(ty: Ty<'tcx>) -> bool {
818+
match ty.sty {
819+
ty::Char | ty::Int(_) | ty::Uint(_) => true,
820+
_ => false,
821+
}
822+
}
823+
815824
match ctor {
816-
ConstantRange(lo, hi, ty, end) => {
825+
ConstantRange(lo, hi, ty, end) if is_integral(ty) => {
817826
// Perform a shift if the underlying types are signed,
818827
// which makes the interval arithmetic simpler.
819828
let bias = IntRange::signed_bias(tcx, ty);
@@ -826,7 +835,7 @@ impl<'tcx> IntRange<'tcx> {
826835
Some(IntRange { range: lo..=(hi - offset), ty })
827836
}
828837
}
829-
ConstantValue(val) => {
838+
ConstantValue(val) if is_integral(val.ty) => {
830839
let ty = val.ty;
831840
if let Some(val) = val.assert_bits(tcx, ty::ParamEnv::empty().and(ty)) {
832841
let bias = IntRange::signed_bias(tcx, ty);
@@ -836,9 +845,7 @@ impl<'tcx> IntRange<'tcx> {
836845
None
837846
}
838847
}
839-
Single | Variant(_) | Slice(_) => {
840-
None
841-
}
848+
_ => None,
842849
}
843850
}
844851

src/test/run-pass/array-slice-vec/vec-matching-autoslice.stderr

-8
This file was deleted.

src/test/run-pass/binding/match-range.stderr

-20
This file was deleted.

src/test/run-pass/issues/issue-15881-model-lexer-dotdotdot.stderr

-8
This file was deleted.

src/test/run-pass/issues/issue-7222.stderr

-8
This file was deleted.

src/test/ui/match/match-range-fail-dominate.stderr

+1-7
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,5 @@ error: unreachable pattern
6262
LL | 0.02f64 => {}
6363
| ^^^^^^^
6464

65-
error: unreachable pattern
66-
--> $DIR/match-range-fail-dominate.rs:47:7
67-
|
68-
LL | _ => {}
69-
| ^
70-
71-
error: aborting due to 6 previous errors
65+
error: aborting due to 5 previous errors
7266

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![allow(illegal_floating_point_literal_pattern)]
2+
#![deny(unreachable_patterns)]
3+
4+
fn main() {
5+
match 0.0 {
6+
0.0..=1.0 => {}
7+
_ => {} // ok
8+
}
9+
10+
match 0.0 { //~ ERROR non-exhaustive patterns
11+
0.0..=1.0 => {}
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0004]: non-exhaustive patterns: `_` not covered
2+
--> $DIR/non-exhaustive-float-range-match.rs:10:11
3+
|
4+
LL | match 0.0 { //~ ERROR non-exhaustive patterns
5+
| ^^^ pattern `_` not covered
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0004`.

0 commit comments

Comments
 (0)