mirror of
https://github.com/luau-lang/luau.git
synced 2025-04-01 17:30:53 +01:00
Merge 86ecc212af
into 12dac2f1f4
This commit is contained in:
commit
67713d7f8c
2 changed files with 60 additions and 7 deletions
|
@ -46,6 +46,7 @@ LUAU_FASTFLAGVARIABLE(LuauInferLocalTypesInMultipleAssignments)
|
|||
LUAU_FASTFLAGVARIABLE(LuauDoNotLeakNilInRefinement)
|
||||
LUAU_FASTFLAGVARIABLE(LuauExtraFollows)
|
||||
LUAU_FASTFLAG(LuauUserTypeFunTypecheck)
|
||||
LUAU_FASTFLAGVARIABLE(LuauRefineJustTheReadProperty)
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
|
@ -530,11 +531,18 @@ void ConstraintGenerator::computeRefinement(
|
|||
|
||||
TypeId nextDiscriminantTy = arena->addType(TableType{});
|
||||
NotNull<TableType> table{getMutable<TableType>(nextDiscriminantTy)};
|
||||
// When we fully support read-write properties (i.e. when we allow properties with
|
||||
// completely disparate read and write types), then the following property can be
|
||||
// set to read-only since refinements only tell us about what we read. This cannot
|
||||
// be allowed yet though because it causes read and write types to diverge.
|
||||
table->props[*key->propName] = Property::rw(discriminantTy);
|
||||
if (FFlag::LuauRefineJustTheReadProperty)
|
||||
{
|
||||
table->props[*key->propName] = Property::readonly(discriminantTy);
|
||||
}
|
||||
else
|
||||
{
|
||||
// When we fully support read-write properties (i.e. when we allow properties with
|
||||
// completely disparate read and write types), then the following property can be
|
||||
// set to read-only since refinements only tell us about what we read. This cannot
|
||||
// be allowed yet though because it causes read and write types to diverge.
|
||||
table->props[*key->propName] = Property::rw(discriminantTy);
|
||||
}
|
||||
table->scope = scope.get();
|
||||
table->state = TableState::Sealed;
|
||||
|
||||
|
@ -548,7 +556,7 @@ void ConstraintGenerator::computeRefinement(
|
|||
refis->get(proposition->key->def)->shouldAppendNilType =
|
||||
(sense || !eq) && containsSubscriptedDefinition(proposition->key->def) && !proposition->implicitFromCall;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
refis->get(proposition->key->def)->shouldAppendNilType = (sense || !eq) && containsSubscriptedDefinition(proposition->key->def);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ LUAU_FASTFLAG(LuauIntersectNotNil)
|
|||
LUAU_FASTFLAG(LuauSkipNoRefineDuringRefinement)
|
||||
LUAU_FASTFLAG(LuauFunctionCallsAreNotNilable)
|
||||
LUAU_FASTFLAG(LuauDoNotLeakNilInRefinement)
|
||||
LUAU_FASTFLAG(LuauRefineJustTheReadProperty)
|
||||
|
||||
using namespace Luau;
|
||||
|
||||
|
@ -2538,7 +2539,6 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "function_calls_are_not_nillable")
|
|||
return nil
|
||||
end
|
||||
)"));
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE_FIXTURE(BuiltinsFixture, "oss_1528_method_calls_are_not_nillable")
|
||||
|
@ -2562,4 +2562,49 @@ TEST_CASE_FIXTURE(BuiltinsFixture, "oss_1528_method_calls_are_not_nillable")
|
|||
)"));
|
||||
}
|
||||
|
||||
TEST_CASE_FIXTURE(Fixture, "refine_just_the_read_property")
|
||||
{
|
||||
ScopedFastFlag sff[]{
|
||||
{FFlag::LuauSolverV2, true},
|
||||
{FFlag::LuauRefineJustTheReadProperty, true},
|
||||
};
|
||||
|
||||
CheckResult result = check(R"(
|
||||
type Foo = { p: boolean }
|
||||
|
||||
function f(x: Foo)
|
||||
if x.p == true then return end
|
||||
|
||||
x.p = true
|
||||
x.p = false
|
||||
end
|
||||
)");
|
||||
|
||||
LUAU_REQUIRE_NO_ERRORS(result);
|
||||
|
||||
// The first check is correct because it reflects the state of the program by that point.
|
||||
// The second check is not. It fails to account for transitive typestate change from the
|
||||
// previous statement.
|
||||
CHECK_EQ("Foo & { read p: ~true }", toString(requireTypeAtPosition({6, 12})));
|
||||
CHECK_EQ("Foo & { read p: ~true }", toString(requireTypeAtPosition({7, 12})));
|
||||
}
|
||||
|
||||
TEST_CASE_FIXTURE(Fixture, "refine_just_the_read_property_typestate")
|
||||
{
|
||||
ScopedFastFlag sff[]{
|
||||
{FFlag::LuauSolverV2, true},
|
||||
{FFlag::LuauRefineJustTheReadProperty, true},
|
||||
};
|
||||
|
||||
CheckResult result = check(R"(
|
||||
type Foo = { p: {}? }
|
||||
|
||||
function f(x: Foo)
|
||||
if not x.p then x.p = {} end
|
||||
end
|
||||
)");
|
||||
|
||||
LUAU_REQUIRE_NO_ERRORS(result);
|
||||
}
|
||||
|
||||
TEST_SUITE_END();
|
||||
|
|
Loading…
Add table
Reference in a new issue