luau/Analysis/include/Luau/Constraint.h

211 lines
4.8 KiB
C
Raw Normal View History

2022-06-17 08:54:42 +08:00
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
#pragma once
2022-07-01 07:29:02 +08:00
#include "Luau/Ast.h" // Used for some of the enumerations
2022-10-22 01:33:43 +08:00
#include "Luau/Def.h"
2022-12-10 02:07:25 +08:00
#include "Luau/DenseHash.h"
2022-06-17 08:54:42 +08:00
#include "Luau/NotNull.h"
2023-01-04 01:33:19 +08:00
#include "Luau/Type.h"
2022-10-22 01:33:43 +08:00
#include "Luau/Variant.h"
2022-06-17 08:54:42 +08:00
2022-06-24 09:44:07 +08:00
#include <string>
2022-06-17 08:54:42 +08:00
#include <memory>
#include <vector>
namespace Luau
{
2022-07-29 11:41:13 +08:00
struct Scope;
2023-01-04 01:33:19 +08:00
struct Type;
using TypeId = const Type*;
2022-06-17 08:54:42 +08:00
struct TypePackVar;
using TypePackId = const TypePackVar*;
// subType <: superType
struct SubtypeConstraint
{
TypeId subType;
TypeId superType;
};
// subPack <: superPack
struct PackSubtypeConstraint
{
TypePackId subPack;
TypePackId superPack;
};
2022-08-26 04:55:08 +08:00
// generalizedType ~ gen sourceType
2022-06-17 08:54:42 +08:00
struct GeneralizationConstraint
{
TypeId generalizedType;
TypeId sourceType;
};
// subType ~ inst superType
struct InstantiationConstraint
{
TypeId subType;
TypeId superType;
};
2022-07-01 07:29:02 +08:00
struct UnaryConstraint
{
AstExprUnary::Op op;
TypeId operandType;
TypeId resultType;
};
2022-09-02 07:00:14 +08:00
// let L : leftType
// let R : rightType
// in
// L op R : resultType
2022-07-01 07:29:02 +08:00
struct BinaryConstraint
{
AstExprBinary::Op op;
TypeId leftType;
TypeId rightType;
TypeId resultType;
2022-12-10 02:07:25 +08:00
// When we dispatch this constraint, we update the key at this map to record
// the overload that we selected.
2023-02-03 20:34:12 +08:00
const AstNode* astFragment;
DenseHashMap<const AstNode*, TypeId>* astOriginalCallTypes;
DenseHashMap<const AstNode*, TypeId>* astOverloadResolvedTypes;
2022-07-01 07:29:02 +08:00
};
2022-09-02 07:00:14 +08:00
// iteratee is iterable
// iterators is the iteration types.
struct IterableConstraint
{
TypePackId iterator;
TypePackId variables;
};
2022-06-24 09:44:07 +08:00
// name(namedType) = name
struct NameConstraint
{
TypeId namedType;
std::string name;
2023-01-28 05:28:45 +08:00
bool synthetic = false;
2023-02-17 22:53:37 +08:00
std::vector<TypeId> typeParameters;
std::vector<TypePackId> typePackParameters;
2022-06-24 09:44:07 +08:00
};
2022-08-05 05:27:28 +08:00
// target ~ inst target
struct TypeAliasExpansionConstraint
{
2023-01-04 01:33:19 +08:00
// Must be a PendingExpansionType.
2022-08-05 05:27:28 +08:00
TypeId target;
};
2022-09-02 07:00:14 +08:00
struct FunctionCallConstraint
{
TypeId fn;
2022-09-30 06:11:54 +08:00
TypePackId argsPack;
2022-09-02 07:00:14 +08:00
TypePackId result;
2022-09-30 06:11:54 +08:00
class AstExprCall* callSite;
2023-02-11 02:50:54 +08:00
std::vector<std::optional<TypeId>> discriminantTypes;
2022-09-02 07:00:14 +08:00
};
2022-09-24 02:32:10 +08:00
// 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;
};
2022-11-19 02:45:14 +08:00
// 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;
};
2022-12-02 18:46:05 +08:00
// 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
2022-11-05 01:02:37 +08:00
struct SingletonOrTopTypeConstraint
2022-10-22 01:33:43 +08:00
{
2022-11-05 01:02:37 +08:00
TypeId resultType;
2022-10-22 01:33:43 +08:00
TypeId discriminantType;
2022-12-02 18:46:05 +08:00
bool negated;
2022-10-22 01:33:43 +08:00
};
using ConstraintV = Variant<SubtypeConstraint, PackSubtypeConstraint, GeneralizationConstraint, InstantiationConstraint, UnaryConstraint,
BinaryConstraint, IterableConstraint, NameConstraint, TypeAliasExpansionConstraint, FunctionCallConstraint, PrimitiveTypeConstraint,
2022-11-19 02:45:14 +08:00
HasPropConstraint, SetPropConstraint, SingletonOrTopTypeConstraint>;
2022-09-02 07:00:14 +08:00
2022-06-17 08:54:42 +08:00
struct Constraint
{
2022-09-02 07:00:14 +08:00
Constraint(NotNull<Scope> scope, const Location& location, ConstraintV&& c);
2022-06-17 08:54:42 +08:00
Constraint(const Constraint&) = delete;
Constraint& operator=(const Constraint&) = delete;
2022-09-02 07:00:14 +08:00
NotNull<Scope> scope;
2023-02-11 02:50:54 +08:00
Location location;
2022-06-17 08:54:42 +08:00
ConstraintV c;
2022-09-02 07:00:14 +08:00
2022-06-17 08:54:42 +08:00
std::vector<NotNull<Constraint>> dependencies;
};
2022-09-24 02:32:10 +08:00
using ConstraintPtr = std::unique_ptr<Constraint>;
2022-06-17 08:54:42 +08:00
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