Skip to content
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
11 changes: 11 additions & 0 deletions Analysis/include/Luau/ConstraintGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,17 @@ struct ConstraintGenerator
Polarity initialPolarity = Polarity::Positive
);

// Clip with LuauForwardPolarityForFunctionTypes
TypePackId resolveTypePack_DEPRECATED(
const ScopePtr& scope,
const AstTypeList& list,
bool inTypeArguments,
bool replaceErrorWithFresh = false,
Polarity initialPolarity = Polarity::Positive
);

TypePackId resolveTypePack_(const ScopePtr& scope, const AstTypeList& list, bool inTypeArguments, bool replaceErrorWithFresh);

/**
* Creates generic types given a list of AST definitions, resolving default
* types as required.
Expand Down
4 changes: 2 additions & 2 deletions Analysis/include/Luau/Frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,13 @@ struct Frontend

size_t dynamicConstraintsCreated = 0;
};

Frontend(SolverMode mode, FileResolver* fileResolver, ConfigResolver* configResolver, FrontendOptions options = {});
Frontend(FileResolver* fileResolver, ConfigResolver* configResolver, const FrontendOptions& options = {});

void setLuauSolverMode(SolverMode mode);
SolverMode getLuauSolverMode() const;
// The default value assuming there is no workspace setup yet
std::atomic<SolverMode> useNewLuauSolver{FFlag::LuauSolverV2 ? SolverMode::New : SolverMode::Old};
std::atomic<SolverMode> useNewLuauSolver;
// Parse module graph and prepare SourceNode/SourceModule data, including required dependencies without running typechecking
void parse(const ModuleName& name);
void parseModules(const std::vector<ModuleName>& name);
Expand Down
11 changes: 10 additions & 1 deletion Analysis/include/Luau/Generalization.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ struct GeneralizationResult
}
};

// Replace a single free type by its bounds according to the polarity provided.
GeneralizationResult<TypeId> generalizeType(
NotNull<TypeArena> arena,
NotNull<BuiltinTypes> builtinTypes,
Expand All @@ -41,6 +40,15 @@ GeneralizationResult<TypeId> generalizeType(
const GeneralizationParams<TypeId>& params
);

// Replace a single free type by its bounds according to the polarity provided.
GeneralizationResult<TypeId> generalizeType_DEPRECATED(
NotNull<TypeArena> arena,
NotNull<BuiltinTypes> builtinTypes,
NotNull<Scope> scope,
TypeId freeTy,
const GeneralizationParams<TypeId>& params
);

// Generalize one type pack
GeneralizationResult<TypePackId> generalizeTypePack(
NotNull<TypeArena> arena,
Expand All @@ -52,6 +60,7 @@ GeneralizationResult<TypePackId> generalizeTypePack(

void sealTable(NotNull<Scope> scope, TypeId ty);


/** Attempt to generalize a type.
*
* If generalizationTarget is set, then only that type will be replaced by its
Expand Down
19 changes: 0 additions & 19 deletions Analysis/include/Luau/InferPolarity.h

This file was deleted.

47 changes: 29 additions & 18 deletions Analysis/include/Luau/Instantiation2.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ namespace Luau
struct TypeArena;
struct TypeCheckLimits;

struct Replacer : Substitution
struct Replacer_DEPRECATED : Substitution
{
DenseHashMap<TypeId, TypeId> replacements;
DenseHashMap<TypePackId, TypePackId> replacementPacks;

Replacer(NotNull<TypeArena> arena, DenseHashMap<TypeId, TypeId> replacements, DenseHashMap<TypePackId, TypePackId> replacementPacks)
Replacer_DEPRECATED(NotNull<TypeArena> arena, DenseHashMap<TypeId, TypeId> replacements, DenseHashMap<TypePackId, TypePackId> replacementPacks)
: Substitution(TxnLog::empty(), arena)
, replacements(std::move(replacements))
, replacementPacks(std::move(replacementPacks))
Expand Down Expand Up @@ -53,6 +53,33 @@ struct Replacer : Substitution
}
};

struct Replacer : Substitution
{
NotNull<DenseHashMap<TypeId, TypeId>> replacements;
NotNull<DenseHashMap<TypePackId, TypePackId>> replacementPacks;

Replacer(NotNull<TypeArena> arena, NotNull<DenseHashMap<TypeId, TypeId>> replacements, NotNull<DenseHashMap<TypePackId, TypePackId>> replacementPacks);

bool isDirty(TypeId ty) override;

bool isDirty(TypePackId tp) override;

TypeId clean(TypeId ty) override;

TypePackId clean(TypePackId tp) override;

bool ignoreChildren(TypeId ty) override;

private:
/**
* It is *very* easy to create the world's worst bug by using a bound type
* as key: this is a helper function we run in debug mode to confirm this
* isn't the case.
*/
bool checkReplacementKeys() const;

};

// A substitution which replaces generic functions by monomorphic functions
struct Instantiation2 final : Substitution
{
Expand Down Expand Up @@ -94,22 +121,6 @@ struct Instantiation2 final : Substitution
TypePackId clean(TypePackId tp) override;
};

// Clip with LuauInstantiationUsesGenericPolarity
std::optional<TypeId> instantiate2_DEPRECATED(
TypeArena* arena,
DenseHashMap<TypeId, TypeId> genericSubstitutions,
DenseHashMap<TypePackId, TypePackId> genericPackSubstitutions,
TypeId ty
);

// Clip with LuauInstantiationUsesGenericPolarity
std::optional<TypePackId> instantiate2_DEPRECATED(
TypeArena* arena,
DenseHashMap<TypeId, TypeId> genericSubstitutions,
DenseHashMap<TypePackId, TypePackId> genericPackSubstitutions,
TypePackId tp
);

std::optional<TypeId> instantiate2(
TypeArena* arena,
DenseHashMap<TypeId, TypeId> genericSubstitutions,
Expand Down
12 changes: 0 additions & 12 deletions Analysis/include/Luau/TableLiteralInference.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,6 @@ struct PushTypeResult
std::vector<IncompleteInference> incompleteTypes;
};

// Clip with LuauPushTypeConstraintLambdas3
PushTypeResult pushTypeInto_DEPRECATED(
NotNull<DenseHashMap<const AstExpr*, TypeId>> astTypes,
NotNull<DenseHashMap<const AstExpr*, TypeId>> astExpectedTypes,
NotNull<ConstraintSolver> solver,
NotNull<const Constraint> constraint,
NotNull<Unifier2> unifier,
NotNull<Subtyping> subtyping,
TypeId expectedType,
const AstExpr* expr
);

PushTypeResult pushTypeInto(
NotNull<DenseHashMap<const AstExpr*, TypeId>> astTypes,
NotNull<DenseHashMap<const AstExpr*, TypeId>> astExpectedTypes,
Expand Down
2 changes: 2 additions & 0 deletions Analysis/include/Luau/Unifier2.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ struct Unifier2
UnifyResult unify_(const MetatableType* subMetatable, const AnyType*);
UnifyResult unify_(const AnyType*, const MetatableType* superMetatable);

UnifyResult unify_DEPRECATED(TypePackId subTp, TypePackId superTp);

UnifyResult unify_(TypePackId subTp, TypePackId superTp);

std::optional<TypeId> generalize(TypeId ty);
Expand Down
4 changes: 4 additions & 0 deletions Analysis/src/AstJsonEncoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#include <math.h>

LUAU_FASTFLAG(LuauConst)

namespace Luau
{

Expand Down Expand Up @@ -241,6 +243,8 @@ struct AstJsonEncoder : public AstVisitor
else
write("luauType", nullptr);
write("name", local->name);
if (FFlag::LuauConst)
write("isConst", local->isConst);
writeType("AstLocal");
write("location", local->location);
popComma(c);
Expand Down
6 changes: 6 additions & 0 deletions Analysis/src/AutocompleteCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,11 @@ static void autocompleteProps(
auto indexIt = mtable->props.find("__index");
if (indexIt != mtable->props.end())
{
#ifndef __EMSCRIPTEN__
// EMSDK cannot compile the flag-off branch, so force the flag on with defines here.
// Delete these conditionals when this flag is removed.
if (FFlag::LuauACOnMTTWriteOnlyPropNoCrash)
#endif
{
TypeId followed = indexIt->second.readTy.value_or(nullptr);
if (followed == nullptr)
Expand All @@ -418,6 +422,7 @@ static void autocompleteProps(
autocompleteProps(module, typeArena, builtinTypes, rootTy, *indexFunctionResult, indexType, nodes, result, seen);
}
}
#ifndef __EMSCRIPTEN__
else
{
TypeId followed;
Expand All @@ -436,6 +441,7 @@ static void autocompleteProps(
autocompleteProps(module, typeArena, builtinTypes, rootTy, *indexFunctionResult, indexType, nodes, result, seen);
}
}
#endif
}
};

Expand Down
43 changes: 18 additions & 25 deletions Analysis/src/BuiltinDefinitions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include "Luau/DenseHash.h"
#include "Luau/Error.h"
#include "Luau/Frontend.h"
#include "Luau/InferPolarity.h"
#include "Luau/Module.h"
#include "Luau/NotNull.h"
#include "Luau/Subtyping.h"
Expand All @@ -34,9 +33,9 @@
LUAU_FASTFLAG(LuauSolverV2)
LUAU_FASTFLAGVARIABLE(LuauTableCloneClonesType4)
LUAU_FASTFLAGVARIABLE(LuauCloneForIntersectionsUnions)
LUAU_FASTFLAG(LuauStorePolarityInline)
LUAU_FASTFLAGVARIABLE(LuauTableFreezeCheckIsSubtype)
LUAU_FASTFLAG(LuauAnalysisUsesSolverMode)
LUAU_FASTFLAGVARIABLE(LuauSilenceDynamicFormatStringErrors)

namespace Luau
{
Expand Down Expand Up @@ -297,8 +296,6 @@ void addGlobalBinding(GlobalTypes& globals, const ScopePtr& scope, const std::st

void addGlobalBinding(GlobalTypes& globals, const ScopePtr& scope, const std::string& name, Binding binding)
{
if (!FFlag::LuauStorePolarityInline)
inferGenericPolarities_DEPRECATED(NotNull{&globals.globalTypes}, NotNull{scope.get()}, binding.typeId);
scope->bindings[globals.globalNames.names->getOrAdd(name.c_str())] = binding;
}

Expand Down Expand Up @@ -372,10 +369,8 @@ void registerBuiltinGlobals(Frontend& frontend, GlobalTypes& globals, bool typeC
);
LUAU_ASSERT(loadResult.success);

TypeId genericK =
FFlag::LuauStorePolarityInline ? arena.addType(GenericType{globalScope, "K", Polarity::Mixed}) : arena.addType(GenericType{globalScope, "K"});
TypeId genericV =
FFlag::LuauStorePolarityInline ? arena.addType(GenericType{globalScope, "V", Polarity::Mixed}) : arena.addType(GenericType{globalScope, "V"});
TypeId genericK = arena.addType(GenericType{globalScope, "K", Polarity::Mixed});
TypeId genericV = arena.addType(GenericType{globalScope, "V", Polarity::Mixed});
TypeId mapOfKtoV = arena.addType(TableType{{}, TableIndexer(genericK, genericV), globals.globalScope->level, TableState::Generic});

std::optional<TypeId> stringMetatableTy = getMetatable(builtinTypes->stringType, builtinTypes);
Expand Down Expand Up @@ -424,16 +419,14 @@ void registerBuiltinGlobals(Frontend& frontend, GlobalTypes& globals, bool typeC
// pairs<K, V>(t: Table<K, V>) -> ((Table<K, V>, K?) -> (K, V), Table<K, V>, nil)
addGlobalBinding(globals, "pairs", arena.addType(FunctionType{{genericK, genericV}, {}, pairsArgsTypePack, pairsReturnTypePack}), "@luau");

TypeId genericMT = FFlag::LuauStorePolarityInline ? arena.addType(GenericType{globalScope, "MT", Polarity::Mixed})
: arena.addType(GenericType{globalScope, "MT"});
TypeId genericMT = arena.addType(GenericType{globalScope, "MT", Polarity::Mixed});

TableType tab{TableState::Generic, globals.globalScope->level};
TypeId tabTy = arena.addType(std::move(tab));

TypeId tableMetaMT = arena.addType(MetatableType{tabTy, genericMT});

TypeId genericT =
FFlag::LuauStorePolarityInline ? arena.addType(GenericType{globalScope, "T", Polarity::Mixed}) : arena.addType(GenericType{globalScope, "T"});
TypeId genericT = arena.addType(GenericType{globalScope, "T", Polarity::Mixed});

if (frontend.getLuauSolverMode() == SolverMode::New)
{
Expand Down Expand Up @@ -479,8 +472,7 @@ void registerBuiltinGlobals(Frontend& frontend, GlobalTypes& globals, bool typeC
if (frontend.getLuauSolverMode() == SolverMode::New)
{
// declare function assert<T>(value: T, errorMessage: string?): intersect<T, ~(false?)>
TypeId genericT = FFlag::LuauStorePolarityInline ? arena.addType(GenericType{globalScope, "T", Polarity::Mixed})
: arena.addType(GenericType{globalScope, "T"});
TypeId genericT = arena.addType(GenericType{globalScope, "T", Polarity::Mixed});

TypeId refinedTy = arena.addType(
TypeFunctionInstanceType{
Expand Down Expand Up @@ -508,20 +500,13 @@ void registerBuiltinGlobals(Frontend& frontend, GlobalTypes& globals, bool typeC
// the top table type. We do the best we can by modelling these
// functions using unconstrained generics. It's not quite right,
// but it'll be ok for now.
TypeId genericTy = FFlag::LuauStorePolarityInline ? arena.addType(GenericType{globalScope, "T", Polarity::Mixed})
: arena.addType(GenericType{globalScope, "T"});
TypeId genericTy = arena.addType(GenericType{globalScope, "T", Polarity::Mixed});
TypePackId thePack = arena.addTypePack({genericTy});
TypeId idTyWithMagic = arena.addType(FunctionType{{genericTy}, {}, thePack, thePack});
ttv->props["freeze"] = makeProperty(idTyWithMagic, "@luau/global/table.freeze");

if (!FFlag::LuauStorePolarityInline)
inferGenericPolarities_DEPRECATED(NotNull{&globals.globalTypes}, NotNull{globalScope}, idTyWithMagic);

TypeId idTy = arena.addType(FunctionType{{genericTy}, {}, thePack, thePack});

if (!FFlag::LuauStorePolarityInline)
inferGenericPolarities_DEPRECATED(NotNull{&globals.globalTypes}, NotNull{globalScope}, idTy);

ttv->props["clone"] = makeProperty(idTy, "@luau/global/table.clone");
}
else
Expand Down Expand Up @@ -773,10 +758,18 @@ bool MagicFormat::typeCheck(const MagicFunctionTypeCheckContext& context)
formatString = {stringSingleton->value};
}

if (!formatString)
if (FFlag::LuauSilenceDynamicFormatStringErrors)
{
context.typechecker->reportError(CannotCheckDynamicStringFormatCalls{}, context.callSite->location);
return true;
if (!formatString)
return true;
}
else
{
if (!formatString)
{
context.typechecker->reportError(CannotCheckDynamicStringFormatCalls{}, context.callSite->location);
return true;
}
}

// CLI-150726: The block below effectively constructs a type pack and then type checks it by going parameter-by-parameter.
Expand Down
Loading