mirror of
https://github.com/luau-lang/luau.git
synced 2024-11-15 14:25:44 +08:00
d2ab5df62b
We've made a few small changes to reduce the amount of stack we use when typechecking nested method calls (eg `foo:bar():baz():quux()`). We've also fixed a small bytecode compiler issue that caused us to emit redundant jump instructions in code that conditionally uses `break` or `continue`. On the new solver, we've switched to a new, better way to handle augmentations to unsealed tables. We've also made some substantial improvements to type inference and error reporting on function calls. These things should both be on par with the old solver now. The main improvements to the native code generator have been elimination of some redundant type tag checks. Also, we are starting to inline particular fastcalls directly to IR. --------- Co-authored-by: Arseny Kapoulkine <arseny.kapoulkine@gmail.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com>
148 lines
3.9 KiB
C++
148 lines
3.9 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/Constraint.h"
|
|
#include "Luau/NotNull.h"
|
|
#include "Luau/Scope.h"
|
|
#include "Luau/Module.h"
|
|
#include "Luau/ToString.h"
|
|
#include "Luau/Error.h"
|
|
#include "Luau/Variant.h"
|
|
|
|
#include <optional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace Luau
|
|
{
|
|
|
|
struct ErrorSnapshot
|
|
{
|
|
std::string message;
|
|
Location location;
|
|
};
|
|
|
|
struct BindingSnapshot
|
|
{
|
|
std::string typeId;
|
|
std::string typeString;
|
|
Location location;
|
|
};
|
|
|
|
struct TypeBindingSnapshot
|
|
{
|
|
std::string typeId;
|
|
std::string typeString;
|
|
};
|
|
|
|
struct ExprTypesAtLocation
|
|
{
|
|
Location location;
|
|
TypeId ty;
|
|
std::optional<TypeId> expectedTy;
|
|
};
|
|
|
|
struct AnnotationTypesAtLocation
|
|
{
|
|
Location location;
|
|
TypeId resolvedTy;
|
|
};
|
|
|
|
struct ConstraintGenerationLog
|
|
{
|
|
std::string source;
|
|
std::vector<ErrorSnapshot> errors;
|
|
|
|
std::vector<ExprTypesAtLocation> exprTypeLocations;
|
|
std::vector<AnnotationTypesAtLocation> annotationTypeLocations;
|
|
};
|
|
|
|
struct ScopeSnapshot
|
|
{
|
|
std::unordered_map<Name, BindingSnapshot> bindings;
|
|
std::unordered_map<Name, TypeBindingSnapshot> typeBindings;
|
|
std::unordered_map<Name, TypeBindingSnapshot> typePackBindings;
|
|
std::vector<ScopeSnapshot> children;
|
|
};
|
|
|
|
using ConstraintBlockTarget = Variant<TypeId, TypePackId, NotNull<const Constraint>>;
|
|
|
|
struct ConstraintBlock
|
|
{
|
|
ConstraintBlockTarget target;
|
|
std::string stringification;
|
|
};
|
|
|
|
struct ConstraintSnapshot
|
|
{
|
|
std::string stringification;
|
|
Location location;
|
|
std::vector<ConstraintBlock> blocks;
|
|
};
|
|
|
|
struct BoundarySnapshot
|
|
{
|
|
DenseHashMap<const Constraint*, ConstraintSnapshot> unsolvedConstraints{nullptr};
|
|
ScopeSnapshot rootScope;
|
|
DenseHashMap<const void*, std::string> typeStrings{nullptr};
|
|
};
|
|
|
|
struct StepSnapshot
|
|
{
|
|
const Constraint* currentConstraint;
|
|
bool forced;
|
|
DenseHashMap<const Constraint*, ConstraintSnapshot> unsolvedConstraints{nullptr};
|
|
ScopeSnapshot rootScope;
|
|
DenseHashMap<const void*, std::string> typeStrings{nullptr};
|
|
};
|
|
|
|
struct TypeSolveLog
|
|
{
|
|
BoundarySnapshot initialState;
|
|
std::vector<StepSnapshot> stepStates;
|
|
BoundarySnapshot finalState;
|
|
};
|
|
|
|
struct TypeCheckLog
|
|
{
|
|
std::vector<ErrorSnapshot> errors;
|
|
};
|
|
|
|
struct DcrLogger
|
|
{
|
|
std::string compileOutput();
|
|
|
|
void captureSource(std::string source);
|
|
void captureGenerationError(const TypeError& error);
|
|
void captureConstraintLocation(NotNull<const Constraint> constraint, Location location);
|
|
void captureGenerationModule(const ModulePtr& module);
|
|
|
|
void pushBlock(NotNull<const Constraint> constraint, TypeId block);
|
|
void pushBlock(NotNull<const Constraint> constraint, TypePackId block);
|
|
void pushBlock(NotNull<const Constraint> constraint, NotNull<const Constraint> block);
|
|
void popBlock(TypeId block);
|
|
void popBlock(TypePackId block);
|
|
void popBlock(NotNull<const Constraint> block);
|
|
|
|
void captureInitialSolverState(const Scope* rootScope, const std::vector<NotNull<const Constraint>>& unsolvedConstraints);
|
|
StepSnapshot prepareStepSnapshot(
|
|
const Scope* rootScope, NotNull<const Constraint> current, bool force, const std::vector<NotNull<const Constraint>>& unsolvedConstraints);
|
|
void commitStepSnapshot(StepSnapshot snapshot);
|
|
void captureFinalSolverState(const Scope* rootScope, const std::vector<NotNull<const Constraint>>& unsolvedConstraints);
|
|
|
|
void captureTypeCheckError(const TypeError& error);
|
|
|
|
private:
|
|
ConstraintGenerationLog generationLog;
|
|
std::unordered_map<NotNull<const Constraint>, std::vector<ConstraintBlockTarget>> constraintBlocks;
|
|
TypeSolveLog solveLog;
|
|
TypeCheckLog checkLog;
|
|
|
|
ToStringOptions opts{true};
|
|
|
|
std::vector<ConstraintBlock> snapshotBlocks(NotNull<const Constraint> constraint);
|
|
void captureBoundaryState(BoundarySnapshot& target, const Scope* rootScope, const std::vector<NotNull<const Constraint>>& unsolvedConstraints);
|
|
};
|
|
|
|
} // namespace Luau
|