From 637e9be026970224760ed1b0e0a568b434497a94 Mon Sep 17 00:00:00 2001 From: JaDogg Date: Sat, 25 May 2024 19:27:47 +0100 Subject: [PATCH] fix(type_checker): does not allow passing const to a nonconst, allow passing nonconst to a const --- compiler/src/compiler/type_checker.cpp | 5 +++++ compiler/tests/test_type_checker.cpp | 22 ++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/compiler/src/compiler/type_checker.cpp b/compiler/src/compiler/type_checker.cpp index 0f675470..660b4fef 100644 --- a/compiler/src/compiler/type_checker.cpp +++ b/compiler/src/compiler/type_checker.cpp @@ -1111,6 +1111,7 @@ void type_checker::visit_const_stmt(const_stmt *obj) { auto match = type_match(obj->data_type_->args_[0], expression_dt, true); if (match.matched_) { placeholder = expression_data; + placeholder.datatype_ = obj->data_type_; // Set the correct data type } else { std::stringstream message{}; message << "Constant '" << name << "' data type mismatch. "; @@ -1150,6 +1151,10 @@ type_match_result type_checker::type_match(ykdatatype *required_datatype, required_datatype->auto_cast(provided_datatype, dt_pool_, false, true); if (castable != nullptr) { return type_match_result{"", true, true}; } } + // Pass a Type to a Const[Type] is allowed (becomes more restrictive) + if (primitive_or_obj && is_identical_type(required_datatype->const_unwrap(), provided_datatype)) { + return type_match_result{"", true, false}; + } std::stringstream message{}; message << "data type mismatch. Expected: "; message << required_datatype->as_string_simplified(); diff --git a/compiler/tests/test_type_checker.cpp b/compiler/tests/test_type_checker.cpp index 599596e9..6d5290c3 100644 --- a/compiler/tests/test_type_checker.cpp +++ b/compiler/tests/test_type_checker.cpp @@ -413,6 +413,28 @@ TEST_CASE( " return 0", "Variable argument: 5 mismatches. Expected: int Provided: i64"); } +TEST_CASE("type checker: pass in a non constant structure to a const") { + test_typechecker_snippet_full_ok( + "class A:\n" + " a: int\n" + "def afunc(a: Const[A]) -> None:\n" + " pass\n" + "def main() -> int:\n" + " myobj = A{a: 1}\n" + " afunc(myobj)\n" + " return 0"); +} +TEST_CASE("type checker: pass in a constant structure object to a non const") { + test_typechecker_snippet_full( + "class A:\n" + " a: int\n" + "def afunc(a: A) -> None:\n" + " pass\n" + "def main() -> int:\n" + " myobj: Const[A] = A{a: 1}\n" + " afunc(myobj)\n" + " return 0", "Parameter & argument 1 mismatches. Expected: A Provided: Const[A]"); +} TEST_CASE("type checker: func ptr call parameter and argument mismatches") { test_typechecker_snippet_full_ok("def fnc(a: int, b: int) -> None:\n" " pass\n"