Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync to upstream/release/656 #1612

Merged
merged 3 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion Analysis/include/Luau/FragmentAutocomplete.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ namespace Luau
{
struct FrontendOptions;

enum class FragmentTypeCheckStatus
{
Success,
SkipAutocomplete,
};

struct FragmentAutocompleteAncestryResult
{
DenseHashMap<AstName, AstLocal*> localMap{AstName()};
Expand All @@ -29,6 +35,7 @@ struct FragmentParseResult
AstStatBlock* root = nullptr;
std::vector<AstNode*> ancestry;
AstStat* nearestStatement = nullptr;
std::vector<Comment> commentLocations;
std::unique_ptr<Allocator> alloc = std::make_unique<Allocator>();
};

Expand Down Expand Up @@ -56,7 +63,7 @@ FragmentParseResult parseFragment(
std::optional<Position> fragmentEndPosition
);

FragmentTypeCheckResult typecheckFragment(
std::pair<FragmentTypeCheckStatus, FragmentTypeCheckResult> typecheckFragment(
Frontend& frontend,
const ModuleName& moduleName,
const Position& cursorPos,
Expand Down
3 changes: 3 additions & 0 deletions Analysis/include/Luau/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include <unordered_map>
#include <optional>

LUAU_FASTFLAG(LuauIncrementalAutocompleteCommentDetection)

namespace Luau
{

Expand Down Expand Up @@ -55,6 +57,7 @@ struct SourceModule
}
};

bool isWithinComment(const std::vector<Comment>& commentLocations, Position pos);
bool isWithinComment(const SourceModule& sourceModule, Position pos);
bool isWithinComment(const ParseResult& result, Position pos);

Expand Down
2 changes: 2 additions & 0 deletions Analysis/include/Luau/Scope.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ struct Scope
// we need that the generic type `T` in both cases is the same, so we use a cache.
std::unordered_map<Name, TypeId> typeAliasTypeParameters;
std::unordered_map<Name, TypePackId> typeAliasTypePackParameters;

std::optional<std::vector<TypeId>> interiorFreeTypes;
};

// Returns true iff the left scope encloses the right scope. A Scope* equal to
Expand Down
2 changes: 1 addition & 1 deletion Analysis/include/Luau/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ struct TypeFunctionInstanceType
std::vector<TypeId> typeArguments;
std::vector<TypePackId> packArguments;

std::optional<AstName> userFuncName; // Name of the user-defined type function; only available for UDTFs
std::optional<AstName> userFuncName; // Name of the user-defined type function; only available for UDTFs
UserDefinedFunctionData userFuncData;

TypeFunctionInstanceType(
Expand Down
2 changes: 1 addition & 1 deletion Analysis/include/Luau/TypeFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ struct TypeFunctionContext
// The constraint being reduced in this run of the reduction
const Constraint* constraint;

std::optional<AstName> userFuncName; // Name of the user-defined type function; only available for UDTFs
std::optional<AstName> userFuncName; // Name of the user-defined type function; only available for UDTFs

TypeFunctionContext(NotNull<ConstraintSolver> cs, NotNull<Scope> scope, NotNull<const Constraint> constraint);

Expand Down
13 changes: 11 additions & 2 deletions Analysis/include/Luau/TypeUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,8 @@ bool isLiteral(const AstExpr* expr);
std::vector<TypeId> findBlockedTypesIn(AstExprTable* expr, NotNull<DenseHashMap<const AstExpr*, TypeId>> astTypes);

/**
* Given a function call and a mapping from expression to type, determine
* whether the type of any argument in said call in depends on a blocked types.
* Given a function call and a mapping from expression to type, determine
* whether the type of any argument in said call in depends on a blocked types.
* This is used as a precondition for bidirectional inference: be warned that
* the behavior of this algorithm is tightly coupled to that of bidirectional
* inference.
Expand All @@ -280,4 +280,13 @@ std::vector<TypeId> findBlockedTypesIn(AstExprTable* expr, NotNull<DenseHashMap<
*/
std::vector<TypeId> findBlockedArgTypesIn(AstExprCall* expr, NotNull<DenseHashMap<const AstExpr*, TypeId>> astTypes);

/**
* Given a scope and a free type, find the closest parent that has a present
* `interiorFreeTypes` and append the given type to said list. This list will
* be generalized when the requiste `GeneralizationConstraint` is resolved.
* @param scope Initial scope this free type was attached to
* @param ty Free type to track.
*/
void trackInteriorFreeType(Scope* scope, TypeId ty);

} // namespace Luau
1 change: 0 additions & 1 deletion Analysis/src/AnyTypeSummary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,6 @@ void AnyTypeSummary::visit(const Scope* scope, AstStatReturn* ret, const Module*
}
}
}

}

void AnyTypeSummary::visit(const Scope* scope, AstStatLocal* local, const Module* module, NotNull<BuiltinTypes> builtinTypes)
Expand Down
7 changes: 7 additions & 0 deletions Analysis/src/AutocompleteCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ LUAU_FASTINT(LuauTypeInferIterationLimit)
LUAU_FASTINT(LuauTypeInferRecursionLimit)

LUAU_FASTFLAGVARIABLE(LuauAutocompleteRefactorsForIncrementalAutocomplete)
LUAU_FASTFLAGVARIABLE(LuauAutocompleteUseLimits)

static const std::unordered_set<std::string> kStatementStartingKeywords =
{"while", "if", "local", "repeat", "function", "do", "for", "return", "break", "continue", "type", "export"};
Expand Down Expand Up @@ -177,6 +178,12 @@ static bool checkTypeMatch(TypeId subTy, TypeId superTy, NotNull<Scope> scope, T
unifier.normalize = false;
unifier.checkInhabited = false;

if (FFlag::LuauAutocompleteUseLimits)
{
unifierState.counters.recursionLimit = FInt::LuauTypeInferRecursionLimit;
unifierState.counters.iterationLimit = FInt::LuauTypeInferIterationLimit;
}

return unifier.canUnify(subTy, superTy).empty();
}
}
Expand Down
4 changes: 3 additions & 1 deletion Analysis/src/BuiltinDefinitions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,9 @@ static void dcrMagicFunctionTypeCheckFormat(MagicFunctionTypeCheckContext contex
if (!fmt)
{
if (FFlag::LuauStringFormatArityFix)
context.typechecker->reportError(CountMismatch{1, std::nullopt, 0, CountMismatch::Arg, true, "string.format"}, context.callSite->location);
context.typechecker->reportError(
CountMismatch{1, std::nullopt, 0, CountMismatch::Arg, true, "string.format"}, context.callSite->location
);
return;
}

Expand Down
1 change: 0 additions & 1 deletion Analysis/src/Constraint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ struct ReferenceCountInitializer : TypeOnceVisitor
// of this type, hence:
return !FFlag::LuauDontRefCountTypesInTypeFunctions;
}

};

bool isReferenceCountedType(const TypeId typ)
Expand Down
67 changes: 41 additions & 26 deletions Analysis/src/ConstraintGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@
LUAU_FASTINT(LuauCheckRecursionLimit)
LUAU_FASTFLAG(DebugLuauLogSolverToJson)
LUAU_FASTFLAG(DebugLuauMagicTypes)
LUAU_FASTFLAG(DebugLuauEqSatSimplification)
LUAU_FASTFLAG(LuauTypestateBuiltins2)
LUAU_FASTFLAG(LuauUserTypeFunUpdateAllEnvs)

LUAU_FASTFLAGVARIABLE(LuauNewSolverVisitErrorExprLvalues)
LUAU_FASTFLAGVARIABLE(LuauNewSolverPrePopulateClasses)
LUAU_FASTFLAGVARIABLE(LuauUserTypeFunExportedAndLocal)
LUAU_FASTFLAGVARIABLE(LuauNewSolverPrePopulateClasses)
LUAU_FASTFLAGVARIABLE(LuauNewSolverPopulateTableLocations)
LUAU_FASTFLAGVARIABLE(LuauUserTypeFunNoExtraConstraint)
LUAU_FASTFLAGVARIABLE(LuauTrackInteriorFreeTypesOnScope)

LUAU_FASTFLAGVARIABLE(InferGlobalTypes)

Expand Down Expand Up @@ -233,8 +233,17 @@ void ConstraintGenerator::visitModuleRoot(AstStatBlock* block)
Checkpoint end = checkpoint(this);

TypeId result = arena->addType(BlockedType{});
NotNull<Constraint> genConstraint =
addConstraint(scope, block->location, GeneralizationConstraint{result, moduleFnTy, std::move(interiorTypes.back())});
NotNull<Constraint> genConstraint = addConstraint(
scope,
block->location,
GeneralizationConstraint{
result, moduleFnTy, FFlag::LuauTrackInteriorFreeTypesOnScope ? std::vector<TypeId>{} : std::move(interiorTypes.back())
}
);

if (FFlag::LuauTrackInteriorFreeTypesOnScope)
scope->interiorFreeTypes = std::move(interiorTypes.back());

getMutable<BlockedType>(result)->setOwner(genConstraint);
forEachConstraint(
start,
Expand Down Expand Up @@ -303,9 +312,19 @@ void ConstraintGenerator::visitFragmentRoot(const ScopePtr& resumeScope, AstStat
}
}


TypeId ConstraintGenerator::freshType(const ScopePtr& scope)
{
return Luau::freshType(arena, builtinTypes, scope.get());
if (FFlag::LuauTrackInteriorFreeTypesOnScope)
{
auto ft = Luau::freshType(arena, builtinTypes, scope.get());
interiorTypes.back().push_back(ft);
return ft;
}
else
{
return Luau::freshType(arena, builtinTypes, scope.get());
}
}

TypePackId ConstraintGenerator::freshTypePack(const ScopePtr& scope)
Expand Down Expand Up @@ -2408,8 +2427,17 @@ Inference ConstraintGenerator::check(const ScopePtr& scope, AstExprFunction* fun
Checkpoint endCheckpoint = checkpoint(this);

TypeId generalizedTy = arena->addType(BlockedType{});
NotNull<Constraint> gc =
addConstraint(sig.signatureScope, func->location, GeneralizationConstraint{generalizedTy, sig.signature, std::move(interiorTypes.back())});
NotNull<Constraint> gc = addConstraint(
sig.signatureScope,
func->location,
GeneralizationConstraint{
generalizedTy, sig.signature, FFlag::LuauTrackInteriorFreeTypesOnScope ? std::vector<TypeId>{} : std::move(interiorTypes.back())
}
);

if (FFlag::LuauTrackInteriorFreeTypesOnScope)
sig.signatureScope->interiorFreeTypes = std::move(interiorTypes.back());

getMutable<BlockedType>(generalizedTy)->setOwner(gc);
interiorTypes.pop_back();

Expand Down Expand Up @@ -2975,11 +3003,11 @@ Inference ConstraintGenerator::check(const ScopePtr& scope, AstExprTable* expr,
ty,
expr,
toBlock
);
// The visitor we ran prior should ensure that there are no
// blocked types that we would encounter while matching on
// this expression.
LUAU_ASSERT(toBlock.empty());
);
// The visitor we ran prior should ensure that there are no
// blocked types that we would encounter while matching on
// this expression.
LUAU_ASSERT(toBlock.empty());
}
}

Expand Down Expand Up @@ -3941,20 +3969,7 @@ TypeId ConstraintGenerator::createTypeFunctionInstance(

TypeId ConstraintGenerator::simplifyUnion(const ScopePtr& scope, Location location, TypeId left, TypeId right)
{
if (FFlag::DebugLuauEqSatSimplification)
{
TypeId ty = arena->addType(UnionType{{left, right}});
std::optional<EqSatSimplificationResult> res = eqSatSimplify(simplifier, ty);
if (!res)
return ty;

for (TypeId tyFun : res->newTypeFunctions)
addConstraint(scope, location, ReduceConstraint{tyFun});

return res->result;
}
else
return ::Luau::simplifyUnion(builtinTypes, arena, left, right).result;
return ::Luau::simplifyUnion(builtinTypes, arena, left, right).result;
}

std::vector<NotNull<Constraint>> borrowConstraints(const std::vector<ConstraintPtr>& constraints)
Expand Down
34 changes: 32 additions & 2 deletions Analysis/src/ConstraintSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ LUAU_FASTFLAGVARIABLE(DebugLuauEqSatSimplification)
LUAU_FASTFLAG(LuauNewSolverPopulateTableLocations)
LUAU_FASTFLAGVARIABLE(LuauAllowNilAssignmentToIndexer)
LUAU_FASTFLAG(LuauUserTypeFunNoExtraConstraint)
LUAU_FASTFLAG(LuauTrackInteriorFreeTypesOnScope)

namespace Luau
{
Expand Down Expand Up @@ -724,8 +725,20 @@ bool ConstraintSolver::tryDispatch(const GeneralizationConstraint& c, NotNull<co
bind(constraint, c.generalizedType, builtinTypes->errorRecoveryType());
}

for (TypeId ty : c.interiorTypes)
generalize(NotNull{arena}, builtinTypes, constraint->scope, generalizedTypes, ty, /* avoidSealingTables */ false);
if (FFlag::LuauTrackInteriorFreeTypesOnScope)
{
// We check if this member is initialized and then access it, but
// clang-tidy doesn't understand this is safe.
if (constraint->scope->interiorFreeTypes)
for (TypeId ty : *constraint->scope->interiorFreeTypes) // NOLINT(bugprone-unchecked-optional-access)
generalize(NotNull{arena}, builtinTypes, constraint->scope, generalizedTypes, ty, /* avoidSealingTables */ false);
}
else
{
for (TypeId ty : c.interiorTypes)
generalize(NotNull{arena}, builtinTypes, constraint->scope, generalizedTypes, ty, /* avoidSealingTables */ false);
}


return true;
}
Expand Down Expand Up @@ -801,6 +814,11 @@ bool ConstraintSolver::tryDispatch(const IterableConstraint& c, NotNull<const Co
{
TypeId keyTy = freshType(arena, builtinTypes, constraint->scope);
TypeId valueTy = freshType(arena, builtinTypes, constraint->scope);
if (FFlag::LuauTrackInteriorFreeTypesOnScope)
{
trackInteriorFreeType(constraint->scope, keyTy);
trackInteriorFreeType(constraint->scope, valueTy);
}
TypeId tableTy =
arena->addType(TableType{TableType::Props{}, TableIndexer{keyTy, valueTy}, TypeLevel{}, constraint->scope, TableState::Free});

Expand Down Expand Up @@ -2062,6 +2080,8 @@ bool ConstraintSolver::tryDispatch(const UnpackConstraint& c, NotNull<const Cons
// constitute any meaningful constraint, so we replace it
// with a free type.
TypeId f = freshType(arena, builtinTypes, constraint->scope);
if (FFlag::LuauTrackInteriorFreeTypesOnScope)
trackInteriorFreeType(constraint->scope, f);
shiftReferences(resultTy, f);
emplaceType<BoundType>(asMutable(resultTy), f);
}
Expand Down Expand Up @@ -2197,6 +2217,11 @@ bool ConstraintSolver::tryDispatchIterableTable(TypeId iteratorTy, const Iterabl
{
TypeId keyTy = freshType(arena, builtinTypes, constraint->scope);
TypeId valueTy = freshType(arena, builtinTypes, constraint->scope);
if (FFlag::LuauTrackInteriorFreeTypesOnScope)
{
trackInteriorFreeType(constraint->scope, keyTy);
trackInteriorFreeType(constraint->scope, valueTy);
}
TypeId tableTy = arena->addType(TableType{TableState::Sealed, {}, constraint->scope});
getMutable<TableType>(tableTy)->indexer = TableIndexer{keyTy, valueTy};

Expand Down Expand Up @@ -2453,6 +2478,8 @@ TablePropLookupResult ConstraintSolver::lookupTableProp(
if (ttv->state == TableState::Free)
{
TypeId result = freshType(arena, builtinTypes, ttv->scope);
if (FFlag::LuauTrackInteriorFreeTypesOnScope)
trackInteriorFreeType(ttv->scope, result);
switch (context)
{
case ValueContext::RValue:
Expand Down Expand Up @@ -2562,6 +2589,9 @@ TablePropLookupResult ConstraintSolver::lookupTableProp(
LUAU_ASSERT(tt);
TypeId propType = freshType(arena, builtinTypes, scope);

if (FFlag::LuauTrackInteriorFreeTypesOnScope)
trackInteriorFreeType(scope, propType);

switch (context)
{
case ValueContext::RValue:
Expand Down
Loading
Loading