mirror of
https://github.com/luau-lang/luau.git
synced 2024-12-13 13:30:40 +00:00
c5089def6e
* Fix a bug where reading a property from an unsealed table caused inference to improperly infer the existence of that property. * Fix #827 We have also made a lot of progress on the new solver and the JIT. Both projects are still in the process of being built out. Neither are ready for general use yet. We are mostly working to tighten up how the new solver handles refinements and updates to unsealed tables to bring it up to the same level as the old solver. --------- Co-authored-by: Arseny Kapoulkine <arseny.kapoulkine@gmail.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
209 lines
4.8 KiB
C++
209 lines
4.8 KiB
C++
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
|
#pragma once
|
|
|
|
#include "Luau/Ast.h" // Used for some of the enumerations
|
|
#include "Luau/Def.h"
|
|
#include "Luau/DenseHash.h"
|
|
#include "Luau/NotNull.h"
|
|
#include "Luau/Type.h"
|
|
#include "Luau/Variant.h"
|
|
|
|
#include <string>
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
namespace Luau
|
|
{
|
|
|
|
struct Scope;
|
|
|
|
struct Type;
|
|
using TypeId = const Type*;
|
|
|
|
struct TypePackVar;
|
|
using TypePackId = const TypePackVar*;
|
|
|
|
// subType <: superType
|
|
struct SubtypeConstraint
|
|
{
|
|
TypeId subType;
|
|
TypeId superType;
|
|
};
|
|
|
|
// subPack <: superPack
|
|
struct PackSubtypeConstraint
|
|
{
|
|
TypePackId subPack;
|
|
TypePackId superPack;
|
|
};
|
|
|
|
// generalizedType ~ gen sourceType
|
|
struct GeneralizationConstraint
|
|
{
|
|
TypeId generalizedType;
|
|
TypeId sourceType;
|
|
};
|
|
|
|
// subType ~ inst superType
|
|
struct InstantiationConstraint
|
|
{
|
|
TypeId subType;
|
|
TypeId superType;
|
|
};
|
|
|
|
struct UnaryConstraint
|
|
{
|
|
AstExprUnary::Op op;
|
|
TypeId operandType;
|
|
TypeId resultType;
|
|
};
|
|
|
|
// let L : leftType
|
|
// let R : rightType
|
|
// in
|
|
// L op R : resultType
|
|
struct BinaryConstraint
|
|
{
|
|
AstExprBinary::Op op;
|
|
TypeId leftType;
|
|
TypeId rightType;
|
|
TypeId resultType;
|
|
|
|
// When we dispatch this constraint, we update the key at this map to record
|
|
// the overload that we selected.
|
|
const AstNode* astFragment;
|
|
DenseHashMap<const AstNode*, TypeId>* astOriginalCallTypes;
|
|
DenseHashMap<const AstNode*, TypeId>* astOverloadResolvedTypes;
|
|
};
|
|
|
|
// iteratee is iterable
|
|
// iterators is the iteration types.
|
|
struct IterableConstraint
|
|
{
|
|
TypePackId iterator;
|
|
TypePackId variables;
|
|
};
|
|
|
|
// name(namedType) = name
|
|
struct NameConstraint
|
|
{
|
|
TypeId namedType;
|
|
std::string name;
|
|
bool synthetic = false;
|
|
};
|
|
|
|
// target ~ inst target
|
|
struct TypeAliasExpansionConstraint
|
|
{
|
|
// Must be a PendingExpansionType.
|
|
TypeId target;
|
|
};
|
|
|
|
struct FunctionCallConstraint
|
|
{
|
|
std::vector<NotNull<const struct Constraint>> innerConstraints;
|
|
TypeId fn;
|
|
TypePackId argsPack;
|
|
TypePackId result;
|
|
class AstExprCall* callSite;
|
|
std::vector<std::optional<TypeId>> discriminantTypes;
|
|
};
|
|
|
|
// result ~ prim ExpectedType SomeSingletonType MultitonType
|
|
//
|
|
// If ExpectedType is potentially a singleton (an actual singleton or a union
|
|
// that contains a singleton), then result ~ SomeSingletonType
|
|
//
|
|
// else result ~ MultitonType
|
|
struct PrimitiveTypeConstraint
|
|
{
|
|
TypeId resultType;
|
|
TypeId expectedType;
|
|
TypeId singletonType;
|
|
TypeId multitonType;
|
|
};
|
|
|
|
// result ~ hasProp type "prop_name"
|
|
//
|
|
// If the subject is a table, bind the result to the named prop. If the table
|
|
// has an indexer, bind it to the index result type. If the subject is a union,
|
|
// bind the result to the union of its constituents' properties.
|
|
//
|
|
// It would be nice to get rid of this constraint and someday replace it with
|
|
//
|
|
// T <: {p: X}
|
|
//
|
|
// Where {} describes an inexact shape type.
|
|
struct HasPropConstraint
|
|
{
|
|
TypeId resultType;
|
|
TypeId subjectType;
|
|
std::string prop;
|
|
};
|
|
|
|
// result ~ setProp subjectType ["prop", "prop2", ...] propType
|
|
//
|
|
// If the subject is a table or table-like thing that already has the named
|
|
// property chain, we unify propType with that existing property type.
|
|
//
|
|
// If the subject is a free table, we augment it in place.
|
|
//
|
|
// If the subject is an unsealed table, result is an augmented table that
|
|
// includes that new prop.
|
|
struct SetPropConstraint
|
|
{
|
|
TypeId resultType;
|
|
TypeId subjectType;
|
|
std::vector<std::string> path;
|
|
TypeId propType;
|
|
};
|
|
|
|
// if negation:
|
|
// result ~ if isSingleton D then ~D else unknown where D = discriminantType
|
|
// if not negation:
|
|
// result ~ if isSingleton D then D else unknown where D = discriminantType
|
|
struct SingletonOrTopTypeConstraint
|
|
{
|
|
TypeId resultType;
|
|
TypeId discriminantType;
|
|
bool negated;
|
|
};
|
|
|
|
using ConstraintV = Variant<SubtypeConstraint, PackSubtypeConstraint, GeneralizationConstraint, InstantiationConstraint, UnaryConstraint,
|
|
BinaryConstraint, IterableConstraint, NameConstraint, TypeAliasExpansionConstraint, FunctionCallConstraint, PrimitiveTypeConstraint,
|
|
HasPropConstraint, SetPropConstraint, SingletonOrTopTypeConstraint>;
|
|
|
|
struct Constraint
|
|
{
|
|
Constraint(NotNull<Scope> scope, const Location& location, ConstraintV&& c);
|
|
|
|
Constraint(const Constraint&) = delete;
|
|
Constraint& operator=(const Constraint&) = delete;
|
|
|
|
NotNull<Scope> scope;
|
|
Location location;
|
|
ConstraintV c;
|
|
|
|
std::vector<NotNull<Constraint>> dependencies;
|
|
};
|
|
|
|
using ConstraintPtr = std::unique_ptr<Constraint>;
|
|
|
|
inline Constraint& asMutable(const Constraint& c)
|
|
{
|
|
return const_cast<Constraint&>(c);
|
|
}
|
|
|
|
template<typename T>
|
|
T* getMutable(Constraint& c)
|
|
{
|
|
return ::Luau::get_if<T>(&c.c);
|
|
}
|
|
|
|
template<typename T>
|
|
const T* get(const Constraint& c)
|
|
{
|
|
return getMutable<T>(asMutable(c));
|
|
}
|
|
|
|
} // namespace Luau
|