Revert 'unify' implementation back to its more elegant form

And add support for Pair.
This commit is contained in:
KtorZ 2024-04-03 11:58:11 +02:00 committed by Kasey
parent cbf3ef2854
commit 3020af7cd7
1 changed files with 80 additions and 136 deletions

View File

@ -1495,7 +1495,8 @@ impl<'a> Environment<'a> {
.map_err(|e| e.flip_unify()); .map_err(|e| e.flip_unify());
} }
match lhs.deref() { match (lhs.deref(), rhs.deref()) {
(
Type::App { Type::App {
module: m1, module: m1,
name: n1, name: n1,
@ -1503,17 +1504,16 @@ impl<'a> Environment<'a> {
public: _, public: _,
contains_opaque: _, contains_opaque: _,
alias: _, alias: _,
} => { },
if let Type::App { Type::App {
module: m2, module: m2,
name: n2, name: n2,
args: args2, args: args2,
public: _, public: _,
contains_opaque: _, contains_opaque: _,
alias: _, alias: _,
} = rhs.deref() },
{ ) if m1 == m2 && n1 == n2 && args1.len() == args2.len() => {
if m1 == m2 && n1 == n2 && args1.len() == args2.len() {
for (a, b) in args1.iter().zip(args2) { for (a, b) in args1.iter().zip(args2) {
unify_enclosed_type( unify_enclosed_type(
lhs.clone(), lhs.clone(),
@ -1522,36 +1522,18 @@ impl<'a> Environment<'a> {
)?; )?;
} }
Ok(()) Ok(())
} else {
Err(Error::CouldNotUnify {
location,
expected: lhs.clone(),
given: rhs.clone(),
situation: None,
rigid_type_names: HashMap::new(),
})
}
} else {
Err(Error::CouldNotUnify {
location,
expected: lhs.clone(),
given: rhs.clone(),
situation: None,
rigid_type_names: HashMap::new(),
})
}
} }
(
Type::Tuple { Type::Tuple {
elems: elems1, elems: elems1,
alias: _, alias: _,
} => { },
if let Type::Tuple { Type::Tuple {
elems: elems2, elems: elems2,
alias: _, alias: _,
} = rhs.deref() },
{ ) if elems1.len() == elems2.len() => {
if elems1.len() == elems2.len() {
for (a, b) in elems1.iter().zip(elems2) { for (a, b) in elems1.iter().zip(elems2) {
unify_enclosed_type( unify_enclosed_type(
lhs.clone(), lhs.clone(),
@ -1560,38 +1542,42 @@ impl<'a> Environment<'a> {
)?; )?;
} }
Ok(()) Ok(())
} else {
Err(Error::CouldNotUnify {
location,
expected: lhs.clone(),
given: rhs.clone(),
situation: None,
rigid_type_names: HashMap::new(),
})
}
} else {
Err(Error::CouldNotUnify {
location,
expected: lhs.clone(),
given: rhs.clone(),
situation: None,
rigid_type_names: HashMap::new(),
})
}
} }
(
Type::Pair {
fst: lhs_fst,
snd: lhs_snd,
alias: _,
},
Type::Pair {
fst: rhs_fst,
snd: rhs_snd,
alias: _,
},
) => {
for (a, b) in [lhs_fst, lhs_snd].into_iter().zip([rhs_fst, rhs_snd]) {
unify_enclosed_type(
lhs.clone(),
rhs.clone(),
self.unify(a.clone(), b.clone(), location, false),
)?;
}
Ok(())
}
(
Type::Fn { Type::Fn {
args: args1, args: args1,
ret: retrn1, ret: retrn1,
alias: _, alias: _,
} => { },
if let Type::Fn { Type::Fn {
args: args2, args: args2,
ret: retrn2, ret: retrn2,
alias: _, alias: _,
} = rhs.deref() },
{ ) if args1.len() == args2.len() => {
if args1.len() == args2.len() {
for (a, b) in args1.iter().zip(args2) { for (a, b) in args1.iter().zip(args2) {
self.unify(a.clone(), b.clone(), location, allow_cast) self.unify(a.clone(), b.clone(), location, allow_cast)
.map_err(|_| Error::CouldNotUnify { .map_err(|_| Error::CouldNotUnify {
@ -1610,57 +1596,15 @@ impl<'a> Environment<'a> {
situation: None, situation: None,
rigid_type_names: HashMap::new(), rigid_type_names: HashMap::new(),
}) })
} else { }
Err(Error::CouldNotUnify {
_ => Err(Error::CouldNotUnify {
location, location,
expected: lhs.clone(), expected: lhs.clone(),
given: rhs.clone(), given: rhs.clone(),
situation: None, situation: None,
rigid_type_names: HashMap::new(), rigid_type_names: HashMap::new(),
}) }),
}
} else {
Err(Error::CouldNotUnify {
location,
expected: lhs.clone(),
given: rhs.clone(),
situation: None,
rigid_type_names: HashMap::new(),
})
}
}
Type::Pair { fst, snd, alias: _ } => {
if let Type::Pair {
fst: fst2,
snd: snd2,
alias: _,
} = rhs.deref()
{
unify_enclosed_type(
lhs.clone(),
rhs.clone(),
self.unify(fst.clone(), fst2.clone(), location, false),
)?;
unify_enclosed_type(
lhs.clone(),
rhs.clone(),
self.unify(snd.clone(), snd2.clone(), location, false),
)?;
Ok(())
} else {
Err(Error::CouldNotUnify {
location,
expected: lhs.clone(),
given: rhs.clone(),
situation: None,
rigid_type_names: HashMap::new(),
})
}
}
Type::Var { .. } => unreachable!(),
} }
} }