diff options
| author | tslil <tslil@posteo.de> | 2026-05-06 14:27:43 +0100 |
|---|---|---|
| committer | tslil <tslil@posteo.de> | 2026-05-06 20:40:27 +0100 |
| commit | d682ad6bbb5547ffbcc19da90275ff43e4e03e20 (patch) | |
| tree | 43dc3bb60d0f65793e3a17fcf867ece0ff09ab8b /src/checker_set.rs | |
| parent | 1b4abb8fdd81f6de2166ef3f064a77fd5622fe83 (diff) | |
WiP
Diffstat (limited to 'src/checker_set.rs')
| -rw-r--r-- | src/checker_set.rs | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/src/checker_set.rs b/src/checker_set.rs index a00ea81..1a89631 100644 --- a/src/checker_set.rs +++ b/src/checker_set.rs @@ -230,7 +230,7 @@ impl CheckerState { .element; Ok(sub_element) } - _ => panic!( + Element::Inject { .. } | Element::Literal(_) => panic!( "invariant violation: check_element returned neither a record or stuck computation for record set" ), } @@ -312,7 +312,6 @@ impl CheckerState { let scrutinee = self.check_element(scrutinee, owner)?; // which variant are we, if any - let matching: Option<(String, Element)> = match scrutinee { Element::Inject { ref field, @@ -326,6 +325,18 @@ impl CheckerState { ), }; + // are we allowed to posit the equality of elements scrutinee = + // (arm.tag). (arm.bound) when looking at necessarily + // non-matching arms? + let posit_equality_with = match &scrutinee { + Element::Var(v) => Some(v.clone()), + Element::Inject { .. } + | Element::Project { .. } + | Element::Case { .. } + | Element::Literal(_) + | Element::Record(_) => None, + }; + // for each arm, recurse with a concrete value (if we have one) // otherwise fall back to hypothetical elements; in the former // case record the end result @@ -333,7 +344,8 @@ impl CheckerState { let mut processed_arms = Vec::new(); for arm in arms { let OwnedField { - field: field_set, .. + field: field_set, + owner, } = self.lookup_variant_field(&arm.tag)?; let mut ctx = self.clone(); @@ -345,7 +357,9 @@ impl CheckerState { { let canonical = ctx.make_element_definition(binding_name, inner.clone(), binding_set)?; - let output = ctx.check_element((&arm.body).into(), set)?; + let this_set = ctx.check_set(set)?; + + let output = ctx.check_element((&arm.body).into(), &this_set)?; if matches!(computed_output, Some(_)) { panic!( "invariant violation: we somehow matched multiple arms in case analysis" @@ -359,7 +373,20 @@ impl CheckerState { } } else { let canonical = ctx.make_element_binding(binding_name, binding_set)?; - let body = ctx.check_element((&arm.body).into(), set)?; + + if let Some(ref scrutinee_var) = posit_equality_with { + ctx.make_element_definition( + scrutinee_var.clone(), + Element::Inject { + field: arm.tag.clone(), + element: Box::new(Element::Var(canonical.clone())), + }, + owner.clone(), + )?; + }; + let this_set = ctx.check_set(set)?; + let body = ctx.check_element((&arm.body).into(), &this_set)?; + CaseArm { tag: arm.tag.clone(), bound: canonical, |
