diff --git a/compiler/solve/src/solve.rs b/compiler/solve/src/solve.rs index 4a57c10378..7179caac90 100644 --- a/compiler/solve/src/solve.rs +++ b/compiler/solve/src/solve.rs @@ -1319,10 +1319,8 @@ fn check_ability_specialization( .filter(|mia| mia.ability == root_data.parent_ability) .collect::>(); ability_implementations_for_specialization.dedup(); - debug_assert_eq!( - ability_implementations_for_specialization.len(), 1, - "If there's more than one, the definition is ambiguous - this should be an error" - ); + + debug_assert!(ability_implementations_for_specialization.len() == 1, "Multiple variables bound to an ability - this is ambiguous and should have been caught in canonicalization"); // This is a valid specialization! Record it. let specialization_type = ability_implementations_for_specialization[0].typ; diff --git a/reporting/tests/test_reporting.rs b/reporting/tests/test_reporting.rs index d544e1cb64..a8d1b8a32a 100644 --- a/reporting/tests/test_reporting.rs +++ b/reporting/tests/test_reporting.rs @@ -9577,4 +9577,46 @@ I need all branches in an `if` to have the same type! ), ) } + + #[test] + fn ability_specialization_conflicting_specialization_types() { + new_report_problem_as( + indoc!( + r#" + app "test" provides [ eq ] to "./platform" + + Eq has + eq : a, a -> Bool | a has Eq + + You := {} + AndI := {} + + eq = \$You {}, $AndI {} -> False + "# + ), + indoc!( + r#" + ── TYPE MISMATCH ─────────────────────────────────────────────────────────────── + + Something is off with this specialization of `eq`: + + 9│ eq = \$You {}, $AndI {} -> False + ^^ + + This value is a declared specialization of type: + + You, AndI -> [ False, True ] + + But the type annotation on `eq` says it must match: + + You, You -> Bool + + Tip: Type comparisons between an opaque type are only ever equal if + both types are the same opaque type. Did you mean to create an opaque + type by wrapping it? If I have an opaque type Age := U32 I can create + an instance of this opaque type by doing @Age 23. + "# + ), + ) + } }