⭐️ A friendly language for building type-safe, scalable systems!

fix all tests, for real this time

authored by giacomocavalieri.me and committed by Louis Pilfold e2f9c59e 57e87d35

+22 -2
compiler-core/src/type_/expression.rs
··· 1609 if let Err(error) = unify(left.type_(), right.type_()) { 1610 self.problems 1611 .error(convert_unify_error(error, right.location())); 1612 } 1613 1614 self.check_for_inefficient_empty_list_check(name, &left, &right, location); 1615 - self.check_for_redundant_comparison(name, &left, &right, location); 1616 1617 return TypedExpr::BinOp { 1618 location, ··· 1650 let unify_left = unify(input_type.clone(), left.type_()); 1651 let unify_right = unify(input_type.clone(), right.type_()); 1652 1653 // There's some common cases in which we can provide nicer error messages: 1654 // - if we're using a float operator on int values 1655 // - if we're using an int operator on float values ··· 1687 } 1688 1689 self.check_for_inefficient_empty_list_check(name, &left, &right, location); 1690 - self.check_for_redundant_comparison(name, &left, &right, location); 1691 1692 TypedExpr::BinOp { 1693 location, ··· 5048 } 5049 }, 5050 5051 ( 5052 TypedExpr::RecordAccess { 5053 index: index_one, ··· 5071 // TODO: For complex expressions we just give up, maybe in future we 5072 // could be smarter and perform further comparisons but it sounds like 5073 // there's no huge value in this. 5074 (_, _) => StaticComparison::CantTell, 5075 } 5076 }
··· 1609 if let Err(error) = unify(left.type_(), right.type_()) { 1610 self.problems 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); 1617 } 1618 1619 self.check_for_inefficient_empty_list_check(name, &left, &right, location); 1620 1621 return TypedExpr::BinOp { 1622 location, ··· 1654 let unify_left = unify(input_type.clone(), left.type_()); 1655 let unify_right = unify(input_type.clone(), right.type_()); 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 + 1663 // There's some common cases in which we can provide nicer error messages: 1664 // - if we're using a float operator on int values 1665 // - if we're using an int operator on float values ··· 1697 } 1698 1699 self.check_for_inefficient_empty_list_check(name, &left, &right, location); 1700 1701 TypedExpr::BinOp { 1702 location, ··· 5057 } 5058 }, 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 + 5070 ( 5071 TypedExpr::RecordAccess { 5072 index: index_one, ··· 5090 // TODO: For complex expressions we just give up, maybe in future we 5091 // could be smarter and perform further comparisons but it sounds like 5092 // there's no huge value in this. 5093 + // 5094 (_, _) => StaticComparison::CantTell, 5095 } 5096 }
+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
···
··· 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
··· 4173 " 4174 ); 4175 }
··· 4173 " 4174 ); 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 + }