Skip to content

Commit ff6d381

Browse files
vrn-snannieetangaatxehgoldsteinIlya Rezvov
authored
Sync to upstream/release/698 (#2070)
# General Another week, another release. Happy Halloween! 🎃 ## Require - Integrate support for `.config.luau` files into `Luau.Require` as part of the [Luau-syntax configuration files RFC](https://rfcs.luau.org/config-luauconfig.html). - `is_config_present` has been replaced with `get_config_status`. - `get_luau_config_timeout` has been added to configure extraction timeouts at runtime. - Enable support for `.config.luau` files in `luau` and `luau-analyze`. - Merge the `Luau.RequireNavigator` static library into `Luau.Require`. ## Analysis - Add fuel-based limits for normalization: normalization will now take a set number of steps (the "fuel") and stop when we hit a certain number of steps ("run out of fuel"). This is in lieu of trying to check static limits on the size of its inputs. This may result in seeing more "code too complex" errors but should dramatically reduce the number of cases where Luau becomes unresponsive and uses several gigabytes of memory. We plan to tune this limit over time to find the right balance between responsiveness and completeness. - Fix a case where refining a variable with the type `any` would cause it to become `unknown` instead due to normalization not preserving `any` in the top type position. - Improve the wording of type errors in the new non-strict mode. - Fix #1910. - Fix #2065. - Fix #1483. - Fix #2018. ## Miscellaneous - Introduce `Luau::overloaded` to facilitate interacting with `Luau::Variant`. - Add type checking support to the [Luau demo](https://luau.org/demo)! --- Co-authored-by: Annie Tang <[email protected]> Co-authored-by: Ariel Weiss <[email protected]> Co-authored-by: Hunter Goldstein <[email protected]> Co-authored-by: Ilya Rezvov <[email protected]> Co-authored-by: Sora Kanosue <[email protected]> Co-authored-by: Varun Saini <[email protected]>
1 parent c906d59 commit ff6d381

File tree

111 files changed

+1937
-2197
lines changed

Some content is hidden

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

111 files changed

+1937
-2197
lines changed

Analysis/include/Luau/ConstraintSolver.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -218,18 +218,6 @@ struct ConstraintSolver
218218

219219
void generalizeOneType(TypeId ty);
220220

221-
/**
222-
* Bind a type variable to another type.
223-
*
224-
* A constraint is required and will validate that blockedTy is owned by this
225-
* constraint. This prevents one constraint from interfering with another's
226-
* blocked types.
227-
*
228-
* Bind will also unblock the type variable for you.
229-
*/
230-
void bind(NotNull<const Constraint> constraint, TypeId ty, TypeId boundTo);
231-
void bind(NotNull<const Constraint> constraint, TypePackId tp, TypePackId boundTo);
232-
233221
template<typename T, typename... Args>
234222
void emplace(NotNull<const Constraint> constraint, TypeId ty, Args&&... args);
235223

@@ -404,6 +392,18 @@ struct ConstraintSolver
404392
*/
405393
void shiftReferences(TypeId source, TypeId target);
406394

395+
/**
396+
* Bind a type variable to another type.
397+
*
398+
* A constraint is required and will validate that blockedTy is owned by this
399+
* constraint. This prevents one constraint from interfering with another's
400+
* blocked types.
401+
*
402+
* Bind will also unblock the type variable for you.
403+
*/
404+
void bind(NotNull<const Constraint> constraint, TypeId ty, TypeId boundTo);
405+
void bind(NotNull<const Constraint> constraint, TypePackId tp, TypePackId boundTo);
406+
407407
/**
408408
* Generalizes the given free type if the reference counting allows it.
409409
* @param the scope to generalize in

Analysis/include/Luau/Normalize.h

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,8 @@ class Normalizer
317317
DenseHashMap<TypeId, bool> cachedIsInhabited{nullptr};
318318
DenseHashMap<std::pair<TypeId, TypeId>, bool, TypeIdPairHash> cachedIsInhabitedIntersection{{nullptr, nullptr}};
319319

320+
std::optional<int> fuel{std::nullopt};
321+
320322
bool withinResourceLimits();
321323
bool useNewLuauSolver() const;
322324

@@ -342,13 +344,29 @@ class Normalizer
342344

343345
// If this returns null, the typechecker should emit a "too complex" error
344346
std::shared_ptr<const NormalizedType> normalize(TypeId ty);
345-
void clearNormal(NormalizedType& norm);
346347

348+
void clearCaches();
349+
350+
NormalizationResult isIntersectionInhabited(TypeId left, TypeId right);
351+
352+
// Check for inhabitance
353+
NormalizationResult isInhabited(TypeId ty);
354+
NormalizationResult isInhabited(const NormalizedType* norm);
355+
356+
// -------- Convert back from a normalized type to a type
357+
TypeId typeFromNormal(const NormalizedType& norm);
358+
359+
std::optional<TypePackId> intersectionOfTypePacks(TypePackId here, TypePackId there);
360+
361+
// Move to private with LuauNormalizerStepwiseFuel
362+
std::optional<TypePackId> intersectionOfTypePacks_INTERNAL(TypePackId here, TypePackId there);
363+
364+
private:
347365
// ------- Cached TypeIds
348366
TypeId unionType(TypeId here, TypeId there);
349367
TypeId intersectionType(TypeId here, TypeId there);
350368
const TypeIds* cacheTypeIds(TypeIds tys);
351-
void clearCaches();
369+
void clearNormal(NormalizedType& norm);
352370

353371
// ------- Normalizing unions
354372
void unionTysWithTy(TypeIds& here, TypeId there);
@@ -389,7 +407,6 @@ class Normalizer
389407
void intersectExternTypes(NormalizedExternType& heres, const NormalizedExternType& theres);
390408
void intersectExternTypesWithExternType(NormalizedExternType& heres, TypeId there);
391409
void intersectStrings(NormalizedStringType& here, const NormalizedStringType& there);
392-
std::optional<TypePackId> intersectionOfTypePacks(TypePackId here, TypePackId there);
393410
std::optional<TypeId> intersectionOfTables(TypeId here, TypeId there, SeenTablePropPairs& seenTablePropPairs, Set<TypeId>& seenSet);
394411
void intersectTablesWithTable(TypeIds& heres, TypeId there, SeenTablePropPairs& seenTablePropPairs, Set<TypeId>& seenSetTypes);
395412
void intersectTables(TypeIds& heres, const TypeIds& theres);
@@ -411,18 +428,20 @@ class Normalizer
411428
Set<TypeId>& seenSet
412429
);
413430

414-
// Check for inhabitance
415-
NormalizationResult isInhabited(TypeId ty);
416431
NormalizationResult isInhabited(TypeId ty, Set<TypeId>& seen);
417-
NormalizationResult isInhabited(const NormalizedType* norm);
418432
NormalizationResult isInhabited(const NormalizedType* norm, Set<TypeId>& seen);
419433

420434
// Check for intersections being inhabited
421-
NormalizationResult isIntersectionInhabited(TypeId left, TypeId right);
422435
NormalizationResult isIntersectionInhabited(TypeId left, TypeId right, SeenTablePropPairs& seenTablePropPairs, Set<TypeId>& seenSet);
423436

424-
// -------- Convert back from a normalized type to a type
425-
TypeId typeFromNormal(const NormalizedType& norm);
437+
438+
// Fuel setup
439+
440+
bool initializeFuel();
441+
void clearFuel();
442+
void consumeFuel();
443+
444+
friend struct FuelInitializer;
426445
};
427446

428447
} // namespace Luau

Analysis/include/Luau/Subtyping.h

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,6 @@ struct SubtypingEnvironment
147147
TypeIds upperBound;
148148
};
149149

150-
// TODO: Clip with LuauSubtypingGenericsDoesntUseVariance
151-
struct GenericBounds_DEPRECATED
152-
{
153-
DenseHashSet<TypeId> lowerBound{nullptr};
154-
DenseHashSet<TypeId> upperBound{nullptr};
155-
};
156-
157150
/* For nested subtyping relationship tests of mapped generic bounds, we keep the outer environment immutable */
158151
SubtypingEnvironment* parent = nullptr;
159152

@@ -165,23 +158,16 @@ struct SubtypingEnvironment
165158
TypeId ty,
166159
NotNull<InternalErrorReporter> iceReporter
167160
);
168-
// TODO: Clip with LuauSubtypingGenericsDoesntUseVariance
169-
std::optional<TypeId> applyMappedGenerics_DEPRECATED(NotNull<BuiltinTypes> builtinTypes, NotNull<TypeArena> arena, TypeId ty);
170161

171162
// TODO: Clip with LuauTryFindSubstitutionReturnOptional
172163
const TypeId* tryFindSubstitution_DEPRECATED(TypeId ty) const;
173164
std::optional<TypeId> tryFindSubstitution(TypeId ty) const;
174-
// TODO: Clip with LuauSubtypingGenericsDoesntUseVariance
175165
const SubtypingResult* tryFindSubtypingResult(std::pair<TypeId, TypeId> subAndSuper) const;
176166

177167
bool containsMappedType(TypeId ty) const;
178168
bool containsMappedPack(TypePackId tp) const;
179169

180170
GenericBounds& getMappedTypeBounds(TypeId ty, NotNull<InternalErrorReporter> iceReporter);
181-
// TODO: Clip with LuauSubtypingGenericsDoesntUseVariance
182-
GenericBounds_DEPRECATED& getMappedTypeBounds_DEPRECATED(TypeId ty);
183-
// TODO: Clip with LuauSubtypingGenericPacksDoesntUseVariance2
184-
TypePackId* getMappedPackBounds_DEPRECATED(TypePackId tp);
185171
MappedGenericEnvironment::LookupResult lookupGenericPack(TypePackId tp) const;
186172

187173
/*
@@ -191,12 +177,8 @@ struct SubtypingEnvironment
191177
* of each vector represents the current scope.
192178
*/
193179
DenseHashMap<TypeId, std::vector<GenericBounds>> mappedGenerics{nullptr};
194-
// TODO: Clip with LuauSubtypingGenericsDoesntUseVariance
195-
DenseHashMap<TypeId, GenericBounds_DEPRECATED> mappedGenerics_DEPRECATED{nullptr};
196180

197181
MappedGenericEnvironment mappedGenericPacks;
198-
// TODO: Clip with LuauSubtypingGenericPacksDoesntUseVariance2
199-
DenseHashMap<TypePackId, TypePackId> mappedGenericPacks_DEPRECATED{nullptr};
200182

201183
/*
202184
* See the test cyclic_tables_are_assumed_to_be_compatible_with_extern_types for
@@ -206,8 +188,6 @@ struct SubtypingEnvironment
206188
*/
207189
DenseHashMap<TypeId, TypeId> substitutions{nullptr};
208190

209-
// TODO: Clip with LuauSubtypingGenericsDoesntUseVariance
210-
DenseHashMap<std::pair<TypeId, TypeId>, SubtypingResult, TypePairHash> ephemeralCache{{}};
211191

212192
// We use this cache to track pairs of subtypes that we tried to subtype, and found them to be in the seen set at the time.
213193
// In those situations, we return True, but mark the result as not cacheable, because we don't want to cache broader results which
@@ -237,7 +217,7 @@ struct Subtyping
237217
Contravariant
238218
};
239219

240-
// TODO: Clip this along with LuauSubtypingGenericsDoesntUseVariance?
220+
// TODO: Clip in CLI-170986
241221
Variance variance = Variance::Covariant;
242222

243223
using SeenSet = Set<std::pair<TypeId, TypeId>, TypePairHash>;
@@ -467,8 +447,6 @@ struct Subtyping
467447
SubtypingResult isTailCovariantWithTail(SubtypingEnvironment& env, NotNull<Scope> scope, Nothing, TypePackId superTp, const GenericTypePack* super);
468448

469449
bool bindGeneric(SubtypingEnvironment& env, TypeId subTp, TypeId superTp);
470-
// Clip with LuauSubtypingGenericPacksDoesntUseVariance2
471-
bool bindGeneric_DEPRECATED(SubtypingEnvironment& env, TypePackId subTp, TypePackId superTp) const;
472450

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

Analysis/include/Luau/ToString.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ inline std::string toStringNamedFunction(const std::string& funcName, const Func
127127
return toStringNamedFunction(funcName, ftv, opts);
128128
}
129129

130+
// Converts the given number index into a human-readable string for that index to be used in errors.
131+
// e.g. the index `0` becomes `1st`, `1` becomes `2nd`, `11` becomes `12th`, etc.
132+
std::string toHumanReadableIndex(size_t number);
133+
130134
std::optional<std::string> getFunctionNameAsString(const AstExpr& expr);
131135

132136
// It could be useful to see the text representation of a type during a debugging session instead of exploring the content of the class

Analysis/include/Luau/TypePack.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -231,11 +231,6 @@ bool isEmpty(TypePackId tp);
231231
/// Flattens out a type pack. Also returns a valid TypePackId tail if the type pack's full size is not known
232232
std::pair<std::vector<TypeId>, std::optional<TypePackId>> flatten(TypePackId tp);
233233
std::pair<std::vector<TypeId>, std::optional<TypePackId>> flatten(TypePackId tp, const TxnLog& log);
234-
// TODO: Clip with LuauSubtypingGenericPacksDoesntUseVariance2
235-
std::pair<std::vector<TypeId>, std::optional<TypePackId>> flatten_DEPRECATED(
236-
TypePackId tp,
237-
const DenseHashMap<TypePackId, TypePackId>& mappedGenericPacks
238-
);
239234

240235
/// Returs true if the type pack arose from a function that is declared to be variadic.
241236
/// Returns *false* for function argument packs that are inferred to be safe to oversaturate!

Analysis/include/Luau/TypePath.h

Lines changed: 0 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -241,54 +241,8 @@ std::string toString(const TypePath::Path& path, bool prefixDot = false);
241241
/// Converts a Path to a human readable string for error reporting.
242242
std::string toStringHuman(const TypePath::Path& path);
243243

244-
// To keep my head straight when clipping:
245-
// LuauReturnMappedGenericPacksFromSubtyping3 expects mappedGenericPacks AND arena
246-
// LuauSubtypingGenericPacksDoesntUseVariance2 expects just arena. this is the final state
247-
248-
// TODO: clip below two along with `LuauReturnMappedGenericPacksFromSubtyping3`
249-
std::optional<TypeOrPack> traverse_DEPRECATED(TypeId root, const Path& path, NotNull<BuiltinTypes> builtinTypes);
250-
std::optional<TypeOrPack> traverse_DEPRECATED(TypePackId root, const Path& path, NotNull<BuiltinTypes> builtinTypes);
251244
std::optional<TypeOrPack> traverse(TypePackId root, const Path& path, NotNull<BuiltinTypes> builtinTypes, NotNull<TypeArena> arena);
252-
// TODO: Clip with LuauSubtypingGenericPacksDoesntUseVariance2
253-
std::optional<TypeOrPack> traverse_DEPRECATED(
254-
TypePackId root,
255-
const Path& path,
256-
NotNull<BuiltinTypes> builtinTypes,
257-
NotNull<const DenseHashMap<TypePackId, TypePackId>> mappedGenericPacks,
258-
NotNull<TypeArena> arena
259-
);
260245
std::optional<TypeOrPack> traverse(TypeId root, const Path& path, NotNull<BuiltinTypes> builtinTypes, NotNull<TypeArena> arena);
261-
// TODO: Clip with LuauSubtypingGenericPacksDoesntUseVariance2
262-
std::optional<TypeOrPack> traverse_DEPRECATED(
263-
TypeId root,
264-
const Path& path,
265-
NotNull<BuiltinTypes> builtinTypes,
266-
NotNull<const DenseHashMap<TypePackId, TypePackId>> mappedGenericPacks,
267-
NotNull<TypeArena> arena
268-
);
269-
270-
/// Traverses a path from a type to its end point, which must be a type. This overload will fail if the path contains a PackSlice component or a
271-
/// mapped generic pack.
272-
/// @param root the entry point of the traversal
273-
/// @param path the path to traverse
274-
/// @param builtinTypes the built-in types in use (used to acquire the string metatable)
275-
/// @returns the TypeId at the end of the path, or nullopt if the traversal failed.
276-
std::optional<TypeId> traverseForType_DEPRECATED(TypeId root, const Path& path, NotNull<BuiltinTypes> builtinTypes);
277-
278-
/// Traverses a path from a type to its end point, which must be a type.
279-
/// @param root the entry point of the traversal
280-
/// @param path the path to traverse
281-
/// @param builtinTypes the built-in types in use (used to acquire the string metatable)
282-
/// @param mappedGenericPacks the mapping for any encountered generic packs we want to reify
283-
/// @param arena a TypeArena, required if path has a PackSlice component
284-
/// @returns the TypeId at the end of the path, or nullopt if the traversal failed.
285-
std::optional<TypeId> traverseForType_DEPRECATED(
286-
TypeId root,
287-
const Path& path,
288-
NotNull<BuiltinTypes> builtinTypes,
289-
NotNull<const DenseHashMap<TypePackId, TypePackId>> mappedGenericPacks,
290-
NotNull<TypeArena> arena
291-
);
292246

293247
/// Traverses a path from a type to its end point, which must be a type.
294248
/// @param root the entry point of the traversal
@@ -298,28 +252,6 @@ std::optional<TypeId> traverseForType_DEPRECATED(
298252
/// @returns the TypeId at the end of the path, or nullopt if the traversal failed.
299253
std::optional<TypeId> traverseForType(TypeId root, const Path& path, NotNull<BuiltinTypes> builtinTypes, NotNull<TypeArena> arena);
300254

301-
/// Traverses a path from a type pack to its end point, which must be a type.
302-
/// @param root the entry point of the traversal
303-
/// @param path the path to traverse
304-
/// @param builtinTypes the built-in types in use (used to acquire the string metatable)
305-
/// @returns the TypeId at the end of the path, or nullopt if the traversal failed.
306-
std::optional<TypeId> traverseForType_DEPRECATED(TypePackId root, const Path& path, NotNull<BuiltinTypes> builtinTypes);
307-
308-
/// Traverses a path from a type pack to its end point, which must be a type.
309-
/// @param root the entry point of the traversal
310-
/// @param path the path to traverse
311-
/// @param builtinTypes the built-in types in use (used to acquire the string metatable)
312-
/// @param mappedGenericPacks the mapping for any encountered generic packs we want to reify
313-
/// @param arena a TypeArena, required if path has a PackSlice component
314-
/// @returns the TypeId at the end of the path, or nullopt if the traversal failed.
315-
std::optional<TypeId> traverseForType_DEPRECATED(
316-
TypePackId root,
317-
const Path& path,
318-
NotNull<BuiltinTypes> builtinTypes,
319-
NotNull<const DenseHashMap<TypePackId, TypePackId>> mappedGenericPacks,
320-
NotNull<TypeArena> arena
321-
);
322-
323255
/// Traverses a path from a type pack to its end point, which must be a type.
324256
/// @param root the entry point of the traversal
325257
/// @param path the path to traverse
@@ -328,29 +260,6 @@ std::optional<TypeId> traverseForType_DEPRECATED(
328260
/// @returns the TypeId at the end of the path, or nullopt if the traversal failed.
329261
std::optional<TypeId> traverseForType(TypePackId root, const Path& path, NotNull<BuiltinTypes> builtinTypes, NotNull<TypeArena> arena);
330262

331-
/// Traverses a path from a type to its end point, which must be a type pack. This overload will fail if the path contains a PackSlice component or a
332-
/// mapped generic pack.
333-
/// @param root the entry point of the traversal
334-
/// @param path the path to traverse
335-
/// @param builtinTypes the built-in types in use (used to acquire the string metatable)
336-
/// @returns the TypePackId at the end of the path, or nullopt if the traversal failed.
337-
std::optional<TypePackId> traverseForPack_DEPRECATED(TypeId root, const Path& path, NotNull<BuiltinTypes> builtinTypes);
338-
339-
/// Traverses a path from a type to its end point, which must be a type pack.
340-
/// @param root the entry point of the traversal
341-
/// @param path the path to traverse
342-
/// @param builtinTypes the built-in types in use (used to acquire the string metatable)
343-
/// @param mappedGenericPacks the mapping for any encountered generic packs we want to reify
344-
/// @param arena a TypeArena, required if path has a PackSlice component
345-
/// @returns the TypePackId at the end of the path, or nullopt if the traversal failed.
346-
std::optional<TypePackId> traverseForPack_DEPRECATED(
347-
TypeId root,
348-
const Path& path,
349-
NotNull<BuiltinTypes> builtinTypes,
350-
NotNull<const DenseHashMap<TypePackId, TypePackId>> mappedGenericPacks,
351-
NotNull<TypeArena> arena
352-
);
353-
354263
/// Traverses a path from a type to its end point, which must be a type pack.
355264
/// @param root the entry point of the traversal
356265
/// @param path the path to traverse
@@ -359,28 +268,6 @@ std::optional<TypePackId> traverseForPack_DEPRECATED(
359268
/// @returns the TypePackId at the end of the path, or nullopt if the traversal failed.
360269
std::optional<TypePackId> traverseForPack(TypeId root, const Path& path, NotNull<BuiltinTypes> builtinTypes, NotNull<TypeArena> arena);
361270

362-
/// Traverses a path from a type pack to its end point, which must be a type pack.
363-
/// @param root the entry point of the traversal
364-
/// @param path the path to traverse
365-
/// @param builtinTypes the built-in types in use (used to acquire the string metatable)
366-
/// @returns the TypePackId at the end of the path, or nullopt if the traversal failed.
367-
std::optional<TypePackId> traverseForPack_DEPRECATED(TypePackId root, const Path& path, NotNull<BuiltinTypes> builtinTypes);
368-
369-
/// Traverses a path from a type pack to its end point, which must be a type pack.
370-
/// @param root the entry point of the traversal
371-
/// @param path the path to traverse
372-
/// @param builtinTypes the built-in types in use (used to acquire the string metatable)
373-
/// @param mappedGenericPacks the mapping for any encountered generic packs we want to reify
374-
/// @param arena a TypeArena, required if path has a PackSlice component
375-
/// @returns the TypePackId at the end of the path, or nullopt if the traversal failed.
376-
std::optional<TypePackId> traverseForPack_DEPRECATED(
377-
TypePackId root,
378-
const Path& path,
379-
NotNull<BuiltinTypes> builtinTypes,
380-
NotNull<const DenseHashMap<TypePackId, TypePackId>> mappedGenericPacks,
381-
NotNull<TypeArena> arena
382-
);
383-
384271
/// Traverses a path from a type pack to its end point, which must be a type pack.
385272
/// @param root the entry point of the traversal
386273
/// @param path the path to traverse

Analysis/include/Luau/TypeUtils.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "Luau/Type.h"
77
#include "Luau/TypeIds.h"
88
#include "Luau/TypePack.h"
9+
#include "Luau/VisitType.h"
910

1011
#include <memory>
1112
#include <optional>
@@ -388,5 +389,17 @@ struct IntersectionBuilder
388389
TypeId addIntersection(NotNull<TypeArena> arena, NotNull<BuiltinTypes> builtinTypes, std::initializer_list<TypeId> list);
389390
TypeId addUnion(NotNull<TypeArena> arena, NotNull<BuiltinTypes> builtinTypes, std::initializer_list<TypeId> list);
390391

392+
struct ContainsAnyGeneric final : public TypeOnceVisitor
393+
{
394+
bool found = false;
395+
396+
explicit ContainsAnyGeneric();
397+
398+
bool visit(TypeId ty) override;
399+
bool visit(TypePackId ty) override;
400+
401+
static bool hasAnyGeneric(TypeId ty);
402+
static bool hasAnyGeneric(TypePackId tp);
403+
};
391404

392405
} // namespace Luau

0 commit comments

Comments
 (0)