From 9f4d0fc4f2cf811311c8ff8cce7241feed5ff005 Mon Sep 17 00:00:00 2001 From: Felipe705x Date: Sun, 19 Apr 2026 19:13:18 -0400 Subject: [PATCH 1/3] fix: some property test failures --- src/ast/descriptor.rs | 1 + src/ast/label.rs | 3 +++ src/ast/types.rs | 2 +- src/typechecker/variable_type.rs | 5 +++-- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/ast/descriptor.rs b/src/ast/descriptor.rs index 509f370..082f3dc 100644 --- a/src/ast/descriptor.rs +++ b/src/ast/descriptor.rs @@ -228,6 +228,7 @@ impl PropertyType { /// Open types allow extra keys; closed types must match exactly. pub fn is_subtype(t1: &PropertyType, t2: &PropertyType) -> bool { match (t1, t2) { + (PropertyType::Zero, _) => true, (PropertyType::Open(_), PropertyType::Open(_)) => { // Check common keys t1.keys() diff --git a/src/ast/label.rs b/src/ast/label.rs index a319d55..cd6ac7e 100644 --- a/src/ast/label.rs +++ b/src/ast/label.rs @@ -50,6 +50,9 @@ impl LabelType { (LabelType::And(left, right), _) => { LabelType::is_subtype(left, l2) || LabelType::is_subtype(right, l2) } + (LabelType::Or(left, right), _) => { + LabelType::is_subtype(left, l2) && LabelType::is_subtype(right, l2) + } (_, LabelType::Or(left, right)) => { LabelType::is_subtype(l1, left) || LabelType::is_subtype(l1, right) } diff --git a/src/ast/types.rs b/src/ast/types.rs index 2147cc8..7ac9e78 100644 --- a/src/ast/types.rs +++ b/src/ast/types.rs @@ -61,7 +61,7 @@ impl SimpleType { pub fn is_subtype(t1: &SimpleType, t2: &SimpleType) -> bool { match (t1, t2) { (SimpleType::Star, _) | (_, SimpleType::Star) => true, - (_, SimpleType::Zero) => true, + (SimpleType::Zero, _) => true, (SimpleType::Union(t1a, t1b), _) => { SimpleType::is_subtype(t1a, t2) && SimpleType::is_subtype(t1b, t2) } diff --git a/src/typechecker/variable_type.rs b/src/typechecker/variable_type.rs index 9bab96c..80b8033 100644 --- a/src/typechecker/variable_type.rs +++ b/src/typechecker/variable_type.rs @@ -216,6 +216,7 @@ impl VariableType { /// General meet operator (greatest lower bound). pub fn meet(a: &VariableType, b: &VariableType) -> Result { match (a, b) { + (VariableType::Zero, _) | (_, VariableType::Zero) => Ok(VariableType::Zero), (VariableType::List(inner_a), VariableType::List(inner_b)) => Ok(VariableType::List( Box::new(VariableType::meet(inner_a, inner_b)?), )), @@ -227,14 +228,13 @@ impl VariableType { let r1 = VariableType::meet(t1, b); let r2 = VariableType::meet(t2, b); match (r1, r2) { - (Ok(v1), Ok(v2)) => Ok(VariableType::Union(Box::new(v1), Box::new(v2))), + (Ok(v1), Ok(v2)) => Ok(VariableType::join(v1, v2)), (Ok(v1), Err(_)) => Ok(v1), (Err(_), Ok(v2)) => Ok(v2), (Err(e1), Err(_)) => Err(e1), } } (_, VariableType::Union(_, _)) => VariableType::meet(b, a), - (VariableType::Zero, _) | (_, VariableType::Zero) => Ok(VariableType::Zero), _ => Err(format!( "Meet undefined between variable types {:?} and {:?}", a, b @@ -263,6 +263,7 @@ impl VariableType { /// Checks if t1 is a subtype of t2. pub fn is_subtype(t1: &VariableType, t2: &VariableType) -> bool { match (t1, t2) { + (VariableType::Zero, _) => true, (VariableType::Node(n1), VariableType::Node(n2)) => { DescriptorType::is_subtype(&n1.0, &n2.0) } From 9fb5f1fb0391b384477e642203c16f42d74e3afc Mon Sep 17 00:00:00 2001 From: Felipe705x Date: Sun, 19 Apr 2026 19:56:58 -0400 Subject: [PATCH 2/3] fix(simple-type): drop gradual_eq, use == / meet!=Zero (GQL 55170573) Made-with: Cursor --- src/ast/types.rs | 19 ++----------------- src/typechecker/checker.rs | 6 +++--- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/src/ast/types.rs b/src/ast/types.rs index 7ac9e78..b8e7b26 100644 --- a/src/ast/types.rs +++ b/src/ast/types.rs @@ -36,26 +36,11 @@ impl SimpleType { let meet2 = SimpleType::meet(a, t2); SimpleType::union(&meet1, &meet2) } - _ if SimpleType::gradual_eq(a, b) => a.clone(), + _ if a == b => a.clone(), _ => SimpleType::Zero, // Incompatible types } } - /// Returns true if t1 and t2 are considered equal under the gradual type system. - /// StarType is treated as equal to anything. - pub fn gradual_eq(t1: &SimpleType, t2: &SimpleType) -> bool { - match (t1, t2) { - (SimpleType::Star, _) | (_, SimpleType::Star) => true, - (SimpleType::Union(t1a, t1b), _) => { - SimpleType::gradual_eq(t1a, t2) || SimpleType::gradual_eq(t1b, t2) - } - (_, SimpleType::Union(t2a, t2b)) => { - SimpleType::gradual_eq(t1, t2a) || SimpleType::gradual_eq(t1, t2b) - } - _ => t1 == t2, - } - } - /// Returns true if t1 is a (gradual) subtype of t2. /// Used in type tests and type refinements. pub fn is_subtype(t1: &SimpleType, t2: &SimpleType) -> bool { @@ -63,7 +48,7 @@ impl SimpleType { (SimpleType::Star, _) | (_, SimpleType::Star) => true, (SimpleType::Zero, _) => true, (SimpleType::Union(t1a, t1b), _) => { - SimpleType::is_subtype(t1a, t2) && SimpleType::is_subtype(t1b, t2) + SimpleType::is_subtype(t1a, t2) || SimpleType::is_subtype(t1b, t2) } (_, SimpleType::Union(t2a, t2b)) => { SimpleType::is_subtype(t1, t2a) || SimpleType::is_subtype(t1, t2b) diff --git a/src/typechecker/checker.rs b/src/typechecker/checker.rs index 2902027..da0cffa 100644 --- a/src/typechecker/checker.rs +++ b/src/typechecker/checker.rs @@ -243,8 +243,8 @@ impl Typechecker { match Self::binop_delta(op) { Some((expected_t1, expected_t2, result_t)) => { - if SimpleType::gradual_eq(&t1, &expected_t1) - && SimpleType::gradual_eq(&t2, &expected_t2) + if SimpleType::meet(&t1, &expected_t1) != SimpleType::Zero + && SimpleType::meet(&t2, &expected_t2) != SimpleType::Zero { result_t } else { @@ -270,7 +270,7 @@ impl Typechecker { match Self::unop_delta(op) { Some((expected_t, result_t)) => { - if SimpleType::gradual_eq(&t, &expected_t) { + if SimpleType::meet(&t, &expected_t) != SimpleType::Zero { result_t } else { self.warnings From 2664255743628cf0954f9575b01ef7d623c44c0b Mon Sep 17 00:00:00 2001 From: Felipe705x Date: Sun, 19 Apr 2026 21:14:09 -0400 Subject: [PATCH 3/3] fix: clippy --- src/ast/label.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ast/label.rs b/src/ast/label.rs index cd6ac7e..06aa185 100644 --- a/src/ast/label.rs +++ b/src/ast/label.rs @@ -56,7 +56,6 @@ impl LabelType { (_, LabelType::Or(left, right)) => { LabelType::is_subtype(l1, left) || LabelType::is_subtype(l1, right) } - _ => false, } } }