Skip to content

Commit a7be4fc

Browse files
Vighnesh-Vaatxealexmccordandyfriesenaviralg
authored
Sync to upstream/release/633 (#1318)
# What's Changed? - Mostly stability and bugfixes with the new solver. ## New Solver - Typechecking with the new solver should respect the no-check hot comment. - Record type alias locations and property locations of table assignments - Maintain location information for exported table types - Stability fixes for normalization - Report internal constraint solver errors. --- ### Internal Contributors Co-authored-by: Aaron Weiss <aaronweiss@roblox.com> Co-authored-by: Alexander McCord <amccord@roblox.com> Co-authored-by: Andy Friesen <afriesen@roblox.com> Co-authored-by: Vighnesh Vijay <vvijay@roblox.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com> --------- Co-authored-by: Aaron Weiss <aaronweiss@roblox.com> Co-authored-by: Alexander McCord <amccord@roblox.com> Co-authored-by: Andy Friesen <afriesen@roblox.com> Co-authored-by: Aviral Goel <agoel@roblox.com> Co-authored-by: David Cope <dcope@roblox.com> Co-authored-by: Lily Brown <lbrown@roblox.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
1 parent 0d26888 commit a7be4fc

25 files changed

+212
-376
lines changed

Analysis/include/Luau/Constraint.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,10 @@ struct AssignPropConstraint
202202
std::string propName;
203203
TypeId rhsType;
204204

205+
/// If a new property is to be inserted into a table type, it will be
206+
/// ascribed this location.
207+
std::optional<Location> propLocation;
208+
205209
/// The canonical write type of the property. It is _solely_ used to
206210
/// populate astTypes during constraint resolution. Nothing should ever
207211
/// block on it.

Analysis/src/ConstraintGenerator.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,6 +1246,9 @@ ControlFlow ConstraintGenerator::visit(const ScopePtr& scope, AstStatTypeAlias*
12461246
return ControlFlow::None;
12471247
}
12481248

1249+
scope->typeAliasLocations[alias->name.value] = alias->location;
1250+
scope->typeAliasNameLocations[alias->name.value] = alias->nameLocation;
1251+
12491252
ScopePtr* defnScope = astTypeAliasDefiningScopes.find(alias);
12501253

12511254
std::unordered_map<Name, TypeFun>* typeBindings;
@@ -2441,7 +2444,7 @@ void ConstraintGenerator::visitLValue(const ScopePtr& scope, AstExprIndexName* e
24412444

24422445
bool incremented = recordPropertyAssignment(lhsTy);
24432446

2444-
auto apc = addConstraint(scope, expr->location, AssignPropConstraint{lhsTy, expr->index.value, rhsType, propTy, incremented});
2447+
auto apc = addConstraint(scope, expr->location, AssignPropConstraint{lhsTy, expr->index.value, rhsType, expr->indexLocation, propTy, incremented});
24452448
getMutable<BlockedType>(propTy)->setOwner(apc);
24462449
}
24472450

@@ -2457,7 +2460,7 @@ void ConstraintGenerator::visitLValue(const ScopePtr& scope, AstExprIndexExpr* e
24572460

24582461
bool incremented = recordPropertyAssignment(lhsTy);
24592462

2460-
auto apc = addConstraint(scope, expr->location, AssignPropConstraint{lhsTy, std::move(propName), rhsType, propTy, incremented});
2463+
auto apc = addConstraint(scope, expr->location, AssignPropConstraint{lhsTy, std::move(propName), rhsType, expr->index->location, propTy, incremented});
24612464
getMutable<BlockedType>(propTy)->setOwner(apc);
24622465

24632466
return;
@@ -2478,6 +2481,7 @@ Inference ConstraintGenerator::check(const ScopePtr& scope, AstExprTable* expr,
24782481
LUAU_ASSERT(ttv);
24792482

24802483
ttv->state = TableState::Unsealed;
2484+
ttv->definitionModuleName = module->name;
24812485
ttv->scope = scope.get();
24822486

24832487
interiorTypes.back().push_back(ty);
@@ -2509,7 +2513,7 @@ Inference ConstraintGenerator::check(const ScopePtr& scope, AstExprTable* expr,
25092513
if (AstExprConstantString* key = item.key->as<AstExprConstantString>())
25102514
{
25112515
std::string propName{key->value.data, key->value.size};
2512-
ttv->props[propName] = {itemTy};
2516+
ttv->props[propName] = {itemTy, /*deprecated*/ false, {}, key->location};
25132517
}
25142518
else
25152519
{

Analysis/src/ConstraintSolver.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,9 @@ void ConstraintSolver::run()
486486
progress |= runSolverPass(true);
487487
} while (progress);
488488

489+
if (!unsolvedConstraints.empty())
490+
reportError(InternalError{"Type inference failed to complete, you may see some confusing types and type errors."}, Location{});
491+
489492
// After we have run all the constraints, type families should be generalized
490493
// At this point, we can try to perform one final simplification to suss out
491494
// whether type families are truly uninhabited or if they can reduce
@@ -1729,7 +1732,10 @@ bool ConstraintSolver::tryDispatch(const AssignPropConstraint& c, NotNull<const
17291732
if (lhsTable->state == TableState::Unsealed || lhsTable->state == TableState::Free)
17301733
{
17311734
bind(constraint, c.propType, rhsType);
1732-
lhsTable->props[propName] = Property::rw(rhsType);
1735+
Property& newProp = lhsTable->props[propName];
1736+
newProp.readTy = rhsType;
1737+
newProp.writeTy = rhsType;
1738+
newProp.location = c.propLocation;
17331739

17341740
if (lhsTable->state == TableState::Unsealed && c.decrementPropCount)
17351741
{

Analysis/src/Frontend.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ LUAU_FASTFLAGVARIABLE(DebugLuauLogSolverToJsonFile, false)
4141
LUAU_FASTFLAGVARIABLE(DebugLuauForbidInternalTypes, false)
4242
LUAU_FASTFLAGVARIABLE(DebugLuauForceStrictMode, false)
4343
LUAU_FASTFLAGVARIABLE(DebugLuauForceNonStrictMode, false)
44+
LUAU_FASTFLAGVARIABLE(LuauSourceModuleUpdatedWithSelectedMode, false)
4445

4546
namespace Luau
4647
{
@@ -918,6 +919,9 @@ void Frontend::checkBuildQueueItem(BuildQueueItem& item)
918919
mode = Mode::Nonstrict;
919920
else
920921
mode = sourceModule.mode.value_or(config.mode);
922+
923+
if (FFlag::LuauSourceModuleUpdatedWithSelectedMode)
924+
item.sourceModule->mode = {mode};
921925
ScopePtr environmentScope = item.environmentScope;
922926
double timestamp = getTimestamp();
923927
const std::vector<RequireCycle>& requireCycles = item.requireCycles;
@@ -1240,9 +1244,7 @@ ModulePtr check(const SourceModule& sourceModule, Mode mode, const std::vector<R
12401244
ModulePtr result = std::make_shared<Module>();
12411245
result->name = sourceModule.name;
12421246
result->humanReadableName = sourceModule.humanReadableName;
1243-
1244-
result->mode = sourceModule.mode.value_or(Mode::NoCheck);
1245-
1247+
result->mode = mode;
12461248
result->internalTypes.owningModule = result.get();
12471249
result->interfaceTypes.owningModule = result.get();
12481250

@@ -1323,10 +1325,19 @@ ModulePtr check(const SourceModule& sourceModule, Mode mode, const std::vector<R
13231325
}
13241326
else
13251327
{
1326-
if (mode == Mode::Nonstrict)
1328+
switch (mode)
1329+
{
1330+
case Mode::Nonstrict:
13271331
Luau::checkNonStrict(builtinTypes, iceHandler, NotNull{&unifierState}, NotNull{&dfg}, NotNull{&limits}, sourceModule, result.get());
1328-
else
1332+
break;
1333+
case Mode::Definition:
1334+
// fallthrough intentional
1335+
case Mode::Strict:
13291336
Luau::check(builtinTypes, NotNull{&unifierState}, NotNull{&limits}, logger.get(), sourceModule, result.get());
1337+
break;
1338+
case Mode::NoCheck:
1339+
break;
1340+
};
13301341
}
13311342

13321343
unfreeze(result->interfaceTypes);

Analysis/src/Normalize.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,10 @@ bool isSubtype(const NormalizedStringType& subStr, const NormalizedStringType& s
255255

256256
void NormalizedClassType::pushPair(TypeId ty, TypeIds negations)
257257
{
258-
ordering.push_back(ty);
259-
classes.insert(std::make_pair(ty, std::move(negations)));
258+
auto result = classes.insert(std::make_pair(ty, std::move(negations)));
259+
if (result.second)
260+
ordering.push_back(ty);
261+
LUAU_ASSERT(ordering.size() == classes.size());
260262
}
261263

262264
void NormalizedClassType::resetToNever()

Analysis/src/Substitution.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,12 @@ void Substitution::replaceChildren(TypeId ty)
753753
for (auto& [name, prop] : ttv->props)
754754
{
755755
if (FFlag::DebugLuauDeferredConstraintResolution)
756-
prop = Property::create(replace(prop.readTy), replace(prop.writeTy));
756+
{
757+
if (prop.readTy)
758+
prop.readTy = replace(prop.readTy);
759+
if (prop.writeTy)
760+
prop.writeTy = replace(prop.writeTy);
761+
}
757762
else
758763
prop.setType(replace(prop.type()));
759764
}

CodeGen/include/Luau/IrDump.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,8 @@ void toString(IrToStringContext& ctx, IrOp op);
3131

3232
void toString(std::string& result, IrConst constant);
3333

34-
const char* getBytecodeTypeName_DEPRECATED(uint8_t type);
3534
const char* getBytecodeTypeName(uint8_t type, const char* const* userdataTypes);
3635

37-
void toString_DEPRECATED(std::string& result, const BytecodeTypes& bcTypes);
3836
void toString(std::string& result, const BytecodeTypes& bcTypes, const char* const* userdataTypes);
3937

4038
void toStringDetailed(

CodeGen/src/BytecodeAnalysis.cpp

Lines changed: 30 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
#include <algorithm>
1313

14-
LUAU_FASTFLAGVARIABLE(LuauCodegenUserdataOps, false)
1514
LUAU_FASTFLAGVARIABLE(LuauCodegenFastcall3, false)
1615

1716
namespace Luau
@@ -749,50 +748,27 @@ void analyzeBytecodeTypes(IrFunction& function, const HostIrHooks& hostHooks)
749748

750749
regTags[ra] = LBC_TYPE_ANY;
751750

752-
if (FFlag::LuauCodegenUserdataOps)
753-
{
754-
TString* str = gco2ts(function.proto->k[kc].value.gc);
755-
const char* field = getstr(str);
751+
TString* str = gco2ts(function.proto->k[kc].value.gc);
752+
const char* field = getstr(str);
756753

757-
if (bcType.a == LBC_TYPE_VECTOR)
754+
if (bcType.a == LBC_TYPE_VECTOR)
755+
{
756+
if (str->len == 1)
758757
{
759-
if (str->len == 1)
760-
{
761-
// Same handling as LOP_GETTABLEKS block in lvmexecute.cpp - case-insensitive comparison with "X" / "Y" / "Z"
762-
char ch = field[0] | ' ';
763-
764-
if (ch == 'x' || ch == 'y' || ch == 'z')
765-
regTags[ra] = LBC_TYPE_NUMBER;
766-
}
758+
// Same handling as LOP_GETTABLEKS block in lvmexecute.cpp - case-insensitive comparison with "X" / "Y" / "Z"
759+
char ch = field[0] | ' ';
767760

768-
if (regTags[ra] == LBC_TYPE_ANY && hostHooks.vectorAccessBytecodeType)
769-
regTags[ra] = hostHooks.vectorAccessBytecodeType(field, str->len);
770-
}
771-
else if (isCustomUserdataBytecodeType(bcType.a))
772-
{
773-
if (regTags[ra] == LBC_TYPE_ANY && hostHooks.userdataAccessBytecodeType)
774-
regTags[ra] = hostHooks.userdataAccessBytecodeType(bcType.a, field, str->len);
761+
if (ch == 'x' || ch == 'y' || ch == 'z')
762+
regTags[ra] = LBC_TYPE_NUMBER;
775763
}
764+
765+
if (regTags[ra] == LBC_TYPE_ANY && hostHooks.vectorAccessBytecodeType)
766+
regTags[ra] = hostHooks.vectorAccessBytecodeType(field, str->len);
776767
}
777-
else
768+
else if (isCustomUserdataBytecodeType(bcType.a))
778769
{
779-
if (bcType.a == LBC_TYPE_VECTOR)
780-
{
781-
TString* str = gco2ts(function.proto->k[kc].value.gc);
782-
const char* field = getstr(str);
783-
784-
if (str->len == 1)
785-
{
786-
// Same handling as LOP_GETTABLEKS block in lvmexecute.cpp - case-insensitive comparison with "X" / "Y" / "Z"
787-
char ch = field[0] | ' ';
788-
789-
if (ch == 'x' || ch == 'y' || ch == 'z')
790-
regTags[ra] = LBC_TYPE_NUMBER;
791-
}
792-
793-
if (regTags[ra] == LBC_TYPE_ANY && hostHooks.vectorAccessBytecodeType)
794-
regTags[ra] = hostHooks.vectorAccessBytecodeType(field, str->len);
795-
}
770+
if (regTags[ra] == LBC_TYPE_ANY && hostHooks.userdataAccessBytecodeType)
771+
regTags[ra] = hostHooks.userdataAccessBytecodeType(bcType.a, field, str->len);
796772
}
797773

798774
bcType.result = regTags[ra];
@@ -829,7 +805,7 @@ void analyzeBytecodeTypes(IrFunction& function, const HostIrHooks& hostHooks)
829805
regTags[ra] = LBC_TYPE_NUMBER;
830806
else if (bcType.a == LBC_TYPE_VECTOR && bcType.b == LBC_TYPE_VECTOR)
831807
regTags[ra] = LBC_TYPE_VECTOR;
832-
else if (FFlag::LuauCodegenUserdataOps && hostHooks.userdataMetamethodBytecodeType &&
808+
else if (hostHooks.userdataMetamethodBytecodeType &&
833809
(isCustomUserdataBytecodeType(bcType.a) || isCustomUserdataBytecodeType(bcType.b)))
834810
regTags[ra] = hostHooks.userdataMetamethodBytecodeType(bcType.a, bcType.b, opcodeToHostMetamethod(op));
835811

@@ -861,7 +837,7 @@ void analyzeBytecodeTypes(IrFunction& function, const HostIrHooks& hostHooks)
861837
if (bcType.b == LBC_TYPE_NUMBER || bcType.b == LBC_TYPE_VECTOR)
862838
regTags[ra] = LBC_TYPE_VECTOR;
863839
}
864-
else if (FFlag::LuauCodegenUserdataOps && hostHooks.userdataMetamethodBytecodeType &&
840+
else if (hostHooks.userdataMetamethodBytecodeType &&
865841
(isCustomUserdataBytecodeType(bcType.a) || isCustomUserdataBytecodeType(bcType.b)))
866842
{
867843
regTags[ra] = hostHooks.userdataMetamethodBytecodeType(bcType.a, bcType.b, opcodeToHostMetamethod(op));
@@ -884,7 +860,7 @@ void analyzeBytecodeTypes(IrFunction& function, const HostIrHooks& hostHooks)
884860

885861
if (bcType.a == LBC_TYPE_NUMBER && bcType.b == LBC_TYPE_NUMBER)
886862
regTags[ra] = LBC_TYPE_NUMBER;
887-
else if (FFlag::LuauCodegenUserdataOps && hostHooks.userdataMetamethodBytecodeType &&
863+
else if (hostHooks.userdataMetamethodBytecodeType &&
888864
(isCustomUserdataBytecodeType(bcType.a) || isCustomUserdataBytecodeType(bcType.b)))
889865
regTags[ra] = hostHooks.userdataMetamethodBytecodeType(bcType.a, bcType.b, opcodeToHostMetamethod(op));
890866

@@ -907,7 +883,7 @@ void analyzeBytecodeTypes(IrFunction& function, const HostIrHooks& hostHooks)
907883
regTags[ra] = LBC_TYPE_NUMBER;
908884
else if (bcType.a == LBC_TYPE_VECTOR && bcType.b == LBC_TYPE_VECTOR)
909885
regTags[ra] = LBC_TYPE_VECTOR;
910-
else if (FFlag::LuauCodegenUserdataOps && hostHooks.userdataMetamethodBytecodeType &&
886+
else if (hostHooks.userdataMetamethodBytecodeType &&
911887
(isCustomUserdataBytecodeType(bcType.a) || isCustomUserdataBytecodeType(bcType.b)))
912888
regTags[ra] = hostHooks.userdataMetamethodBytecodeType(bcType.a, bcType.b, opcodeToHostMetamethod(op));
913889

@@ -939,7 +915,7 @@ void analyzeBytecodeTypes(IrFunction& function, const HostIrHooks& hostHooks)
939915
if (bcType.b == LBC_TYPE_NUMBER || bcType.b == LBC_TYPE_VECTOR)
940916
regTags[ra] = LBC_TYPE_VECTOR;
941917
}
942-
else if (FFlag::LuauCodegenUserdataOps && hostHooks.userdataMetamethodBytecodeType &&
918+
else if (hostHooks.userdataMetamethodBytecodeType &&
943919
(isCustomUserdataBytecodeType(bcType.a) || isCustomUserdataBytecodeType(bcType.b)))
944920
{
945921
regTags[ra] = hostHooks.userdataMetamethodBytecodeType(bcType.a, bcType.b, opcodeToHostMetamethod(op));
@@ -962,7 +938,7 @@ void analyzeBytecodeTypes(IrFunction& function, const HostIrHooks& hostHooks)
962938

963939
if (bcType.a == LBC_TYPE_NUMBER && bcType.b == LBC_TYPE_NUMBER)
964940
regTags[ra] = LBC_TYPE_NUMBER;
965-
else if (FFlag::LuauCodegenUserdataOps && hostHooks.userdataMetamethodBytecodeType &&
941+
else if (hostHooks.userdataMetamethodBytecodeType &&
966942
(isCustomUserdataBytecodeType(bcType.a) || isCustomUserdataBytecodeType(bcType.b)))
967943
regTags[ra] = hostHooks.userdataMetamethodBytecodeType(bcType.a, bcType.b, opcodeToHostMetamethod(op));
968944

@@ -984,7 +960,7 @@ void analyzeBytecodeTypes(IrFunction& function, const HostIrHooks& hostHooks)
984960
regTags[ra] = LBC_TYPE_NUMBER;
985961
else if (bcType.a == LBC_TYPE_VECTOR && bcType.b == LBC_TYPE_VECTOR)
986962
regTags[ra] = LBC_TYPE_VECTOR;
987-
else if (FFlag::LuauCodegenUserdataOps && hostHooks.userdataMetamethodBytecodeType &&
963+
else if (hostHooks.userdataMetamethodBytecodeType &&
988964
(isCustomUserdataBytecodeType(bcType.a) || isCustomUserdataBytecodeType(bcType.b)))
989965
regTags[ra] = hostHooks.userdataMetamethodBytecodeType(bcType.a, bcType.b, opcodeToHostMetamethod(op));
990966

@@ -1014,7 +990,7 @@ void analyzeBytecodeTypes(IrFunction& function, const HostIrHooks& hostHooks)
1014990
if (bcType.b == LBC_TYPE_NUMBER || bcType.b == LBC_TYPE_VECTOR)
1015991
regTags[ra] = LBC_TYPE_VECTOR;
1016992
}
1017-
else if (FFlag::LuauCodegenUserdataOps && hostHooks.userdataMetamethodBytecodeType &&
993+
else if (hostHooks.userdataMetamethodBytecodeType &&
1018994
(isCustomUserdataBytecodeType(bcType.a) || isCustomUserdataBytecodeType(bcType.b)))
1019995
{
1020996
regTags[ra] = hostHooks.userdataMetamethodBytecodeType(bcType.a, bcType.b, opcodeToHostMetamethod(op));
@@ -1047,7 +1023,7 @@ void analyzeBytecodeTypes(IrFunction& function, const HostIrHooks& hostHooks)
10471023
regTags[ra] = LBC_TYPE_NUMBER;
10481024
else if (bcType.a == LBC_TYPE_VECTOR)
10491025
regTags[ra] = LBC_TYPE_VECTOR;
1050-
else if (FFlag::LuauCodegenUserdataOps && hostHooks.userdataMetamethodBytecodeType && isCustomUserdataBytecodeType(bcType.a))
1026+
else if (hostHooks.userdataMetamethodBytecodeType && isCustomUserdataBytecodeType(bcType.a))
10511027
regTags[ra] = hostHooks.userdataMetamethodBytecodeType(bcType.a, LBC_TYPE_ANY, HostMetamethod::Minus);
10521028

10531029
bcType.result = regTags[ra];
@@ -1203,26 +1179,13 @@ void analyzeBytecodeTypes(IrFunction& function, const HostIrHooks& hostHooks)
12031179

12041180
bcType.result = LBC_TYPE_FUNCTION;
12051181

1206-
if (FFlag::LuauCodegenUserdataOps)
1207-
{
1208-
TString* str = gco2ts(function.proto->k[kc].value.gc);
1209-
const char* field = getstr(str);
1182+
TString* str = gco2ts(function.proto->k[kc].value.gc);
1183+
const char* field = getstr(str);
12101184

1211-
if (bcType.a == LBC_TYPE_VECTOR && hostHooks.vectorNamecallBytecodeType)
1212-
knownNextCallResult = LuauBytecodeType(hostHooks.vectorNamecallBytecodeType(field, str->len));
1213-
else if (isCustomUserdataBytecodeType(bcType.a) && hostHooks.userdataNamecallBytecodeType)
1214-
knownNextCallResult = LuauBytecodeType(hostHooks.userdataNamecallBytecodeType(bcType.a, field, str->len));
1215-
}
1216-
else
1217-
{
1218-
if (bcType.a == LBC_TYPE_VECTOR && hostHooks.vectorNamecallBytecodeType)
1219-
{
1220-
TString* str = gco2ts(function.proto->k[kc].value.gc);
1221-
const char* field = getstr(str);
1222-
1223-
knownNextCallResult = LuauBytecodeType(hostHooks.vectorNamecallBytecodeType(field, str->len));
1224-
}
1225-
}
1185+
if (bcType.a == LBC_TYPE_VECTOR && hostHooks.vectorNamecallBytecodeType)
1186+
knownNextCallResult = LuauBytecodeType(hostHooks.vectorNamecallBytecodeType(field, str->len));
1187+
else if (isCustomUserdataBytecodeType(bcType.a) && hostHooks.userdataNamecallBytecodeType)
1188+
knownNextCallResult = LuauBytecodeType(hostHooks.userdataNamecallBytecodeType(bcType.a, field, str->len));
12261189
break;
12271190
}
12281191
case LOP_CALL:

0 commit comments

Comments
 (0)