@@ -28,7 +28,10 @@ pub enum Solution {
2828 ) ]
2929 SignedInteger ,
3030 /// An error.
31- #[ expect( dead_code, reason = "error may be used in the future" ) ]
31+ #[ cfg_attr(
32+ not( test) ,
33+ expect( dead_code, reason = "error may be used in the future" )
34+ ) ]
3235 Error ,
3336}
3437
@@ -244,12 +247,51 @@ impl UnificationTable {
244247 ) ;
245248 rhs
246249 }
247- // Both sides are some kind of integer.
248- ( ( lhs, kind @ Solution :: AnyInteger ) , ( rhs, Solution :: AnyInteger ) )
249- | ( ( lhs, kind @ Solution :: UnsignedInteger ) , ( rhs, Solution :: UnsignedInteger ) ) => {
250- let kind = kind. clone ( ) ;
251- assert_eq ! ( self . set. redirect( lhs, rhs) . expect( "different nodes" ) , kind) ;
252- rhs
250+
251+ (
252+ (
253+ integer,
254+ kind @ ( Solution :: AnyInteger
255+ | Solution :: SignedInteger
256+ | Solution :: UnsignedInteger ) ,
257+ ) ,
258+ ( other, solution) ,
259+ )
260+ | (
261+ ( other, solution) ,
262+ (
263+ integer,
264+ kind @ ( Solution :: AnyInteger
265+ | Solution :: SignedInteger
266+ | Solution :: UnsignedInteger ) ,
267+ ) ,
268+ ) => {
269+ assert ! (
270+ matches!(
271+ solution,
272+ Solution :: AnyInteger | Solution :: UnsignedInteger | Solution :: SignedInteger
273+ ) ,
274+ "cannot unify an integer with a non-integer"
275+ ) ;
276+
277+ match ( kind, solution) {
278+ ( Solution :: AnyInteger , _) => {
279+ assert_eq ! (
280+ self . set. redirect( integer, other) . expect( "different nodes" ) ,
281+ Solution :: AnyInteger ,
282+ ) ;
283+ other
284+ }
285+ ( lhs, rhs) if lhs == rhs => {
286+ let lhs = lhs. clone ( ) ;
287+ assert_eq ! (
288+ self . set. redirect( integer, other) . expect( "different nodes" ) ,
289+ lhs,
290+ ) ;
291+ other
292+ }
293+ _ => panic ! ( "cannot merge incompatible integers" ) ,
294+ }
253295 }
254296 _ => {
255297 todo ! ( )
@@ -494,4 +536,44 @@ mod test {
494536 table. unify ( & types, lhs, rhs) ;
495537 }
496538 }
539+
540+ #[ rstest]
541+ #[ case:: both_any( Solution :: AnyInteger , Solution :: AnyInteger , Solution :: AnyInteger ) ]
542+ #[ case:: both_signed(
543+ Solution :: SignedInteger ,
544+ Solution :: SignedInteger ,
545+ Solution :: SignedInteger
546+ ) ]
547+ #[ case:: both_unsigned(
548+ Solution :: UnsignedInteger ,
549+ Solution :: UnsignedInteger ,
550+ Solution :: UnsignedInteger
551+ ) ]
552+ #[ case:: any_and_signed( Solution :: AnyInteger , Solution :: SignedInteger , Solution :: SignedInteger ) ]
553+ #[ case:: any_and_unsigned(
554+ Solution :: AnyInteger ,
555+ Solution :: UnsignedInteger ,
556+ Solution :: UnsignedInteger
557+ ) ]
558+ #[ should_panic( expected = "cannot merge incompatible integers" ) ]
559+ #[ case:: signed_and_unsigned(
560+ Solution :: SignedInteger ,
561+ Solution :: UnsignedInteger ,
562+ // NOTE: Outcome doesn't matter as it will panic.
563+ Solution :: Error
564+ ) ]
565+ fn integer (
566+ mut table : UnificationTable ,
567+ types : Types ,
568+ #[ case] lhs : Solution ,
569+ #[ case] rhs : Solution ,
570+ #[ case] outcome : Solution ,
571+ ) {
572+ let lhs = table. set . insert ( lhs) ;
573+ let rhs = table. set . insert ( rhs) ;
574+
575+ let result = table. unify ( & types, lhs, rhs) ;
576+
577+ assert_eq ! ( table. get( result) , & outcome) ;
578+ }
497579}
0 commit comments