From 58ef8ef1e754566cb792fef41abb178c7a4b01fc Mon Sep 17 00:00:00 2001 From: karl-police Date: Mon, 16 Sep 2024 02:18:35 +0200 Subject: [PATCH] Allow PrimitiveTypeConstraints to unblock on force dispatch if they own the type --- Analysis/include/Luau/ConstraintSolver.h | 2 +- Analysis/src/ConstraintSolver.cpp | 21 +++++++++++++++++---- tests/TypeInfer.primitives.test.cpp | 18 ++++++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/Analysis/include/Luau/ConstraintSolver.h b/Analysis/include/Luau/ConstraintSolver.h index c6b4a828..0bb8fdb0 100644 --- a/Analysis/include/Luau/ConstraintSolver.h +++ b/Analysis/include/Luau/ConstraintSolver.h @@ -172,7 +172,7 @@ public: bool tryDispatch(const TypeAliasExpansionConstraint& c, NotNull constraint); bool tryDispatch(const FunctionCallConstraint& c, NotNull constraint); bool tryDispatch(const FunctionCheckConstraint& c, NotNull constraint); - bool tryDispatch(const PrimitiveTypeConstraint& c, NotNull constraint); + bool tryDispatch(const PrimitiveTypeConstraint& c, NotNull constraint, bool force); bool tryDispatch(const HasPropConstraint& c, NotNull constraint); diff --git a/Analysis/src/ConstraintSolver.cpp b/Analysis/src/ConstraintSolver.cpp index ae02c60a..83c209bd 100644 --- a/Analysis/src/ConstraintSolver.cpp +++ b/Analysis/src/ConstraintSolver.cpp @@ -630,7 +630,7 @@ bool ConstraintSolver::tryDispatch(NotNull constraint, bool fo else if (auto fcc = get(*constraint)) success = tryDispatch(*fcc, constraint); else if (auto fcc = get(*constraint)) - success = tryDispatch(*fcc, constraint); + success = tryDispatch(*fcc, constraint, force); else if (auto hpc = get(*constraint)) success = tryDispatch(*hpc, constraint); else if (auto spc = get(*constraint)) @@ -1406,7 +1406,7 @@ bool ConstraintSolver::tryDispatch(const FunctionCheckConstraint& c, NotNull constraint) +bool ConstraintSolver::tryDispatch(const PrimitiveTypeConstraint& c, NotNull constraint, bool force) { std::optional expectedType = c.expectedType ? std::make_optional(follow(*c.expectedType)) : std::nullopt; if (expectedType && (isBlocked(*expectedType) || get(*expectedType))) @@ -1422,8 +1422,21 @@ bool ConstraintSolver::tryDispatch(const PrimitiveTypeConstraint& c, NotNull 1) { - block(c.freeType, constraint); - return false; + if (force) + { + // If we get force dispatched and are the owner of the constraint + // Then do not block. + if (canMutate(c.freeType, constraint) == false) + { + block(c.freeType, constraint); + return false; + } + } + else + { + block(c.freeType, constraint); + return false; + } } TypeId bindTo = c.primitiveType; diff --git a/tests/TypeInfer.primitives.test.cpp b/tests/TypeInfer.primitives.test.cpp index c3cce9df..08af221e 100644 --- a/tests/TypeInfer.primitives.test.cpp +++ b/tests/TypeInfer.primitives.test.cpp @@ -96,6 +96,24 @@ TEST_CASE_FIXTURE(Fixture, "check_methods_of_number") } } +TEST_CASE_FIXTURE(BuiltinsFixture, "primitive_types_issue_IfThenElseIf_union_simplification") +{ + if (!FFlag::LuauSolverV2) + return; + + CheckResult result = check(R"( +local v1: string? + +local stringButItIsHere = "Windows" + +v1 = if true then stringButItIsHere +elseif false then "Something" +else "Other" +)"); + + LUAU_REQUIRE_NO_ERRORS(result); +} + TEST_CASE("singleton_types") { BuiltinsFixture a;