@@ -253,7 +253,11 @@ void ConstraintGenerator::visitModuleRoot(AstStatBlock* block)
253
253
// FIXME: This isn't the most efficient thing.
254
254
TypeId domainTy = builtinTypes->neverType ;
255
255
for (TypeId d : domain)
256
+ {
257
+ if (d == ty)
258
+ continue ;
256
259
domainTy = simplifyUnion (builtinTypes, arena, domainTy, d).result ;
260
+ }
257
261
258
262
LUAU_ASSERT (get<BlockedType>(ty));
259
263
asMutable (ty)->ty .emplace <BoundType>(domainTy);
@@ -323,7 +327,7 @@ std::optional<TypeId> ConstraintGenerator::lookup(const ScopePtr& scope, Locatio
323
327
if (!ty)
324
328
{
325
329
ty = arena->addType (BlockedType{});
326
- localTypes[ *ty] = {} ;
330
+ localTypes. try_insert ( *ty, {}) ;
327
331
rootScope->lvalueTypes [operand] = *ty;
328
332
}
329
333
@@ -717,7 +721,7 @@ ControlFlow ConstraintGenerator::visit(const ScopePtr& scope, AstStatLocal* stat
717
721
const Location location = local->location ;
718
722
719
723
TypeId assignee = arena->addType (BlockedType{});
720
- localTypes[ assignee] = {} ;
724
+ localTypes. try_insert ( assignee, {}) ;
721
725
722
726
assignees.push_back (assignee);
723
727
@@ -756,9 +760,9 @@ ControlFlow ConstraintGenerator::visit(const ScopePtr& scope, AstStatLocal* stat
756
760
for (size_t i = 0 ; i < statLocal->vars .size ; ++i)
757
761
{
758
762
LUAU_ASSERT (get<BlockedType>(assignees[i]));
759
- std::vector<TypeId> * localDomain = localTypes.find (assignees[i]);
763
+ TypeIds * localDomain = localTypes.find (assignees[i]);
760
764
LUAU_ASSERT (localDomain);
761
- localDomain->push_back (annotatedTypes[i]);
765
+ localDomain->insert (annotatedTypes[i]);
762
766
}
763
767
764
768
TypePackId annotatedPack = arena->addTypePack (std::move (annotatedTypes));
@@ -790,9 +794,9 @@ ControlFlow ConstraintGenerator::visit(const ScopePtr& scope, AstStatLocal* stat
790
794
for (size_t i = 0 ; i < statLocal->vars .size ; ++i)
791
795
{
792
796
LUAU_ASSERT (get<BlockedType>(assignees[i]));
793
- std::vector<TypeId> * localDomain = localTypes.find (assignees[i]);
797
+ TypeIds * localDomain = localTypes.find (assignees[i]);
794
798
LUAU_ASSERT (localDomain);
795
- localDomain->push_back (valueTypes[i]);
799
+ localDomain->insert (valueTypes[i]);
796
800
}
797
801
}
798
802
@@ -898,7 +902,7 @@ ControlFlow ConstraintGenerator::visit(const ScopePtr& scope, AstStatForIn* forI
898
902
variableTypes.push_back (assignee);
899
903
900
904
TypeId loopVar = arena->addType (BlockedType{});
901
- localTypes[loopVar].push_back (assignee);
905
+ localTypes[loopVar].insert (assignee);
902
906
903
907
if (var->annotation )
904
908
{
@@ -1183,8 +1187,13 @@ ControlFlow ConstraintGenerator::visit(const ScopePtr& scope, AstStatCompoundAss
1183
1187
{
1184
1188
AstExprBinary binop = AstExprBinary{assign->location , assign->op , assign->var , assign->value };
1185
1189
TypeId resultTy = check (scope, &binop).ty ;
1190
+ module ->astCompoundAssignResultTypes [assign] = resultTy;
1191
+
1192
+ TypeId lhsType = check (scope, assign->var ).ty ;
1193
+ visitLValue (scope, assign->var , lhsType);
1186
1194
1187
- visitLValue (scope, assign->var , resultTy);
1195
+ follow (lhsType);
1196
+ follow (resultTy);
1188
1197
1189
1198
return ControlFlow::None;
1190
1199
}
@@ -1383,16 +1392,15 @@ ControlFlow ConstraintGenerator::visit(const ScopePtr& scope, AstStatDeclareClas
1383
1392
}
1384
1393
}
1385
1394
1386
- if (ctv->props .count (propName) == 0 )
1395
+ TableType::Props& props = assignToMetatable ? metatable->props : ctv->props ;
1396
+
1397
+ if (props.count (propName) == 0 )
1387
1398
{
1388
- if (assignToMetatable)
1389
- metatable->props [propName] = {propTy};
1390
- else
1391
- ctv->props [propName] = {propTy};
1399
+ props[propName] = {propTy};
1392
1400
}
1393
1401
else
1394
1402
{
1395
- TypeId currentTy = assignToMetatable ? metatable-> props [propName]. type () : ctv-> props [propName].type ();
1403
+ TypeId currentTy = props[propName].type ();
1396
1404
1397
1405
// We special-case this logic to keep the intersection flat; otherwise we
1398
1406
// would create a ton of nested intersection types.
@@ -1402,19 +1410,13 @@ ControlFlow ConstraintGenerator::visit(const ScopePtr& scope, AstStatDeclareClas
1402
1410
options.push_back (propTy);
1403
1411
TypeId newItv = arena->addType (IntersectionType{std::move (options)});
1404
1412
1405
- if (assignToMetatable)
1406
- metatable->props [propName] = {newItv};
1407
- else
1408
- ctv->props [propName] = {newItv};
1413
+ props[propName] = {newItv};
1409
1414
}
1410
1415
else if (get<FunctionType>(currentTy))
1411
1416
{
1412
1417
TypeId intersection = arena->addType (IntersectionType{{currentTy, propTy}});
1413
1418
1414
- if (assignToMetatable)
1415
- metatable->props [propName] = {intersection};
1416
- else
1417
- ctv->props [propName] = {intersection};
1419
+ props[propName] = {intersection};
1418
1420
}
1419
1421
else
1420
1422
{
@@ -1913,8 +1915,8 @@ Inference ConstraintGenerator::checkIndexName(
1913
1915
// the current lexical position within the script.
1914
1916
if (!tt)
1915
1917
{
1916
- if (auto localDomain = localTypes.find (obj); localDomain && 1 == localDomain->size ())
1917
- tt = getTableType (localDomain->front ());
1918
+ if (TypeIds* localDomain = localTypes.find (obj); localDomain && 1 == localDomain->size ())
1919
+ tt = getTableType (* localDomain->begin ());
1918
1920
}
1919
1921
1920
1922
if (tt)
@@ -2327,14 +2329,14 @@ void ConstraintGenerator::visitLValue(const ScopePtr& scope, AstExprLocal* local
2327
2329
2328
2330
if (ty)
2329
2331
{
2330
- std::vector<TypeId> * localDomain = localTypes.find (*ty);
2332
+ TypeIds * localDomain = localTypes.find (*ty);
2331
2333
if (localDomain)
2332
- localDomain->push_back (rhsType);
2334
+ localDomain->insert (rhsType);
2333
2335
}
2334
2336
else
2335
2337
{
2336
2338
ty = arena->addType (BlockedType{});
2337
- localTypes[*ty].push_back (rhsType);
2339
+ localTypes[*ty].insert (rhsType);
2338
2340
2339
2341
if (annotatedTy)
2340
2342
{
@@ -2359,8 +2361,8 @@ void ConstraintGenerator::visitLValue(const ScopePtr& scope, AstExprLocal* local
2359
2361
if (annotatedTy)
2360
2362
addConstraint (scope, local->location , SubtypeConstraint{rhsType, *annotatedTy});
2361
2363
2362
- if (auto localDomain = localTypes.find (*ty))
2363
- localDomain->push_back (rhsType);
2364
+ if (TypeIds* localDomain = localTypes.find (*ty))
2365
+ localDomain->insert (rhsType);
2364
2366
}
2365
2367
2366
2368
void ConstraintGenerator::visitLValue (const ScopePtr& scope, AstExprGlobal* global, TypeId rhsType)
@@ -2383,7 +2385,8 @@ void ConstraintGenerator::visitLValue(const ScopePtr& scope, AstExprIndexName* e
2383
2385
2384
2386
bool incremented = recordPropertyAssignment (lhsTy);
2385
2387
2386
- addConstraint (scope, expr->location , AssignPropConstraint{lhsTy, expr->index .value , rhsType, propTy, incremented});
2388
+ auto apc = addConstraint (scope, expr->location , AssignPropConstraint{lhsTy, expr->index .value , rhsType, propTy, incremented});
2389
+ getMutable<BlockedType>(propTy)->setOwner (apc);
2387
2390
}
2388
2391
2389
2392
void ConstraintGenerator::visitLValue (const ScopePtr& scope, AstExprIndexExpr* expr, TypeId rhsType)
@@ -2398,7 +2401,8 @@ void ConstraintGenerator::visitLValue(const ScopePtr& scope, AstExprIndexExpr* e
2398
2401
2399
2402
bool incremented = recordPropertyAssignment (lhsTy);
2400
2403
2401
- addConstraint (scope, expr->location , AssignPropConstraint{lhsTy, std::move (propName), rhsType, propTy, incremented});
2404
+ auto apc = addConstraint (scope, expr->location , AssignPropConstraint{lhsTy, std::move (propName), rhsType, propTy, incremented});
2405
+ getMutable<BlockedType>(propTy)->setOwner (apc);
2402
2406
2403
2407
return ;
2404
2408
}
@@ -2407,7 +2411,8 @@ void ConstraintGenerator::visitLValue(const ScopePtr& scope, AstExprIndexExpr* e
2407
2411
TypeId indexTy = check (scope, expr->index ).ty ;
2408
2412
TypeId propTy = arena->addType (BlockedType{});
2409
2413
module ->astTypes [expr] = propTy;
2410
- addConstraint (scope, expr->location , AssignIndexConstraint{lhsTy, indexTy, rhsType, propTy});
2414
+ auto aic = addConstraint (scope, expr->location , AssignIndexConstraint{lhsTy, indexTy, rhsType, propTy});
2415
+ getMutable<BlockedType>(propTy)->setOwner (aic);
2411
2416
}
2412
2417
2413
2418
Inference ConstraintGenerator::check (const ScopePtr& scope, AstExprTable* expr, std::optional<TypeId> expectedType)
@@ -2447,7 +2452,8 @@ Inference ConstraintGenerator::check(const ScopePtr& scope, AstExprTable* expr,
2447
2452
2448
2453
if (AstExprConstantString* key = item.key ->as <AstExprConstantString>())
2449
2454
{
2450
- ttv->props [key->value .begin ()] = {itemTy};
2455
+ std::string propName{key->value .data , key->value .size };
2456
+ ttv->props [propName] = {itemTy};
2451
2457
}
2452
2458
else
2453
2459
{
@@ -3187,7 +3193,7 @@ bool ConstraintGenerator::recordPropertyAssignment(TypeId ty)
3187
3193
}
3188
3194
else if (auto mt = get<MetatableType>(t))
3189
3195
queue.push_back (mt->table );
3190
- else if (auto localDomain = localTypes.find (t))
3196
+ else if (TypeIds* localDomain = localTypes.find (t))
3191
3197
{
3192
3198
for (TypeId domainTy : *localDomain)
3193
3199
queue.push_back (domainTy);
0 commit comments