Skip to content

Commit 1293ed7

Browse files
committed
wip: add tests for Inferred unification
1 parent 047d465 commit 1293ed7

1 file changed

Lines changed: 77 additions & 2 deletions

File tree

src/passes/thir_gen/unification_table.rs

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)