Skip to content

Commit 68bd1b2

Browse files
aatxealexmccordandyfriesenVighnesh-Vaviralg
authored
Sync to upstream/release/622 (#1232)
# What's changed? * Improved the actual message for the type errors for `cannot call non-function` when attempting to call a union of functions/callable tables. The error now correctly explains the issue is an inability to determine the return type of the call in this situation. * Resolve an issue where tables and metatables were not correctly being cloned during instantiation (fixes #1176). * Refactor `luaM_getnextgcopage` to `luaM_getnextpage` (generally removing `gco` prefix where appropriate). * Optimize `table.move` between tables for large ranges of elements. * Reformat a bunch of code automatically using `clang-format`. ### New Type Solver * Clean up minimally-used or unused constraints in the constraint solver (`InstantiationConstraint`, `SetOpConstraint`, `SingletonOrTopTypeConstraint`). * Add a builtin `singleton` type family to replace `SingletonOrTopTypeConstraint` when inferring refinements. * Fixed a crash involving type path reasoning by recording when type family reduction has taken place in the path. * Improved constraint ordering by blocking on unreduced types families that are not yet proven uninhabitable. * Improved the handling of `SetIndexerConstraints` for both better inference quality and to resolve crashes. * Fix a crash when normalizing cyclic unions of intersections. * Fix a crash when normalizing an intersection with the negation of `unknown`. * Fix a number of crashes caused by missing `follow` calls on `TypeId`s. * Changed type family reduction to correctly use a semantic notion of uninhabited types, rather than checking for `never` types specifically. * Refactor the `union` and `intersect` type families to be variadic. ### Native Code Generation * Improve translation for userdata key get/set and userdata/vector namecall. * Provide `[top level]` and `[anonymous]` as function names to `FunctionStats` as appropriate when no function name is available. * Disable unwind support on Android platforms since it is unsupported. * --- ### Internal Contributors Co-authored-by: Aaron Weiss <[email protected]> Co-authored-by: Alexander McCord <[email protected]> Co-authored-by: Andy Friesen <[email protected]> Co-authored-by: Aviral Goel <[email protected]> Co-authored-by: Vighnesh Vijay <[email protected]> Co-authored-by: Vyacheslav Egorov <[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]>
1 parent 9c21462 commit 68bd1b2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1404
-753
lines changed

Analysis/include/Luau/Constraint.h

+3-38
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,6 @@ struct GeneralizationConstraint
5252
std::vector<TypeId> interiorTypes;
5353
};
5454

55-
// subType ~ inst superType
56-
struct InstantiationConstraint
57-
{
58-
TypeId subType;
59-
TypeId superType;
60-
};
61-
6255
// variables ~ iterate iterator
6356
// Unpack the iterator, figure out what types it iterates over, and bind those types to variables.
6457
struct IterableConstraint
@@ -229,17 +222,6 @@ struct SetIndexerConstraint
229222
TypeId propType;
230223
};
231224

232-
// if negation:
233-
// result ~ if isSingleton D then ~D else unknown where D = discriminantType
234-
// if not negation:
235-
// result ~ if isSingleton D then D else unknown where D = discriminantType
236-
struct SingletonOrTopTypeConstraint
237-
{
238-
TypeId resultType;
239-
TypeId discriminantType;
240-
bool negated;
241-
};
242-
243225
// resultType ~ unpack sourceTypePack
244226
//
245227
// Similar to PackSubtypeConstraint, but with one important difference: If the
@@ -269,22 +251,6 @@ struct Unpack1Constraint
269251
bool resultIsLValue = false;
270252
};
271253

272-
// resultType ~ T0 op T1 op ... op TN
273-
//
274-
// op is either union or intersection. If any of the input types are blocked,
275-
// this constraint will block unless forced.
276-
struct SetOpConstraint
277-
{
278-
enum
279-
{
280-
Intersection,
281-
Union
282-
} mode;
283-
284-
TypeId resultType;
285-
std::vector<TypeId> types;
286-
};
287-
288254
// ty ~ reduce ty
289255
//
290256
// Try to reduce ty, if it is a TypeFamilyInstanceType. Otherwise, do nothing.
@@ -301,10 +267,9 @@ struct ReducePackConstraint
301267
TypePackId tp;
302268
};
303269

304-
using ConstraintV = Variant<SubtypeConstraint, PackSubtypeConstraint, GeneralizationConstraint, InstantiationConstraint, IterableConstraint,
305-
NameConstraint, TypeAliasExpansionConstraint, FunctionCallConstraint, FunctionCheckConstraint, PrimitiveTypeConstraint, HasPropConstraint,
306-
SetPropConstraint, HasIndexerConstraint, SetIndexerConstraint, SingletonOrTopTypeConstraint, UnpackConstraint, Unpack1Constraint,
307-
SetOpConstraint, ReduceConstraint, ReducePackConstraint, EqualityConstraint>;
270+
using ConstraintV = Variant<SubtypeConstraint, PackSubtypeConstraint, GeneralizationConstraint, IterableConstraint, NameConstraint,
271+
TypeAliasExpansionConstraint, FunctionCallConstraint, FunctionCheckConstraint, PrimitiveTypeConstraint, HasPropConstraint, SetPropConstraint,
272+
HasIndexerConstraint, SetIndexerConstraint, UnpackConstraint, Unpack1Constraint, ReduceConstraint, ReducePackConstraint, EqualityConstraint>;
308273

309274
struct Constraint
310275
{

Analysis/include/Luau/ConstraintSolver.h

+7-9
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ struct ConstraintSolver
9191
// A mapping from free types to the number of unresolved constraints that mention them.
9292
DenseHashMap<TypeId, size_t> unresolvedConstraints{{}};
9393

94+
// Irreducible/uninhabited type families or type pack families.
95+
DenseHashSet<const void*> uninhabitedTypeFamilies{{}};
96+
9497
// Recorded errors that take place within the solver.
9598
ErrorVec errors;
9699

@@ -124,7 +127,6 @@ struct ConstraintSolver
124127
bool tryDispatch(const SubtypeConstraint& c, NotNull<const Constraint> constraint, bool force);
125128
bool tryDispatch(const PackSubtypeConstraint& c, NotNull<const Constraint> constraint, bool force);
126129
bool tryDispatch(const GeneralizationConstraint& c, NotNull<const Constraint> constraint, bool force);
127-
bool tryDispatch(const InstantiationConstraint& c, NotNull<const Constraint> constraint, bool force);
128130
bool tryDispatch(const IterableConstraint& c, NotNull<const Constraint> constraint, bool force);
129131
bool tryDispatch(const NameConstraint& c, NotNull<const Constraint> constraint);
130132
bool tryDispatch(const TypeAliasExpansionConstraint& c, NotNull<const Constraint> constraint);
@@ -134,22 +136,18 @@ struct ConstraintSolver
134136
bool tryDispatch(const HasPropConstraint& c, NotNull<const Constraint> constraint);
135137
bool tryDispatch(const SetPropConstraint& c, NotNull<const Constraint> constraint);
136138

137-
bool tryDispatchHasIndexer(int& recursionDepth, NotNull<const Constraint> constraint, TypeId subjectType, TypeId indexType, TypeId resultType, Set<TypeId>& seen);
139+
bool tryDispatchHasIndexer(
140+
int& recursionDepth, NotNull<const Constraint> constraint, TypeId subjectType, TypeId indexType, TypeId resultType, Set<TypeId>& seen);
138141
bool tryDispatch(const HasIndexerConstraint& c, NotNull<const Constraint> constraint);
139142

140-
/// (dispatched, found) where
141-
/// - dispatched: this constraint can be considered having dispatched.
142-
/// - found: true if adding an indexer for a particular type was allowed.
143-
std::pair<bool, bool> tryDispatchSetIndexer(NotNull<const Constraint> constraint, TypeId subjectType, TypeId indexType, TypeId propType, bool expandFreeTypeBounds);
143+
std::pair<bool, std::optional<TypeId>> tryDispatchSetIndexer(
144+
NotNull<const Constraint> constraint, TypeId subjectType, TypeId indexType, TypeId propType, bool expandFreeTypeBounds);
144145
bool tryDispatch(const SetIndexerConstraint& c, NotNull<const Constraint> constraint, bool force);
145146

146-
bool tryDispatch(const SingletonOrTopTypeConstraint& c, NotNull<const Constraint> constraint);
147-
148147
bool tryDispatchUnpack1(NotNull<const Constraint> constraint, TypeId resultType, TypeId sourceType, bool resultIsLValue);
149148
bool tryDispatch(const UnpackConstraint& c, NotNull<const Constraint> constraint);
150149
bool tryDispatch(const Unpack1Constraint& c, NotNull<const Constraint> constraint);
151150

152-
bool tryDispatch(const SetOpConstraint& c, NotNull<const Constraint> constraint, bool force);
153151
bool tryDispatch(const ReduceConstraint& c, NotNull<const Constraint> constraint, bool force);
154152
bool tryDispatch(const ReducePackConstraint& c, NotNull<const Constraint> constraint, bool force);
155153
bool tryDispatch(const EqualityConstraint& c, NotNull<const Constraint> constraint, bool force);

Analysis/include/Luau/OverloadResolution.h

+5-12
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ struct OverloadResolver
6969

7070
struct SolveResult
7171
{
72-
enum OverloadCallResult {
72+
enum OverloadCallResult
73+
{
7374
Ok,
7475
CodeTooComplex,
7576
OccursCheckFailed,
@@ -87,16 +88,8 @@ struct SolveResult
8788
// Helper utility, presently used for binary operator type families.
8889
//
8990
// Given a function and a set of arguments, select a suitable overload.
90-
SolveResult solveFunctionCall(
91-
NotNull<TypeArena> arena,
92-
NotNull<BuiltinTypes> builtinTypes,
93-
NotNull<Normalizer> normalizer,
94-
NotNull<InternalErrorReporter> iceReporter,
95-
NotNull<TypeCheckLimits> limits,
96-
NotNull<Scope> scope,
97-
const Location& location,
98-
TypeId fn,
99-
TypePackId argsPack
100-
);
91+
SolveResult solveFunctionCall(NotNull<TypeArena> arena, NotNull<BuiltinTypes> builtinTypes, NotNull<Normalizer> normalizer,
92+
NotNull<InternalErrorReporter> iceReporter, NotNull<TypeCheckLimits> limits, NotNull<Scope> scope, const Location& location, TypeId fn,
93+
TypePackId argsPack);
10194

10295
} // namespace Luau

Analysis/include/Luau/Subtyping.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,8 @@ struct Subtyping
208208
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const TableIndexer& subIndexer, const TableIndexer& superIndexer);
209209
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const Property& subProperty, const Property& superProperty, const std::string& name);
210210

211-
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const std::shared_ptr<const NormalizedType>& subNorm, const std::shared_ptr<const NormalizedType>& superNorm);
211+
SubtypingResult isCovariantWith(
212+
SubtypingEnvironment& env, const std::shared_ptr<const NormalizedType>& subNorm, const std::shared_ptr<const NormalizedType>& superNorm);
212213
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const NormalizedClassType& subClass, const NormalizedClassType& superClass);
213214
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const NormalizedClassType& subClass, const TypeIds& superTables);
214215
SubtypingResult isCovariantWith(SubtypingEnvironment& env, const NormalizedStringType& subString, const NormalizedStringType& superString);

Analysis/include/Luau/TableLiteralInference.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ class AstExpr;
1717
TypeId matchLiteralType(NotNull<DenseHashMap<const AstExpr*, TypeId>> astTypes, NotNull<DenseHashMap<const AstExpr*, TypeId>> astExpectedTypes,
1818
NotNull<BuiltinTypes> builtinTypes, NotNull<TypeArena> arena, NotNull<Unifier2> unifier, TypeId expectedType, TypeId exprType,
1919
const AstExpr* expr, std::vector<TypeId>& toBlock);
20-
}
20+
} // namespace Luau

Analysis/include/Luau/Type.h

+21
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,27 @@ struct TypeFamilyInstanceType
552552

553553
std::vector<TypeId> typeArguments;
554554
std::vector<TypePackId> packArguments;
555+
556+
TypeFamilyInstanceType(NotNull<const TypeFamily> family, std::vector<TypeId> typeArguments, std::vector<TypePackId> packArguments)
557+
: family(family)
558+
, typeArguments(typeArguments)
559+
, packArguments(packArguments)
560+
{
561+
}
562+
563+
TypeFamilyInstanceType(const TypeFamily& family, std::vector<TypeId> typeArguments)
564+
: family{&family}
565+
, typeArguments(typeArguments)
566+
, packArguments{}
567+
{
568+
}
569+
570+
TypeFamilyInstanceType(const TypeFamily& family, std::vector<TypeId> typeArguments, std::vector<TypePackId> packArguments)
571+
: family{&family}
572+
, typeArguments(typeArguments)
573+
, packArguments(packArguments)
574+
{
575+
}
555576
};
556577

557578
/** Represents a pending type alias instantiation.

Analysis/include/Luau/TypeArena.h

+5
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ struct TypeArena
4848
{
4949
return addTypePack(TypePackVar(std::move(tp)));
5050
}
51+
52+
TypeId addTypeFamily(const TypeFamily& family, std::initializer_list<TypeId> types);
53+
TypeId addTypeFamily(const TypeFamily& family, std::vector<TypeId> typeArguments, std::vector<TypePackId> packArguments = {});
54+
TypePackId addTypePackFamily(const TypePackFamily& family, std::initializer_list<TypeId> types);
55+
TypePackId addTypePackFamily(const TypePackFamily& family, std::vector<TypeId> typeArguments, std::vector<TypePackId> packArguments = {});
5156
};
5257

5358
void freeze(TypeArena& arena);

Analysis/include/Luau/TypeFamily.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ struct TypeFamilyReductionResult
9999
};
100100

101101
template<typename T>
102-
using ReducerFunction =
103-
std::function<TypeFamilyReductionResult<T>(T, NotNull<TypeFamilyQueue>, const std::vector<TypeId>&, const std::vector<TypePackId>&, NotNull<TypeFamilyContext>)>;
102+
using ReducerFunction = std::function<TypeFamilyReductionResult<T>(
103+
T, NotNull<TypeFamilyQueue>, const std::vector<TypeId>&, const std::vector<TypePackId>&, NotNull<TypeFamilyContext>)>;
104104

105105
/// Represents a type function that may be applied to map a series of types and
106106
/// type packs to a single output type.
@@ -189,6 +189,7 @@ struct BuiltinTypeFamilies
189189
TypeFamily eqFamily;
190190

191191
TypeFamily refineFamily;
192+
TypeFamily singletonFamily;
192193
TypeFamily unionFamily;
193194
TypeFamily intersectFamily;
194195

Analysis/include/Luau/TypePack.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ struct BlockedTypePack
9292
*/
9393
struct TypeFamilyInstanceTypePack
9494
{
95-
NotNull<TypePackFamily> family;
95+
NotNull<const TypePackFamily> family;
9696

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

Analysis/include/Luau/TypePath.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,18 @@ enum class PackField
7979
Tail,
8080
};
8181

82+
/// Component that represents the result of a reduction
83+
/// `resultType` is `never` if the reduction could not proceed
84+
struct Reduction
85+
{
86+
TypeId resultType;
87+
88+
bool operator==(const Reduction& other) const;
89+
};
90+
8291
/// A single component of a path, representing one inner type or type pack to
8392
/// traverse into.
84-
using Component = Luau::Variant<Property, Index, TypeField, PackField>;
93+
using Component = Luau::Variant<Property, Index, TypeField, PackField, Reduction>;
8594

8695
/// A path through a type or type pack accessing a particular type or type pack
8796
/// contained within.
@@ -156,6 +165,7 @@ struct PathHash
156165
size_t operator()(const Index& idx) const;
157166
size_t operator()(const TypeField& field) const;
158167
size_t operator()(const PackField& field) const;
168+
size_t operator()(const Reduction& reduction) const;
159169
size_t operator()(const Component& component) const;
160170
size_t operator()(const Path& path) const;
161171
};

Analysis/include/Luau/Unifier2.h

+4
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,12 @@ struct Unifier2
4848
int recursionLimit = 0;
4949

5050
std::vector<ConstraintV> incompleteSubtypes;
51+
// null if not in a constraint solving context
52+
DenseHashSet<const void*>* uninhabitedTypeFamilies;
5153

5254
Unifier2(NotNull<TypeArena> arena, NotNull<BuiltinTypes> builtinTypes, NotNull<Scope> scope, NotNull<InternalErrorReporter> ice);
55+
Unifier2(NotNull<TypeArena> arena, NotNull<BuiltinTypes> builtinTypes, NotNull<Scope> scope, NotNull<InternalErrorReporter> ice,
56+
DenseHashSet<const void*>* uninhabitedTypeFamilies);
5357

5458
/** Attempt to commit the subtype relation subTy <: superTy to the type
5559
* graph.

Analysis/src/BuiltinDefinitions.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
*/
2525

2626
LUAU_FASTFLAG(DebugLuauDeferredConstraintResolution);
27-
LUAU_FASTFLAGVARIABLE(LuauSetMetatableOnUnionsOfTables, false);
2827
LUAU_FASTFLAGVARIABLE(LuauMakeStringMethodsChecked, false);
2928

3029
namespace Luau
@@ -1067,7 +1066,7 @@ static std::optional<WithPredicate<TypePackId>> magicFunctionSetMetaTable(
10671066
else if (get<AnyType>(target) || get<ErrorType>(target) || isTableIntersection(target))
10681067
{
10691068
}
1070-
else if (FFlag::LuauSetMetatableOnUnionsOfTables && isTableUnion(target))
1069+
else if (isTableUnion(target))
10711070
{
10721071
const UnionType* ut = get<UnionType>(target);
10731072
LUAU_ASSERT(ut);

0 commit comments

Comments
 (0)