Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve type constructors in the types of constructor fields #728

Merged
merged 1 commit into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/fun/check/type_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ impl Ctx<'_> {
type ProgramTypes = HashMap<Name, Scheme>;

/// A type scheme, aka a polymorphic type.
#[derive(Clone)]
#[derive(Clone, Debug)]
struct Scheme(Vec<Name>, Type);

/// A finite mapping from type variables to types.
#[derive(Clone, Default)]
#[derive(Clone, Default, Debug)]
struct Subst(BTreeMap<Name, Type>);

/// A mapping from term variables to type schemes.
#[derive(Clone, Default)]
#[derive(Clone, Default, Debug)]
struct TypeEnv(BTreeMap<Name, Scheme>);

/// Variable generator for type variables.
Expand Down
16 changes: 8 additions & 8 deletions src/fun/net_to_term.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,29 +440,29 @@ impl Reader<'_> {
return Term::Err;
}

let zero_term = self.read_term(self.net.enter_port(Port(sel_node, 1)));
let mut succ_term = self.read_term(self.net.enter_port(Port(sel_node, 2)));
let zero = self.read_term(self.net.enter_port(Port(sel_node, 1)));
let mut succ = self.read_term(self.net.enter_port(Port(sel_node, 2)));
// Call expand_generated in case of succ_term be a lifted term
succ_term.expand_generated(self.book, self.recursive_defs);
succ.expand_generated(self.book, self.recursive_defs);

// Succ term should be a lambda
let (zero, succ) = match &mut succ_term {
let succ = match &mut succ {
Term::Lam { pat, bod, .. } => {
if let Pattern::Var(nam) = pat.as_ref() {
let mut bod = std::mem::take(bod.as_mut());
if let Some(nam) = nam {
bod.subst(nam, &Term::Var { nam: Name::new(format!("{bnd}-1")) });
}
(zero_term, bod)
bod
} else {
// Readback should never generate non-var patterns for lambdas.
self.error(ReadbackError::InvalidNumericMatch);
(zero_term, succ_term)
succ
}
}
_ => {
self.error(ReadbackError::InvalidNumericMatch);
(zero_term, succ_term)
succ
}
};
Term::Swt {
Expand Down Expand Up @@ -562,7 +562,7 @@ impl Reader<'_> {
/// Returns whether the given port represents a tuple or some other
/// term (usually a lambda).
///
/// Used heuristic: a con node is a tuple if port 1 is a closed net and not an ERA.
/// Used heuristic: a con node is a tuple if port 1 is a closed tree and not an ERA.
fn is_tup(&self, node: NodeId) -> bool {
if !matches!(self.net.node(node).kind, NodeKind::Ctr(CtrKind::Con(_))) {
return false;
Expand Down
4 changes: 4 additions & 0 deletions src/fun/transform/resolve_type_ctrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ impl Ctx<'_> {
for ctr in adt.ctrs.values_mut() {
let res = ctr.typ.resolve_type_ctrs(&adts);
self.info.take_rule_err(res, ctr.name.clone());
for field in ctr.fields.iter_mut() {
let res = field.typ.resolve_type_ctrs(&adts);
self.info.take_rule_err(res, ctr.name.clone());
}
}
}

Expand Down
12 changes: 12 additions & 0 deletions tests/golden_tests/desugar_file/fail_type_bad_rec_fn_adt.bend
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Should give a type error in Erase when unifying the field of type Unit with the match type of Box
type Box:
Box {x: Unit}

type Unit:
Unit

Erase: Box -> None
(Erase (Box/Box x)) = (Erase x)

main: None
main = (Erase (Box/Box Unit/Unit))
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
source: tests/golden_tests.rs
input_file: tests/golden_tests/desugar_file/fail_type_bad_rec_fn_adt.bend
---
Errors:
In λa match a { Box/Box b: (Erase b); }:
Can't unify '(Unit -> d)' and '(Box -> d)'.
Loading