Allow PrimitiveTypeConstraints to unblock on force dispatch if they own the type

This commit is contained in:
karl-police 2024-09-16 02:18:35 +02:00
parent e8a7acb802
commit 58ef8ef1e7
3 changed files with 36 additions and 5 deletions

View File

@ -172,7 +172,7 @@ public:
bool tryDispatch(const TypeAliasExpansionConstraint& c, NotNull<const Constraint> constraint);
bool tryDispatch(const FunctionCallConstraint& c, NotNull<const Constraint> constraint);
bool tryDispatch(const FunctionCheckConstraint& c, NotNull<const Constraint> constraint);
bool tryDispatch(const PrimitiveTypeConstraint& c, NotNull<const Constraint> constraint);
bool tryDispatch(const PrimitiveTypeConstraint& c, NotNull<const Constraint> constraint, bool force);
bool tryDispatch(const HasPropConstraint& c, NotNull<const Constraint> constraint);

View File

@ -630,7 +630,7 @@ bool ConstraintSolver::tryDispatch(NotNull<const Constraint> constraint, bool fo
else if (auto fcc = get<FunctionCheckConstraint>(*constraint))
success = tryDispatch(*fcc, constraint);
else if (auto fcc = get<PrimitiveTypeConstraint>(*constraint))
success = tryDispatch(*fcc, constraint);
success = tryDispatch(*fcc, constraint, force);
else if (auto hpc = get<HasPropConstraint>(*constraint))
success = tryDispatch(*hpc, constraint);
else if (auto spc = get<HasIndexerConstraint>(*constraint))
@ -1406,7 +1406,7 @@ bool ConstraintSolver::tryDispatch(const FunctionCheckConstraint& c, NotNull<con
return true;
}
bool ConstraintSolver::tryDispatch(const PrimitiveTypeConstraint& c, NotNull<const Constraint> constraint)
bool ConstraintSolver::tryDispatch(const PrimitiveTypeConstraint& c, NotNull<const Constraint> constraint, bool force)
{
std::optional<TypeId> expectedType = c.expectedType ? std::make_optional<TypeId>(follow(*c.expectedType)) : std::nullopt;
if (expectedType && (isBlocked(*expectedType) || get<PendingExpansionType>(*expectedType)))
@ -1422,8 +1422,21 @@ bool ConstraintSolver::tryDispatch(const PrimitiveTypeConstraint& c, NotNull<con
// This is probably the only thing that makes this not insane to do.
if (auto refCount = unresolvedConstraints.find(c.freeType); refCount && *refCount > 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;

View File

@ -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;