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,172 +1495,116 @@ 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 { (
module: m1, Type::App {
name: n1, module: m1,
args: args1, name: n1,
public: _, args: args1,
contains_opaque: _, public: _,
alias: _, contains_opaque: _,
} => { 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(), rhs.clone(),
rhs.clone(), self.unify(a.clone(), b.clone(), location, false),
self.unify(a.clone(), b.clone(), location, false), )?;
)?;
}
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(),
})
} }
Ok(())
} }
Type::Tuple { (
elems: elems1, Type::Tuple {
alias: _, elems: elems1,
} => { 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(), rhs.clone(),
rhs.clone(), self.unify(a.clone(), b.clone(), location, false),
self.unify(a.clone(), b.clone(), location, false), )?;
)?;
}
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(),
})
} }
Ok(())
} }
Type::Fn { (
args: args1, Type::Pair {
ret: retrn1, fst: lhs_fst,
alias: _, snd: lhs_snd,
} => { alias: _,
if let Type::Fn { },
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 {
args: args1,
ret: retrn1,
alias: _,
},
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 {
location,
expected: lhs.clone(),
given: rhs.clone(),
situation: None,
rigid_type_names: HashMap::new(),
})?;
}
self.unify(retrn1.clone(), retrn2.clone(), location, false)
.map_err(|_| Error::CouldNotUnify {
location,
expected: lhs.clone(),
given: rhs.clone(),
situation: None,
rigid_type_names: HashMap::new(),
})
} else {
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 { self.unify(retrn1.clone(), retrn2.clone(), location, false)
Err(Error::CouldNotUnify { .map_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(),
}) })
}
}
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!(), _ => Err(Error::CouldNotUnify {
location,
expected: lhs.clone(),
given: rhs.clone(),
situation: None,
rigid_type_names: HashMap::new(),
}),
} }
} }