Skip to content

Commit

Permalink
Sync to upstream/release/553 (#742)
Browse files Browse the repository at this point in the history
* Type inference of `a and b` and `a or b` has been improved (Fixes
#730)
* Improved error message when `for ... in x` loop iterates over a value
that could be 'nil'
* Return type of `next` not includes 'nil' (Fixes
#706)
* Improved type inference of `string` type
* Luau library table type names are now reported as `typeof(string)`/etc
instead of just `string` which was misleading
* Added parsing error when optional type alias type parameter wasn't
provided after `=` token
* Improved tagged union type refinement in conditional expressions, type
in `else` branch should no longer include previously handled union
options
  • Loading branch information
vegorov-rbx authored Nov 10, 2022
1 parent 0f04d52 commit 816e41a
Show file tree
Hide file tree
Showing 44 changed files with 1,531 additions and 578 deletions.
20 changes: 10 additions & 10 deletions Analysis/include/Luau/ConstraintGraphBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ struct ConstraintGraphBuilder
// The root scope of the module we're generating constraints for.
// This is null when the CGB is initially constructed.
Scope* rootScope;

// Constraints that go straight to the solver.
std::vector<ConstraintPtr> constraints;

// Constraints that do not go to the solver right away. Other constraints
// will enqueue them during solving.
std::vector<ConstraintPtr> unqueuedConstraints;

// A mapping of AST node to TypeId.
DenseHashMap<const AstExpr*, TypeId> astTypes{nullptr};
// A mapping of AST node to TypePackId.
Expand Down Expand Up @@ -252,16 +260,8 @@ struct ConstraintGraphBuilder
void prepopulateGlobalScope(const ScopePtr& globalScope, AstStatBlock* program);
};

/**
* Collects a vector of borrowed constraints from the scope and all its child
* scopes. It is important to only call this function when you're done adding
* constraints to the scope or its descendants, lest the borrowed pointers
* become invalid due to a container reallocation.
* @param rootScope the root scope of the scope graph to collect constraints
* from.
* @return a list of pointers to constraints contained within the scope graph.
* None of these pointers should be null.
/** Borrow a vector of pointers from a vector of owning pointers to constraints.
*/
std::vector<NotNull<Constraint>> collectConstraints(NotNull<Scope> rootScope);
std::vector<NotNull<Constraint>> borrowConstraints(const std::vector<ConstraintPtr>& constraints);

} // namespace Luau
4 changes: 2 additions & 2 deletions Analysis/include/Luau/ConstraintSolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ struct ConstraintSolver

DcrLogger* logger;

explicit ConstraintSolver(NotNull<Normalizer> normalizer, NotNull<Scope> rootScope, ModuleName moduleName, NotNull<ModuleResolver> moduleResolver,
std::vector<RequireCycle> requireCycles, DcrLogger* logger);
explicit ConstraintSolver(NotNull<Normalizer> normalizer, NotNull<Scope> rootScope, std::vector<NotNull<Constraint>> constraints,
ModuleName moduleName, NotNull<ModuleResolver> moduleResolver, std::vector<RequireCycle> requireCycles, DcrLogger* logger);

// Randomize the order in which to dispatch constraints
void randomize(unsigned seed);
Expand Down
5 changes: 0 additions & 5 deletions Analysis/include/Luau/Scope.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,6 @@ struct Scope
std::unordered_map<Symbol, Binding> bindings;
TypePackId returnType;
std::optional<TypePackId> varargPack;
// All constraints belonging to this scope.
std::vector<ConstraintPtr> constraints;
// Constraints belonging to this scope that are queued manually by other
// constraints.
std::vector<ConstraintPtr> unqueuedConstraints;

TypeLevel level;

Expand Down
2 changes: 0 additions & 2 deletions Analysis/include/Luau/ToString.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,13 @@ struct ToStringOptions
size_t maxTableLength = size_t(FInt::LuauTableTypeMaximumStringifierLength); // Only applied to TableTypeVars
size_t maxTypeLength = size_t(FInt::LuauTypeMaximumStringifierLength);
ToStringNameMap nameMap;
std::optional<ToStringNameMap> DEPRECATED_nameMap;
std::shared_ptr<Scope> scope; // If present, module names will be added and types that are not available in scope will be marked as 'invalid'
std::vector<std::string> namedFunctionOverrideArgNames; // If present, named function argument names will be overridden
};

struct ToStringResult
{
std::string name;
ToStringNameMap DEPRECATED_nameMap;

bool invalid = false;
bool error = false;
Expand Down
4 changes: 2 additions & 2 deletions Analysis/include/Luau/TypeInfer.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,14 +280,14 @@ struct TypeChecker
TypeId singletonType(bool value);
TypeId singletonType(std::string value);

TypeIdPredicate mkTruthyPredicate(bool sense);
TypeIdPredicate mkTruthyPredicate(bool sense, TypeId emptySetTy);

// TODO: Return TypeId only.
std::optional<TypeId> filterMapImpl(TypeId type, TypeIdPredicate predicate);
std::pair<std::optional<TypeId>, bool> filterMap(TypeId type, TypeIdPredicate predicate);

public:
std::pair<std::optional<TypeId>, bool> pickTypesFromSense(TypeId type, bool sense);
std::pair<std::optional<TypeId>, bool> pickTypesFromSense(TypeId type, bool sense, TypeId emptySetTy);

private:
TypeId unionOfTypes(TypeId a, TypeId b, const ScopePtr& scope, const Location& location, bool unifyFreeTypes = true);
Expand Down
94 changes: 73 additions & 21 deletions Analysis/src/BuiltinDefinitions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
LUAU_FASTFLAGVARIABLE(LuauSetMetaTableArgsCheck, false)
LUAU_FASTFLAG(LuauUnknownAndNeverType)
LUAU_FASTFLAGVARIABLE(LuauBuiltInMetatableNoBadSynthetic, false)
LUAU_FASTFLAG(LuauOptionalNextKey)
LUAU_FASTFLAG(LuauReportShadowedTypeAlias)
LUAU_FASTFLAG(LuauNewLibraryTypeNames)

/** FIXME: Many of these type definitions are not quite completely accurate.
*
Expand Down Expand Up @@ -276,18 +278,38 @@ void registerBuiltinGlobals(TypeChecker& typeChecker)

addGlobalBinding(typeChecker, "string", it->second.type, "@luau");

// next<K, V>(t: Table<K, V>, i: K?) -> (K, V)
TypePackId nextArgsTypePack = arena.addTypePack(TypePack{{mapOfKtoV, makeOption(typeChecker, arena, genericK)}});
addGlobalBinding(typeChecker, "next",
arena.addType(FunctionTypeVar{{genericK, genericV}, {}, nextArgsTypePack, arena.addTypePack(TypePack{{genericK, genericV}})}), "@luau");
if (FFlag::LuauOptionalNextKey)
{
// next<K, V>(t: Table<K, V>, i: K?) -> (K?, V)
TypePackId nextArgsTypePack = arena.addTypePack(TypePack{{mapOfKtoV, makeOption(typeChecker, arena, genericK)}});
TypePackId nextRetsTypePack = arena.addTypePack(TypePack{{makeOption(typeChecker, arena, genericK), genericV}});
addGlobalBinding(typeChecker, "next", arena.addType(FunctionTypeVar{{genericK, genericV}, {}, nextArgsTypePack, nextRetsTypePack}), "@luau");

TypePackId pairsArgsTypePack = arena.addTypePack({mapOfKtoV});

TypeId pairsNext = arena.addType(FunctionTypeVar{nextArgsTypePack, nextRetsTypePack});
TypePackId pairsReturnTypePack = arena.addTypePack(TypePack{{pairsNext, mapOfKtoV, nilType}});

TypePackId pairsArgsTypePack = arena.addTypePack({mapOfKtoV});
// pairs<K, V>(t: Table<K, V>) -> ((Table<K, V>, K?) -> (K, V), Table<K, V>, nil)
addGlobalBinding(
typeChecker, "pairs", arena.addType(FunctionTypeVar{{genericK, genericV}, {}, pairsArgsTypePack, pairsReturnTypePack}), "@luau");
}
else
{
// next<K, V>(t: Table<K, V>, i: K?) -> (K, V)
TypePackId nextArgsTypePack = arena.addTypePack(TypePack{{mapOfKtoV, makeOption(typeChecker, arena, genericK)}});
addGlobalBinding(typeChecker, "next",
arena.addType(FunctionTypeVar{{genericK, genericV}, {}, nextArgsTypePack, arena.addTypePack(TypePack{{genericK, genericV}})}), "@luau");

TypeId pairsNext = arena.addType(FunctionTypeVar{nextArgsTypePack, arena.addTypePack(TypePack{{genericK, genericV}})});
TypePackId pairsReturnTypePack = arena.addTypePack(TypePack{{pairsNext, mapOfKtoV, nilType}});
TypePackId pairsArgsTypePack = arena.addTypePack({mapOfKtoV});

// pairs<K, V>(t: Table<K, V>) -> ((Table<K, V>, K?) -> (K, V), Table<K, V>, nil)
addGlobalBinding(typeChecker, "pairs", arena.addType(FunctionTypeVar{{genericK, genericV}, {}, pairsArgsTypePack, pairsReturnTypePack}), "@luau");
TypeId pairsNext = arena.addType(FunctionTypeVar{nextArgsTypePack, arena.addTypePack(TypePack{{genericK, genericV}})});
TypePackId pairsReturnTypePack = arena.addTypePack(TypePack{{pairsNext, mapOfKtoV, nilType}});

// pairs<K, V>(t: Table<K, V>) -> ((Table<K, V>, K?) -> (K, V), Table<K, V>, nil)
addGlobalBinding(
typeChecker, "pairs", arena.addType(FunctionTypeVar{{genericK, genericV}, {}, pairsArgsTypePack, pairsReturnTypePack}), "@luau");
}

TypeId genericMT = arena.addType(GenericTypeVar{"MT"});

Expand Down Expand Up @@ -319,7 +341,12 @@ void registerBuiltinGlobals(TypeChecker& typeChecker)
if (TableTypeVar* ttv = getMutable<TableTypeVar>(pair.second.typeId))
{
if (!ttv->name)
ttv->name = toString(pair.first);
{
if (FFlag::LuauNewLibraryTypeNames)
ttv->name = "typeof(" + toString(pair.first) + ")";
else
ttv->name = toString(pair.first);
}
}
}

Expand Down Expand Up @@ -370,18 +397,38 @@ void registerBuiltinGlobals(Frontend& frontend)

addGlobalBinding(frontend, "string", it->second.type, "@luau");

// next<K, V>(t: Table<K, V>, i: K?) -> (K, V)
TypePackId nextArgsTypePack = arena.addTypePack(TypePack{{mapOfKtoV, makeOption(frontend, arena, genericK)}});
addGlobalBinding(frontend, "next",
arena.addType(FunctionTypeVar{{genericK, genericV}, {}, nextArgsTypePack, arena.addTypePack(TypePack{{genericK, genericV}})}), "@luau");
if (FFlag::LuauOptionalNextKey)
{
// next<K, V>(t: Table<K, V>, i: K?) -> (K?, V)
TypePackId nextArgsTypePack = arena.addTypePack(TypePack{{mapOfKtoV, makeOption(frontend, arena, genericK)}});
TypePackId nextRetsTypePack = arena.addTypePack(TypePack{{makeOption(frontend, arena, genericK), genericV}});
addGlobalBinding(frontend, "next", arena.addType(FunctionTypeVar{{genericK, genericV}, {}, nextArgsTypePack, nextRetsTypePack}), "@luau");

TypePackId pairsArgsTypePack = arena.addTypePack({mapOfKtoV});

TypeId pairsNext = arena.addType(FunctionTypeVar{nextArgsTypePack, nextRetsTypePack});
TypePackId pairsReturnTypePack = arena.addTypePack(TypePack{{pairsNext, mapOfKtoV, frontend.singletonTypes->nilType}});

TypePackId pairsArgsTypePack = arena.addTypePack({mapOfKtoV});
// pairs<K, V>(t: Table<K, V>) -> ((Table<K, V>, K?) -> (K?, V), Table<K, V>, nil)
addGlobalBinding(
frontend, "pairs", arena.addType(FunctionTypeVar{{genericK, genericV}, {}, pairsArgsTypePack, pairsReturnTypePack}), "@luau");
}
else
{
// next<K, V>(t: Table<K, V>, i: K?) -> (K, V)
TypePackId nextArgsTypePack = arena.addTypePack(TypePack{{mapOfKtoV, makeOption(frontend, arena, genericK)}});
addGlobalBinding(frontend, "next",
arena.addType(FunctionTypeVar{{genericK, genericV}, {}, nextArgsTypePack, arena.addTypePack(TypePack{{genericK, genericV}})}), "@luau");

TypeId pairsNext = arena.addType(FunctionTypeVar{nextArgsTypePack, arena.addTypePack(TypePack{{genericK, genericV}})});
TypePackId pairsReturnTypePack = arena.addTypePack(TypePack{{pairsNext, mapOfKtoV, frontend.singletonTypes->nilType}});
TypePackId pairsArgsTypePack = arena.addTypePack({mapOfKtoV});

// pairs<K, V>(t: Table<K, V>) -> ((Table<K, V>, K?) -> (K, V), Table<K, V>, nil)
addGlobalBinding(frontend, "pairs", arena.addType(FunctionTypeVar{{genericK, genericV}, {}, pairsArgsTypePack, pairsReturnTypePack}), "@luau");
TypeId pairsNext = arena.addType(FunctionTypeVar{nextArgsTypePack, arena.addTypePack(TypePack{{genericK, genericV}})});
TypePackId pairsReturnTypePack = arena.addTypePack(TypePack{{pairsNext, mapOfKtoV, frontend.singletonTypes->nilType}});

// pairs<K, V>(t: Table<K, V>) -> ((Table<K, V>, K?) -> (K, V), Table<K, V>, nil)
addGlobalBinding(
frontend, "pairs", arena.addType(FunctionTypeVar{{genericK, genericV}, {}, pairsArgsTypePack, pairsReturnTypePack}), "@luau");
}

TypeId genericMT = arena.addType(GenericTypeVar{"MT"});

Expand Down Expand Up @@ -413,7 +460,12 @@ void registerBuiltinGlobals(Frontend& frontend)
if (TableTypeVar* ttv = getMutable<TableTypeVar>(pair.second.typeId))
{
if (!ttv->name)
ttv->name = toString(pair.first);
{
if (FFlag::LuauNewLibraryTypeNames)
ttv->name = "typeof(" + toString(pair.first) + ")";
else
ttv->name = toString(pair.first);
}
}
}

Expand Down Expand Up @@ -623,7 +675,7 @@ static std::optional<WithPredicate<TypePackId>> magicFunctionAssert(

if (head.size() > 0)
{
auto [ty, ok] = typechecker.pickTypesFromSense(head[0], true);
auto [ty, ok] = typechecker.pickTypesFromSense(head[0], true, typechecker.singletonTypes->nilType);
if (FFlag::LuauUnknownAndNeverType)
{
if (get<NeverTypeVar>(*ty))
Expand Down
Loading

0 comments on commit 816e41a

Please sign in to comment.