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