@@ -222,14 +222,18 @@ impl UnificationTable {
222222 }
223223
224224 // Type mismatches.
225- _ => todo ! ( ) ,
225+ _ => panic ! ( "cannot merge mismatched inferred types" ) ,
226226 } ;
227227
228228 // Used later for assertion.
229229 let inferred_lhs = inferred_lhs. clone ( ) ;
230230
231231 // Merge the fields together.
232- assert_eq ! ( lhs_fields. len( ) , rhs_fields. len( ) ) ;
232+ assert_eq ! (
233+ lhs_fields. len( ) ,
234+ rhs_fields. len( ) ,
235+ "cannot merge inferred types of different sizes"
236+ ) ;
233237 for ( lhs, rhs) in lhs_fields. into_iter ( ) . zip ( rhs_fields. into_iter ( ) ) {
234238 self . unify ( types, lhs, rhs) ;
235239 }
@@ -419,4 +423,75 @@ mod test {
419423 assert_eq ! ( table. get( result) , & Solution :: Concrete ( ty) ) ;
420424 }
421425 }
426+
427+ mod inferred {
428+ use super :: * ;
429+
430+ #[ rstest]
431+ #[ case:: reference( |solutions: [ _; 1 ] | CompositeType :: Ref ( solutions[ 0 ] ) ) ]
432+ #[ case:: function_no_parameters( |solutions: [ _; 1 ] | CompositeType :: Function { parameters: vec![ ] , return_ty: solutions[ 0 ] } ) ]
433+ #[ case:: function_one_parameter( |solutions: [ _; 2 ] | CompositeType :: Function { parameters: vec![ solutions[ 0 ] ] , return_ty: solutions[ 1 ] } ) ]
434+ #[ case:: function_many_parameters( |solutions: [ _; 4 ] | CompositeType :: Function { parameters: vec![ solutions[ 0 ] , solutions[ 1 ] , solutions[ 2 ] ] , return_ty: solutions[ 3 ] } ) ]
435+ #[ case:: tuple_empty( |_: [ _; 0 ] | CompositeType :: Tuple ( vec![ ] ) ) ]
436+ #[ case:: tuple_one( |solutions: [ _; 1 ] | CompositeType :: Tuple ( Vec :: from_iter( solutions) ) ) ]
437+ #[ case:: tuple_many( |solutions: [ _; 4 ] | CompositeType :: Tuple ( Vec :: from_iter( solutions) ) ) ]
438+ fn matching < const N : usize > (
439+ mut table : UnificationTable ,
440+ types : Types ,
441+ #[ case] get_inferred : impl Fn ( [ SolutionId ; N ] ) -> CompositeType < SolutionId > ,
442+ ) {
443+ let [ lhs_unknowns, rhs_unknowns] = std:: array:: from_fn ( |_| {
444+ std:: array:: from_fn ( |_| table. set . insert ( Solution :: Unknown ) )
445+ } ) ;
446+
447+ let lhs = table
448+ . set
449+ . insert ( Solution :: Inferred ( get_inferred ( lhs_unknowns) ) ) ;
450+ let rhs = table
451+ . set
452+ . insert ( Solution :: Inferred ( get_inferred ( rhs_unknowns) ) ) ;
453+
454+ let result = table. unify ( & types, lhs, rhs) ;
455+
456+ // Unknowns should be merged.
457+ for ( lhs, rhs) in lhs_unknowns. iter ( ) . zip ( rhs_unknowns. iter ( ) ) {
458+ assert_eq ! ( table. set. find_root( * lhs) , table. set. find_root( * rhs) ) ;
459+ }
460+
461+ // Result should be inferred based on merged unknown components.
462+ let expected = get_inferred ( lhs_unknowns. map ( |unknown| table. set . find_root ( unknown) ) ) ;
463+ assert_eq ! ( table. get( result) , & Solution :: Inferred ( expected) ) ;
464+ }
465+
466+ #[ rstest]
467+ #[ should_panic( expected = "cannot merge mismatched inferred types" ) ]
468+ #[ case:: reference_and_function(
469+ |solutions: [ _; 1 ] | CompositeType :: Ref ( solutions[ 0 ] ) ,
470+ |solutions: [ _; 1 ] | CompositeType :: Function { parameters: vec![ ] , return_ty: solutions[ 0 ] } ,
471+ ) ]
472+ #[ should_panic( expected = "cannot merge inferred types of different sizes" ) ]
473+ #[ case:: function_different_parameters(
474+ |solutions: [ _; 1 ] | CompositeType :: Function { parameters: vec![ ] , return_ty: solutions[ 0 ] } ,
475+ |solutions: [ _; 3 ] | CompositeType :: Function { parameters: vec![ solutions[ 0 ] , solutions[ 1 ] ] , return_ty: solutions[ 2 ] } ,
476+ ) ]
477+ #[ should_panic( expected = "cannot merge inferred types of different sizes" ) ]
478+ #[ case:: tuple_different_sizes(
479+ |solutions: [ _; 1 ] | CompositeType :: Tuple ( Vec :: from_iter( solutions) ) ,
480+ |solutions: [ _; 3 ] | CompositeType :: Tuple ( Vec :: from_iter( solutions) ) ,
481+ ) ]
482+ fn mismatched < const N : usize , const M : usize > (
483+ mut table : UnificationTable ,
484+ types : Types ,
485+ #[ case] get_lhs : impl Fn ( [ SolutionId ; N ] ) -> CompositeType < SolutionId > ,
486+ #[ case] get_rhs : impl Fn ( [ SolutionId ; M ] ) -> CompositeType < SolutionId > ,
487+ ) {
488+ let lhs_unknowns = std:: array:: from_fn ( |_| table. set . insert ( Solution :: Unknown ) ) ;
489+ let rhs_unknowns = std:: array:: from_fn ( |_| table. set . insert ( Solution :: Unknown ) ) ;
490+
491+ let lhs = table. set . insert ( Solution :: Inferred ( get_lhs ( lhs_unknowns) ) ) ;
492+ let rhs = table. set . insert ( Solution :: Inferred ( get_rhs ( rhs_unknowns) ) ) ;
493+
494+ table. unify ( & types, lhs, rhs) ;
495+ }
496+ }
422497}
0 commit comments