Skip to content

Commit 0b86340

Browse files
committed
Auto merge of rust-lang#6144 - rust-lang:float-cmp-ref, r=ebroto
allow refs in our constant folder This helps with rust-lang#3804 (but won't completely fix it). --- changelog: none
2 parents 08bd3f0 + 26e4de9 commit 0b86340

File tree

3 files changed

+20
-7
lines changed

3 files changed

+20
-7
lines changed

clippy_lints/src/consts.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ pub enum Constant {
4040
Tuple(Vec<Constant>),
4141
/// A raw pointer.
4242
RawPtr(u128),
43+
/// A reference
44+
Ref(Box<Constant>),
4345
/// A literal with syntax error.
4446
Err(Symbol),
4547
}
@@ -66,6 +68,7 @@ impl PartialEq for Constant {
6668
(&Self::Bool(l), &Self::Bool(r)) => l == r,
6769
(&Self::Vec(ref l), &Self::Vec(ref r)) | (&Self::Tuple(ref l), &Self::Tuple(ref r)) => l == r,
6870
(&Self::Repeat(ref lv, ref ls), &Self::Repeat(ref rv, ref rs)) => ls == rs && lv == rv,
71+
(&Self::Ref(ref lb), &Self::Ref(ref rb)) => *lb == *rb,
6972
// TODO: are there inter-type equalities?
7073
_ => false,
7174
}
@@ -110,6 +113,9 @@ impl Hash for Constant {
110113
Self::RawPtr(u) => {
111114
u.hash(state);
112115
},
116+
Self::Ref(ref r) => {
117+
r.hash(state);
118+
},
113119
Self::Err(ref s) => {
114120
s.hash(state);
115121
},
@@ -144,6 +150,7 @@ impl Constant {
144150
x => x,
145151
}
146152
},
153+
(&Self::Ref(ref lb), &Self::Ref(ref rb)) => Self::partial_cmp(tcx, cmp_type, lb, rb),
147154
// TODO: are there any useful inter-type orderings?
148155
_ => None,
149156
}
@@ -239,7 +246,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
239246
ExprKind::Unary(op, ref operand) => self.expr(operand).and_then(|o| match op {
240247
UnOp::UnNot => self.constant_not(&o, self.typeck_results.expr_ty(e)),
241248
UnOp::UnNeg => self.constant_negate(&o, self.typeck_results.expr_ty(e)),
242-
UnOp::UnDeref => Some(o),
249+
UnOp::UnDeref => Some(if let Constant::Ref(r) = o { *r } else { o }),
243250
}),
244251
ExprKind::Binary(op, ref left, ref right) => self.binop(op, left, right),
245252
ExprKind::Call(ref callee, ref args) => {
@@ -269,6 +276,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
269276
}
270277
},
271278
ExprKind::Index(ref arr, ref index) => self.index(arr, index),
279+
ExprKind::AddrOf(_, _, ref inner) => self.expr(inner).map(|r| Constant::Ref(Box::new(r))),
272280
// TODO: add other expressions.
273281
_ => None,
274282
}

tests/ui/float_cmp.rs

+5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#![allow(
33
unused,
44
clippy::no_effect,
5+
clippy::op_ref,
56
clippy::unnecessary_operation,
67
clippy::cast_lossless,
78
clippy::many_single_char_names
@@ -116,4 +117,8 @@ fn main() {
116117
1.23f64.signum() != x64.signum();
117118
1.23f64.signum() != -(x64.signum());
118119
1.23f64.signum() != 3.21f64.signum();
120+
121+
// the comparison should also look through references
122+
&0.0 == &ZERO;
123+
&&&&0.0 == &&&&ZERO;
119124
}

tests/ui/float_cmp.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: strict comparison of `f32` or `f64`
2-
--> $DIR/float_cmp.rs:65:5
2+
--> $DIR/float_cmp.rs:66:5
33
|
44
LL | ONE as f64 != 2.0;
55
| ^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(ONE as f64 - 2.0).abs() > error_margin`
@@ -8,39 +8,39 @@ LL | ONE as f64 != 2.0;
88
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
99

1010
error: strict comparison of `f32` or `f64`
11-
--> $DIR/float_cmp.rs:70:5
11+
--> $DIR/float_cmp.rs:71:5
1212
|
1313
LL | x == 1.0;
1414
| ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 1.0).abs() < error_margin`
1515
|
1616
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
1717

1818
error: strict comparison of `f32` or `f64`
19-
--> $DIR/float_cmp.rs:73:5
19+
--> $DIR/float_cmp.rs:74:5
2020
|
2121
LL | twice(x) != twice(ONE as f64);
2222
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(twice(x) - twice(ONE as f64)).abs() > error_margin`
2323
|
2424
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
2525

2626
error: strict comparison of `f32` or `f64`
27-
--> $DIR/float_cmp.rs:93:5
27+
--> $DIR/float_cmp.rs:94:5
2828
|
2929
LL | NON_ZERO_ARRAY[i] == NON_ZERO_ARRAY[j];
3030
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(NON_ZERO_ARRAY[i] - NON_ZERO_ARRAY[j]).abs() < error_margin`
3131
|
3232
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
3333

3434
error: strict comparison of `f32` or `f64` arrays
35-
--> $DIR/float_cmp.rs:98:5
35+
--> $DIR/float_cmp.rs:99:5
3636
|
3737
LL | a1 == a2;
3838
| ^^^^^^^^
3939
|
4040
= note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`
4141

4242
error: strict comparison of `f32` or `f64`
43-
--> $DIR/float_cmp.rs:99:5
43+
--> $DIR/float_cmp.rs:100:5
4444
|
4545
LL | a1[0] == a2[0];
4646
| ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(a1[0] - a2[0]).abs() < error_margin`

0 commit comments

Comments
 (0)