From b6a92b2380aeab3e19e0f239485bfad86b2fa044 Mon Sep 17 00:00:00 2001 From: Ada Freya Ahmed Date: Thu, 10 Sep 2026 11:44:02 +0530 Subject: [PATCH 1/2] feat: support using decl types for in/out --- lib/source/pl/core/parser.cpp | 50 +++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/lib/source/pl/core/parser.cpp b/lib/source/pl/core/parser.cpp index 0378bcd7..5726936f 100644 --- a/lib/source/pl/core/parser.cpp +++ b/lib/source/pl/core/parser.cpp @@ -2429,22 +2429,50 @@ namespace pl::core { if (inVariable || outVariable) { bool invalidType = false; - if (const auto builtinType = dynamic_cast(type->getType().get()); builtinType != nullptr) { - if (const auto valueType = builtinType->getType(); !Token::isInteger(valueType) - && !Token::isFloatingPoint(valueType) - && valueType != Token::ValueType::Boolean - && valueType != Token::ValueType::Character - && valueType != Token::ValueType::String) - invalidType = true; - } else if (const auto typeDecl = dynamic_cast(type->getType().get()); typeDecl != nullptr) { - if (const auto enumDecl = dynamic_cast(typeDecl->getType().get()); enumDecl == nullptr) { + auto visitingType = type; + auto declNestLimit = 128; // some high value so infinite recursion breaks + while (!invalidType && visitingType && declNestLimit-- > 0) { + auto checkType = visitingType->getType(); + + if (checkType == nullptr) { invalidType = true; + break; } - } else { + + if (const auto typeDecl = std::dynamic_pointer_cast(checkType); typeDecl != nullptr) { + checkType = typeDecl->getType(); + } + + if (const auto usingDecl = std::dynamic_pointer_cast(checkType); usingDecl != nullptr) { + [[unlikely]] if (usingDecl == visitingType) { + // realistically should never happen but you never know + invalidType = true; + break; + } + + visitingType = usingDecl; + continue; + } + + if (const auto enumDecl = dynamic_cast(checkType.get()); enumDecl != nullptr) { + break; + } + + if (const auto builtinType = dynamic_cast(checkType.get()); builtinType != nullptr) { + const auto valueType = builtinType->getType(); + invalidType = !Token::isInteger(valueType) + && !Token::isFloatingPoint(valueType) + && valueType != Token::ValueType::Boolean + && valueType != Token::ValueType::Character + && valueType != Token::ValueType::String; + break; + } + invalidType = true; + break; } - if (invalidType) { + if (invalidType || visitingType == nullptr || declNestLimit <= 0) { errorDesc("Invalid in/out parameter type.", "Allowed types are: 'char', 'bool', 'str', floating point types, integral types, or enums."); return nullptr; } From 441c61b829ce340369e49df3ef576a68bef630cf Mon Sep 17 00:00:00 2001 From: Ada Freya Ahmed Date: Thu, 10 Sep 2026 23:32:59 +0530 Subject: [PATCH 2/2] qa: requested changes --- lib/source/pl/core/parser.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/source/pl/core/parser.cpp b/lib/source/pl/core/parser.cpp index 5726936f..dd7c2988 100644 --- a/lib/source/pl/core/parser.cpp +++ b/lib/source/pl/core/parser.cpp @@ -2430,7 +2430,7 @@ namespace pl::core { if (inVariable || outVariable) { bool invalidType = false; auto visitingType = type; - auto declNestLimit = 128; // some high value so infinite recursion breaks + i32 declNestLimit = 32; // default evaluation depth while (!invalidType && visitingType && declNestLimit-- > 0) { auto checkType = visitingType->getType(); @@ -2444,8 +2444,8 @@ namespace pl::core { } if (const auto usingDecl = std::dynamic_pointer_cast(checkType); usingDecl != nullptr) { - [[unlikely]] if (usingDecl == visitingType) { - // realistically should never happen but you never know + if (usingDecl == visitingType) [[unlikely]] { + // bad case of forward declarations ending up referencing itself invalidType = true; break; }