Skip to content

Commit

Permalink
Sync to upstream/release/634 (#1325)
Browse files Browse the repository at this point in the history
# What's Changed?

- Performance improvement in the old solver
- Bugfixes in the new solver

## Old Solver

- Mark types that do not need instantiation when being exported to
prevent unnecessary work from being done

## New Solver

- Refactored instances of "type family" with "type function"
- Index-out-of-bounds bug fix in the resolution resolver
- Subtyping reasonings are merged only if all failed

---
### Internal Contributors

Co-authored-by: Aaron Weiss <[email protected]>
Co-authored-by: Vighnesh Vijay <[email protected]>
Co-authored-by: Vyacheslav Egorov <[email protected]>

---------

Co-authored-by: Aaron Weiss <[email protected]>
Co-authored-by: Alexander McCord <[email protected]>
Co-authored-by: Andy Friesen <[email protected]>
Co-authored-by: Vighnesh <[email protected]>
Co-authored-by: Aviral Goel <[email protected]>
Co-authored-by: David Cope <[email protected]>
Co-authored-by: Lily Brown <[email protected]>
Co-authored-by: Vyacheslav Egorov <[email protected]>
  • Loading branch information
9 people authored Jul 12, 2024
1 parent 6bfc38e commit b6b74b4
Show file tree
Hide file tree
Showing 51 changed files with 812 additions and 771 deletions.
2 changes: 1 addition & 1 deletion Analysis/include/Luau/Constraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ struct UnpackConstraint

// ty ~ reduce ty
//
// Try to reduce ty, if it is a TypeFamilyInstanceType. Otherwise, do nothing.
// Try to reduce ty, if it is a TypeFunctionInstanceType. Otherwise, do nothing.
struct ReduceConstraint
{
TypeId ty;
Expand Down
8 changes: 4 additions & 4 deletions Analysis/include/Luau/ConstraintGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,9 +343,9 @@ struct ConstraintGenerator
void reportError(Location location, TypeErrorData err);
void reportCodeTooComplex(Location location);

// make a union type family of these two types
// make a union type function of these two types
TypeId makeUnion(const ScopePtr& scope, Location location, TypeId lhs, TypeId rhs);
// make an intersect type family of these two types
// make an intersect type function of these two types
TypeId makeIntersect(const ScopePtr& scope, Location location, TypeId lhs, TypeId rhs);

/** Scan the program for global definitions.
Expand All @@ -370,8 +370,8 @@ struct ConstraintGenerator
*/
std::vector<std::optional<TypeId>> getExpectedCallTypesForFunctionOverloads(const TypeId fnType);

TypeId createTypeFamilyInstance(
const TypeFamily& family, std::vector<TypeId> typeArguments, std::vector<TypePackId> packArguments, const ScopePtr& scope, Location location);
TypeId createTypeFunctionInstance(
const TypeFunction& family, std::vector<TypeId> typeArguments, std::vector<TypePackId> packArguments, const ScopePtr& scope, Location location);
};

/** Borrow a vector of pointers from a vector of owning pointers to constraints.
Expand Down
10 changes: 5 additions & 5 deletions Analysis/include/Luau/Error.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,11 +334,11 @@ struct DynamicPropertyLookupOnClassesUnsafe
bool operator==(const DynamicPropertyLookupOnClassesUnsafe& rhs) const;
};

struct UninhabitedTypeFamily
struct UninhabitedTypeFunction
{
TypeId ty;

bool operator==(const UninhabitedTypeFamily& rhs) const;
bool operator==(const UninhabitedTypeFunction& rhs) const;
};

struct ExplicitFunctionAnnotationRecommended
Expand All @@ -348,11 +348,11 @@ struct ExplicitFunctionAnnotationRecommended
bool operator==(const ExplicitFunctionAnnotationRecommended& rhs) const;
};

struct UninhabitedTypePackFamily
struct UninhabitedTypePackFunction
{
TypePackId tp;

bool operator==(const UninhabitedTypePackFamily& rhs) const;
bool operator==(const UninhabitedTypePackFunction& rhs) const;
};

struct WhereClauseNeeded
Expand Down Expand Up @@ -449,7 +449,7 @@ using TypeErrorData =
CodeTooComplex, UnificationTooComplex, UnknownPropButFoundLikeProp, GenericError, InternalError, CannotCallNonFunction, ExtraInformation,
DeprecatedApiUsed, ModuleHasCyclicDependency, IllegalRequire, FunctionExitsWithoutReturning, DuplicateGenericParameter, CannotAssignToNever,
CannotInferBinaryOperation, MissingProperties, SwappedGenericTypeParameter, OptionalValueAccess, MissingUnionProperty, TypesAreUnrelated,
NormalizationTooComplex, TypePackMismatch, DynamicPropertyLookupOnClassesUnsafe, UninhabitedTypeFamily, UninhabitedTypePackFamily,
NormalizationTooComplex, TypePackMismatch, DynamicPropertyLookupOnClassesUnsafe, UninhabitedTypeFunction, UninhabitedTypePackFunction,
WhereClauseNeeded, PackWhereClauseNeeded, CheckedFunctionCallError, NonStrictFunctionDefinitionError, PropertyAccessViolation,
CheckedFunctionIncorrectArgs, UnexpectedTypeInSubtyping, UnexpectedTypePackInSubtyping, ExplicitFunctionAnnotationRecommended>;

Expand Down
54 changes: 54 additions & 0 deletions Analysis/include/Luau/Instantiation.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "Luau/Substitution.h"
#include "Luau/TypeFwd.h"
#include "Luau/Unifiable.h"
#include "Luau/VisitType.h"

namespace Luau
{
Expand Down Expand Up @@ -72,6 +73,59 @@ struct Instantiation : Substitution
TypePackId clean(TypePackId tp) override;
};

// Used to find if a FunctionType requires generic type cleanup during instantiation
struct GenericTypeFinder : TypeOnceVisitor
{
bool found = false;

bool visit(TypeId ty) override
{
return !found;
}

bool visit(TypePackId ty) override
{
return !found;
}

bool visit(TypeId ty, const Luau::FunctionType& ftv) override
{
if (ftv.hasNoFreeOrGenericTypes)
return false;

if (!ftv.generics.empty() || !ftv.genericPacks.empty())
found = true;

return !found;
}

bool visit(TypeId ty, const Luau::TableType& ttv) override
{
if (ttv.state == Luau::TableState::Generic)
found = true;

return !found;
}

bool visit(TypeId ty, const Luau::GenericType&) override
{
found = true;
return false;
}

bool visit(TypePackId ty, const Luau::GenericTypePack&) override
{
found = true;
return false;
}

bool visit(TypeId ty, const Luau::ClassType&) override
{
// During function instantiation, classes are not traversed even if they have generics
return false;
}
};

/** Attempt to instantiate a type. Only used under local type inference.
*
* When given a generic function type, instantiate() will return a copy with the
Expand Down
10 changes: 5 additions & 5 deletions Analysis/include/Luau/Subtyping.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "Luau/TypeFwd.h"
#include "Luau/TypePairHash.h"
#include "Luau/TypePath.h"
#include "Luau/TypeFamily.h"
#include "Luau/TypeFunction.h"
#include "Luau/TypeCheckLimits.h"
#include "Luau/DenseHash.h"

Expand Down Expand Up @@ -114,7 +114,7 @@ struct SubtypingEnvironment
DenseHashMap<std::pair<TypeId, TypeId>, SubtypingResult, TypePairHash> ephemeralCache{{}};

/// Applies `mappedGenerics` to the given type.
/// This is used specifically to substitute for generics in type family instances.
/// This is used specifically to substitute for generics in type function instances.
std::optional<TypeId> applyMappedGenerics(NotNull<BuiltinTypes> builtinTypes, NotNull<TypeArena> arena, TypeId ty);
};

Expand Down Expand Up @@ -219,16 +219,16 @@ struct Subtyping
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const TypeIds& subTypes, const TypeIds& superTypes);

SubtypingResult isCovariantWith(SubtypingEnvironment& env, const VariadicTypePack* subVariadic, const VariadicTypePack* superVariadic);
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const TypeFamilyInstanceType* subFamilyInstance, const TypeId superTy);
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const TypeId subTy, const TypeFamilyInstanceType* superFamilyInstance);
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const TypeFunctionInstanceType* subFamilyInstance, const TypeId superTy);
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const TypeId subTy, const TypeFunctionInstanceType* superFamilyInstance);

bool bindGeneric(SubtypingEnvironment& env, TypeId subTp, TypeId superTp);
bool bindGeneric(SubtypingEnvironment& env, TypePackId subTp, TypePackId superTp);

template<typename T, typename Container>
TypeId makeAggregateType(const Container& container, TypeId orElse);

std::pair<TypeId, ErrorVec> handleTypeFamilyReductionResult(const TypeFamilyInstanceType* familyInstance);
std::pair<TypeId, ErrorVec> handleTypeFunctionReductionResult(const TypeFunctionInstanceType* familyInstance);

[[noreturn]] void unexpected(TypeId ty);
[[noreturn]] void unexpected(TypePackId tp);
Expand Down
20 changes: 10 additions & 10 deletions Analysis/include/Luau/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ struct TypeArena;
struct Scope;
using ScopePtr = std::shared_ptr<Scope>;

struct TypeFamily;
struct TypeFunction;
struct Constraint;

/**
Expand Down Expand Up @@ -528,34 +528,34 @@ struct ClassType
};

/**
* An instance of a type family that has not yet been reduced to a more concrete
* An instance of a type function that has not yet been reduced to a more concrete
* type. The constraint solver receives a constraint to reduce each
* TypeFamilyInstanceType to a concrete type. A design detail is important to
* note here: the parameters for this instantiation of the type family are
* TypeFunctionInstanceType to a concrete type. A design detail is important to
* note here: the parameters for this instantiation of the type function are
* contained within this type, so that they can be substituted.
*/
struct TypeFamilyInstanceType
struct TypeFunctionInstanceType
{
NotNull<const TypeFamily> family;
NotNull<const TypeFunction> family;

std::vector<TypeId> typeArguments;
std::vector<TypePackId> packArguments;

TypeFamilyInstanceType(NotNull<const TypeFamily> family, std::vector<TypeId> typeArguments, std::vector<TypePackId> packArguments)
TypeFunctionInstanceType(NotNull<const TypeFunction> family, std::vector<TypeId> typeArguments, std::vector<TypePackId> packArguments)
: family(family)
, typeArguments(typeArguments)
, packArguments(packArguments)
{
}

TypeFamilyInstanceType(const TypeFamily& family, std::vector<TypeId> typeArguments)
TypeFunctionInstanceType(const TypeFunction& family, std::vector<TypeId> typeArguments)
: family{&family}
, typeArguments(typeArguments)
, packArguments{}
{
}

TypeFamilyInstanceType(const TypeFamily& family, std::vector<TypeId> typeArguments, std::vector<TypePackId> packArguments)
TypeFunctionInstanceType(const TypeFunction& family, std::vector<TypeId> typeArguments, std::vector<TypePackId> packArguments)
: family{&family}
, typeArguments(typeArguments)
, packArguments(packArguments)
Expand Down Expand Up @@ -659,7 +659,7 @@ using ErrorType = Unifiable::Error;

using TypeVariant =
Unifiable::Variant<TypeId, FreeType, GenericType, PrimitiveType, SingletonType, BlockedType, PendingExpansionType, FunctionType, TableType,
MetatableType, ClassType, AnyType, UnionType, IntersectionType, LazyType, UnknownType, NeverType, NegationType, TypeFamilyInstanceType>;
MetatableType, ClassType, AnyType, UnionType, IntersectionType, LazyType, UnknownType, NeverType, NegationType, TypeFunctionInstanceType>;

struct Type final
{
Expand Down
8 changes: 4 additions & 4 deletions Analysis/include/Luau/TypeArena.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ struct TypeArena
return addTypePack(TypePackVar(std::move(tp)));
}

TypeId addTypeFamily(const TypeFamily& family, std::initializer_list<TypeId> types);
TypeId addTypeFamily(const TypeFamily& family, std::vector<TypeId> typeArguments, std::vector<TypePackId> packArguments = {});
TypePackId addTypePackFamily(const TypePackFamily& family, std::initializer_list<TypeId> types);
TypePackId addTypePackFamily(const TypePackFamily& family, std::vector<TypeId> typeArguments, std::vector<TypePackId> packArguments = {});
TypeId addTypeFunction(const TypeFunction& family, std::initializer_list<TypeId> types);
TypeId addTypeFunction(const TypeFunction& family, std::vector<TypeId> typeArguments, std::vector<TypePackId> packArguments = {});
TypePackId addTypePackFunction(const TypePackFunction& family, std::initializer_list<TypeId> types);
TypePackId addTypePackFunction(const TypePackFunction& family, std::vector<TypeId> typeArguments, std::vector<TypePackId> packArguments = {});
};

void freeze(TypeArena& arena);
Expand Down
85 changes: 0 additions & 85 deletions Analysis/include/Luau/TypeFamilyReductionGuesser.h

This file was deleted.

Loading

0 comments on commit b6b74b4

Please sign in to comment.