From 460af0bd1e2845b083da4997b7fcee3a48426a10 Mon Sep 17 00:00:00 2001 From: Pierre-Marie de Rodat Date: Fri, 24 Jun 2022 08:55:10 +0000 Subject: [PATCH] Lkt lowering: properly catch type inheritance loops For #622 --- langkit/lkt_lowering.py | 7 ++++--- .../grammar/invalid_derivation_loop/test.lkt | 15 +++++++++++++++ .../grammar/invalid_derivation_loop/test.out | 7 +++++++ .../grammar/invalid_derivation_loop/test.yaml | 1 + 4 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 testsuite/tests/grammar/invalid_derivation_loop/test.lkt create mode 100644 testsuite/tests/grammar/invalid_derivation_loop/test.out create mode 100644 testsuite/tests/grammar/invalid_derivation_loop/test.yaml diff --git a/langkit/lkt_lowering.py b/langkit/lkt_lowering.py index db1cd9b16..e3fcbd28d 100644 --- a/langkit/lkt_lowering.py +++ b/langkit/lkt_lowering.py @@ -21,7 +21,7 @@ from langkit.compiled_types import ( ASTNodeType, AbstractNodeData, Argument, CompiledType, CompiledTypeOrDefer, CompiledTypeRepo, EnumNodeAlternative, EnumType, Field, StructType, T, - TypeRepo, UserField, resolve_type + TypeRepo, UserField ) from langkit.diagnostics import ( DiagnosticError, Location, check_source_language, diagnostic_context, error @@ -1354,8 +1354,9 @@ def lower_type_decl(self, decl: L.TypeDecl) -> CompiledType: try: t = self.compiled_types[decl] except KeyError: - # The type is not lowered yet: let's do it - pass + # The type is not lowered yet: let's do it. Add the sentinel to + # reject type inheritance loop during recursion. + self.compiled_types[decl] = None else: if t is None: error('Type inheritance loop detected') diff --git a/testsuite/tests/grammar/invalid_derivation_loop/test.lkt b/testsuite/tests/grammar/invalid_derivation_loop/test.lkt new file mode 100644 index 000000000..f846d26b1 --- /dev/null +++ b/testsuite/tests/grammar/invalid_derivation_loop/test.lkt @@ -0,0 +1,15 @@ +import lexer_example + +@with_lexer(foo_lexer) +grammar foo_grammar { + @main_rule main_rule <- or(N1("example") | N2("null")) +} + +@abstract class FooNode implements Node[FooNode] { +} + +class N1 : N2 { +} + +class N2 : N1 { +} diff --git a/testsuite/tests/grammar/invalid_derivation_loop/test.out b/testsuite/tests/grammar/invalid_derivation_loop/test.out new file mode 100644 index 000000000..05fce0573 --- /dev/null +++ b/testsuite/tests/grammar/invalid_derivation_loop/test.out @@ -0,0 +1,7 @@ +== test.lkt == +test.lkt:11:1: error: Type inheritance loop detected +11 | class N1 : N2 { + | ^ + + +Done diff --git a/testsuite/tests/grammar/invalid_derivation_loop/test.yaml b/testsuite/tests/grammar/invalid_derivation_loop/test.yaml new file mode 100644 index 000000000..4a499fbd3 --- /dev/null +++ b/testsuite/tests/grammar/invalid_derivation_loop/test.yaml @@ -0,0 +1 @@ +driver: lkt_compile