From ccb2cceea16edc72b89061bb3b6359ca225b423a Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Fri, 22 Mar 2024 19:43:33 +0900 Subject: [PATCH] fix: class definition bug --- crates/erg_compiler/lower.rs | 8 +++++--- crates/erg_parser/ast.rs | 4 ++++ tests/should_ok/recursive_class.er | 21 +++++++++++++++++++++ tests/test.rs | 5 +++++ 4 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 tests/should_ok/recursive_class.er diff --git a/crates/erg_compiler/lower.rs b/crates/erg_compiler/lower.rs index a5ccf655f..5173895ba 100644 --- a/crates/erg_compiler/lower.rs +++ b/crates/erg_compiler/lower.rs @@ -2352,9 +2352,11 @@ impl GenericASTLowerer { let Some(hir::Expr::Call(call)) = hir_def.body.block.first() else { return unreachable_error!(LowerErrors, LowerError, self); }; - if let Some(sup_type) = call.args.get_left_or_key("Super") { - if let Err(err) = self.check_inheritable(type_obj, sup_type, &hir_def.sig) { - self.errs.extend(err); + if hir_def.def_kind().is_inherit() { + if let Some(sup_type) = call.args.get_left_or_key("Super") { + if let Err(err) = self.check_inheritable(type_obj, sup_type, &hir_def.sig) { + self.errs.extend(err); + } } } let Some(constructor) = diff --git a/crates/erg_parser/ast.rs b/crates/erg_parser/ast.rs index 0d83eabbc..0ef138bc5 100644 --- a/crates/erg_parser/ast.rs +++ b/crates/erg_parser/ast.rs @@ -5553,6 +5553,10 @@ impl DefKind { matches!(self, Self::Class | Self::Inherit) } + pub const fn is_inherit(&self) -> bool { + matches!(self, Self::Inherit) + } + pub const fn is_class_or_trait(&self) -> bool { self.is_class() || self.is_trait() } diff --git a/tests/should_ok/recursive_class.er b/tests/should_ok/recursive_class.er new file mode 100644 index 000000000..147e812b6 --- /dev/null +++ b/tests/should_ok/recursive_class.er @@ -0,0 +1,21 @@ +F = Class((obj: Obj) -> F) + +greedy(obj) = + log obj + F.new greedy + +_ = greedy(1)::base(1)::base(1) + +Leaf = Class Int +Leaf|<: Show|. + __str__ ref self = "Leaf(\{self::base})" +Node = Class { left = Tree; right = Tree } +Node|<: Show|. + __str__ ref self = "Node{ left = \{self::left}; right = \{self::right} }" +Tree = Class Node or Leaf +Tree|<: Show|. + __str__ ref self = match self::base: + (l: Leaf) -> l.__str__() + (n: Node)-> n.__str__() + +print! Node.new { left = Tree.new Leaf.new 1; right = Tree.new Leaf.new 2 } diff --git a/tests/test.rs b/tests/test.rs index e55adf2a7..8b437afc5 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -344,6 +344,11 @@ fn exec_record_err() -> Result<(), ()> { expect_failure("tests/should_err/record.er", 0, 1) } +#[test] +fn exec_recursive_class() -> Result<(), ()> { + expect_success("tests/should_ok/recursive_class.er", 0) +} + #[test] fn exec_refinement() -> Result<(), ()> { expect_success("tests/should_ok/refinement.er", 0)