Skip to content

Commit

Permalink
implement leading bar and ampersand in types (#1286)
Browse files Browse the repository at this point in the history
Implements the [Leading `|` and `&` in types](https://rfcs.luau-lang.org/syntax-leading-bar-and-ampersand.html) RFC.

The changes to the parser are exactly as described in the RFC.

---------

Co-authored-by: Alexander McCord <[email protected]>
  • Loading branch information
jackdotink and alexmccord authored Jun 5, 2024
1 parent 041b8ee commit 43bf7c4
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 5 deletions.
34 changes: 29 additions & 5 deletions Ast/src/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ LUAU_FASTINTVARIABLE(LuauParseErrorLimit, 100)
// flag so that we don't break production games by reverting syntax changes.
// See docs/SyntaxChanges.md for an explanation.
LUAU_FASTFLAGVARIABLE(DebugLuauDeferredConstraintResolution, false)
LUAU_FASTFLAGVARIABLE(LuauLeadingBarAndAmpersand, false)

namespace Luau
{
Expand Down Expand Up @@ -1523,7 +1524,11 @@ AstType* Parser::parseFunctionTypeTail(const Lexeme& begin, AstArray<AstGenericT
AstType* Parser::parseTypeSuffix(AstType* type, const Location& begin)
{
TempVector<AstType*> parts(scratchType);
parts.push_back(type);

if (!FFlag::LuauLeadingBarAndAmpersand || type != nullptr)
{
parts.push_back(type);
}

incrementRecursionCounter("type annotation");

Expand Down Expand Up @@ -1623,15 +1628,34 @@ AstTypeOrPack Parser::parseTypeOrPack()
AstType* Parser::parseType(bool inDeclarationContext)
{
unsigned int oldRecursionCount = recursionCounter;
// recursion counter is incremented in parseSimpleType
// recursion counter is incremented in parseSimpleType and/or parseTypeSuffix

Location begin = lexer.current().location;

AstType* type = parseSimpleType(/* allowPack= */ false, /* in declaration context */ inDeclarationContext).type;
if (FFlag::LuauLeadingBarAndAmpersand)
{
AstType* type = nullptr;

recursionCounter = oldRecursionCount;
Lexeme::Type c = lexer.current().type;
if (c != '|' && c != '&')
{
type = parseSimpleType(/* allowPack= */ false, /* in declaration context */ inDeclarationContext).type;
recursionCounter = oldRecursionCount;
}

return parseTypeSuffix(type, begin);
AstType* typeWithSuffix = parseTypeSuffix(type, begin);
recursionCounter = oldRecursionCount;

return typeWithSuffix;
}
else
{
AstType* type = parseSimpleType(/* allowPack= */ false, /* in declaration context */ inDeclarationContext).type;

recursionCounter = oldRecursionCount;

return parseTypeSuffix(type, begin);
}
}

// Type ::= nil | Name[`.' Name] [ `<' Type [`,' ...] `>' ] | `typeof' `(' expr `)' | `{' [PropList] `}'
Expand Down
23 changes: 23 additions & 0 deletions tests/Parser.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ LUAU_FASTINT(LuauRecursionLimit);
LUAU_FASTINT(LuauTypeLengthLimit);
LUAU_FASTINT(LuauParseErrorLimit);
LUAU_FASTFLAG(DebugLuauDeferredConstraintResolution);
LUAU_FASTFLAG(LuauLeadingBarAndAmpersand);

namespace
{
Expand Down Expand Up @@ -3167,4 +3168,26 @@ TEST_CASE_FIXTURE(Fixture, "read_write_table_properties")
LUAU_ASSERT(pr.errors.size() == 0);
}

TEST_CASE_FIXTURE(Fixture, "can_parse_leading_bar_unions_successfully")
{
ScopedFastFlag sff{FFlag::LuauLeadingBarAndAmpersand, true};

parse(R"(type A = | "Hello" | "World")");
}

TEST_CASE_FIXTURE(Fixture, "can_parse_leading_ampersand_intersections_successfully")
{
ScopedFastFlag sff{FFlag::LuauLeadingBarAndAmpersand, true};

parse(R"(type A = & { string } & { number })");
}

TEST_CASE_FIXTURE(Fixture, "mixed_leading_intersection_and_union_not_allowed")
{
ScopedFastFlag sff{FFlag::LuauLeadingBarAndAmpersand, true};

matchParseError("type A = & number | string | boolean", "Mixing union and intersection types is not allowed; consider wrapping in parentheses.");
matchParseError("type A = | number & string & boolean", "Mixing union and intersection types is not allowed; consider wrapping in parentheses.");
}

TEST_SUITE_END();

0 comments on commit 43bf7c4

Please sign in to comment.