+22
-2
compiler-core/src/type_/expression.rs
+22
-2
compiler-core/src/type_/expression.rs
···
1609
1609
if let Err(error) = unify(left.type_(), right.type_()) {
1610
1610
self.problems
1611
1611
.error(convert_unify_error(error, right.location()));
1612
+
} else {
1613
+
// We only want to warn for redundant comparisons if it
1614
+
// makes sense to compare the two values.
1615
+
// That is, their types should match!
1616
+
self.check_for_redundant_comparison(name, &left, &right, location);
1612
1617
}
1613
1618
1614
1619
self.check_for_inefficient_empty_list_check(name, &left, &right, location);
1615
-
self.check_for_redundant_comparison(name, &left, &right, location);
1616
1620
1617
1621
return TypedExpr::BinOp {
1618
1622
location,
···
1650
1654
let unify_left = unify(input_type.clone(), left.type_());
1651
1655
let unify_right = unify(input_type.clone(), right.type_());
1652
1656
1657
+
if unify_left.is_ok() && unify_right.is_ok() {
1658
+
// We only want to warn for redundant comparisons if it makes sense
1659
+
// to compare the two values. That is, their types should match!
1660
+
self.check_for_redundant_comparison(name, &left, &right, location);
1661
+
}
1662
+
1653
1663
// There's some common cases in which we can provide nicer error messages:
1654
1664
// - if we're using a float operator on int values
1655
1665
// - if we're using an int operator on float values
···
1687
1697
}
1688
1698
1689
1699
self.check_for_inefficient_empty_list_check(name, &left, &right, location);
1690
-
self.check_for_redundant_comparison(name, &left, &right, location);
1691
1700
1692
1701
TypedExpr::BinOp {
1693
1702
location,
···
5048
5057
}
5049
5058
},
5050
5059
5060
+
// If we're building two variants with a different index then we can
5061
+
// tell for sure they're going to be different.
5062
+
(one, other)
5063
+
if one
5064
+
.variant_index()
5065
+
.is_some_and(|one| other.variant_index().is_some_and(|other| one != other)) =>
5066
+
{
5067
+
StaticComparison::CertainlyDifferent
5068
+
}
5069
+
5051
5070
(
5052
5071
TypedExpr::RecordAccess {
5053
5072
index: index_one,
···
5071
5090
// TODO: For complex expressions we just give up, maybe in future we
5072
5091
// could be smarter and perform further comparisons but it sounds like
5073
5092
// there's no huge value in this.
5093
+
//
5074
5094
(_, _) => StaticComparison::CantTell,
5075
5095
}
5076
5096
}
+24
compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__warnings__different_records_1_redundant_comparison.snap
+24
compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__warnings__different_records_1_redundant_comparison.snap
···
1
+
---
2
+
source: compiler-core/src/type_/tests/warnings.rs
3
+
expression: "\npub type Either {\n Left(Int)\n Right\n}\n\npub fn main() -> Bool {\n Left(1) == Right\n}\n"
4
+
---
5
+
----- SOURCE CODE
6
+
7
+
pub type Either {
8
+
Left(Int)
9
+
Right
10
+
}
11
+
12
+
pub fn main() -> Bool {
13
+
Left(1) == Right
14
+
}
15
+
16
+
17
+
----- WARNING
18
+
warning: Redundant comparison
19
+
┌─ /src/warning/wrn.gleam:8:3
20
+
│
21
+
8 │ Left(1) == Right
22
+
│ ^^^^^^^^^^^^^^^^ This is always `False`
23
+
24
+
This comparison is redundant since it always fails.
+24
compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__warnings__different_records_3_redundant_comparison.snap
+24
compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__warnings__different_records_3_redundant_comparison.snap
···
1
+
---
2
+
source: compiler-core/src/type_/tests/warnings.rs
3
+
expression: "\npub type Either {\n Left\n Right(Int)\n}\n\npub fn main() -> Bool {\n Left == Right(1)\n}\n"
4
+
---
5
+
----- SOURCE CODE
6
+
7
+
pub type Either {
8
+
Left
9
+
Right(Int)
10
+
}
11
+
12
+
pub fn main() -> Bool {
13
+
Left == Right(1)
14
+
}
15
+
16
+
17
+
----- WARNING
18
+
warning: Redundant comparison
19
+
┌─ /src/warning/wrn.gleam:8:3
20
+
│
21
+
8 │ Left == Right(1)
22
+
│ ^^^^^^^^^^^^^^^^ This is always `False`
23
+
24
+
This comparison is redundant since it always fails.
+16
compiler-core/src/type_/tests/warnings.rs
+16
compiler-core/src/type_/tests/warnings.rs
···
4173
4173
"
4174
4174
);
4175
4175
}
4176
+
4177
+
#[test]
4178
+
fn different_records_3_redundant_comparison() {
4179
+
assert_warning!(
4180
+
"
4181
+
pub type Either {
4182
+
Left
4183
+
Right(Int)
4184
+
}
4185
+
4186
+
pub fn main() -> Bool {
4187
+
Left == Right(1)
4188
+
}
4189
+
"
4190
+
);
4191
+
}