@@ -532,16 +532,17 @@ extension Parser {
532532 var keepGoing : RawTokenSyntax ? = nil
533533 var loopProgress = LoopProgressCondition ( )
534534 repeat {
535- let firstType = self . parseType ( )
536- guard !firstType. is ( RawMissingTypeSyntax . self) else {
535+ let firstArgument = self . parseGenericArgumentType ( )
536+
537+ guard !firstArgument. value. raw. is ( RawMissingTypeSyntax . self) else {
537538 keepGoing = self . consume ( if: . comma)
538539 elements. append (
539540 RawGenericRequirementSyntax (
540541 requirement: . sameTypeRequirement(
541542 RawSameTypeRequirementSyntax (
542- leftType: RawMissingTypeSyntax ( arena : self . arena ) ,
543+ leftType: firstArgument ,
543544 equal: missingToken ( . binaryOperator, text: " == " ) ,
544- rightType: RawMissingTypeSyntax ( arena : self . arena ) ,
545+ rightType: firstArgument ,
545546 arena: self . arena
546547 )
547548 ) ,
@@ -552,137 +553,164 @@ extension Parser {
552553 continue
553554 }
554555
555- enum ExpectedTokenKind : TokenSpecSet {
556- case colon
557- case binaryOperator
558- case postfixOperator
559- case prefixOperator
560-
561- init ? ( lexeme: Lexer . Lexeme , experimentalFeatures: Parser . ExperimentalFeatures ) {
562- switch ( lexeme. rawTokenKind, lexeme. tokenText) {
563- case ( . colon, _) : self = . colon
564- case ( . binaryOperator, " == " ) : self = . binaryOperator
565- case ( . postfixOperator, " == " ) : self = . postfixOperator
566- case ( . prefixOperator, " == " ) : self = . prefixOperator
567- default : return nil
556+ let requirement : RawGenericRequirementSyntax . Requirement
557+
558+ switch RawGenericArgumentTypeSyntax . Value ( firstArgument. value. raw) ! {
559+ // If the first argument is an expression, then we have to have a same
560+ // type requirement. We do not allow conformance requirements like
561+ // '123: Protocol' or layout constraints on expressions.
562+ case . expr:
563+ let ( unexpectedBeforeEqual, equal) = self . expect (
564+ anyIn: SameTypeRequirementSyntax . EqualOptions. self,
565+ default: . binaryOperator
566+ )
567+ let secondArgument = self . parseGenericArgumentType ( )
568+ requirement = . sameTypeRequirement(
569+ RawSameTypeRequirementSyntax (
570+ leftType: firstArgument,
571+ unexpectedBeforeEqual,
572+ equal: equal,
573+ rightType: secondArgument,
574+ arena: self . arena
575+ )
576+ )
577+
578+ // Otherwise, this can be a conformance, same type, or layout constraint.
579+ case . type( let firstType) :
580+ enum ExpectedTokenKind : TokenSpecSet {
581+ case colon
582+ case binaryOperator
583+ case postfixOperator
584+ case prefixOperator
585+
586+ init ? ( lexeme: Lexer . Lexeme , experimentalFeatures: Parser . ExperimentalFeatures ) {
587+ switch ( lexeme. rawTokenKind, lexeme. tokenText) {
588+ case ( . colon, _) : self = . colon
589+ case ( . binaryOperator, " == " ) : self = . binaryOperator
590+ case ( . postfixOperator, " == " ) : self = . postfixOperator
591+ case ( . prefixOperator, " == " ) : self = . prefixOperator
592+ default : return nil
593+ }
568594 }
569- }
570595
571- var spec : TokenSpec {
572- switch self {
573- case . colon: return . colon
574- case . binaryOperator: return . binaryOperator
575- case . postfixOperator: return . postfixOperator
576- case . prefixOperator: return . prefixOperator
596+ var spec : TokenSpec {
597+ switch self {
598+ case . colon: return . colon
599+ case . binaryOperator: return . binaryOperator
600+ case . postfixOperator: return . postfixOperator
601+ case . prefixOperator: return . prefixOperator
602+ }
577603 }
578604 }
579- }
580605
581- let requirement : RawGenericRequirementSyntax . Requirement
582- switch self . at ( anyIn : ExpectedTokenKind . self ) {
583- case ( . colon , let handle) ? :
584- let colon = self . eat ( handle )
585- // A conformance-requirement.
586- if let ( layoutSpecifier , handle ) = self . at ( anyIn : LayoutRequirementSyntax . LayoutSpecifierOptions . self ) {
587- // Parse a layout constraint.
588- let specifier = self . eat ( handle )
589-
590- let unexpectedBeforeLeftParen : RawUnexpectedNodesSyntax ?
591- let leftParen : RawTokenSyntax ?
592- let size : RawTokenSyntax ?
593- let comma : RawTokenSyntax ?
594- let alignment : RawTokenSyntax ?
595- let unexpectedBeforeRightParen : RawUnexpectedNodesSyntax ?
596- let rightParen : RawTokenSyntax ?
597-
598- var hasArguments : Bool {
599- switch layoutSpecifier {
600- case . _Trivial ,
601- . _TrivialAtMost ,
602- . _TrivialStride :
603- return true
604-
605- case . _UnknownLayout ,
606- . _RefCountedObject ,
607- . _NativeRefCountedObject ,
608- . _Class ,
609- . _NativeClass ,
610- . _BridgeObject :
611- return false
606+ switch self . at ( anyIn : ExpectedTokenKind . self ) {
607+ case ( . colon , let handle ) ? :
608+ let colon = self . eat ( handle)
609+ // A conformance-requirement.
610+ if let ( layoutSpecifier , handle ) = self . at ( anyIn : LayoutRequirementSyntax . LayoutSpecifierOptions . self ) {
611+ // Parse a layout constraint.
612+ let specifier = self . eat ( handle )
613+
614+ let unexpectedBeforeLeftParen : RawUnexpectedNodesSyntax ?
615+ let leftParen : RawTokenSyntax ?
616+ let size : RawTokenSyntax ?
617+ let comma : RawTokenSyntax ?
618+ let alignment : RawTokenSyntax ?
619+ let unexpectedBeforeRightParen : RawUnexpectedNodesSyntax ?
620+ let rightParen : RawTokenSyntax ?
621+
622+ var hasArguments : Bool {
623+ switch layoutSpecifier {
624+ case . _Trivial ,
625+ . _TrivialAtMost ,
626+ . _TrivialStride :
627+ return true
628+
629+ case . _UnknownLayout ,
630+ . _RefCountedObject ,
631+ . _NativeRefCountedObject ,
632+ . _Class ,
633+ . _NativeClass ,
634+ . _BridgeObject :
635+ return false
636+ }
612637 }
613- }
614638
615- // Unlike the other layout constraints, _Trivial's argument list
616- // is optional.
617- if hasArguments && ( layoutSpecifier != . _Trivial || self . at ( . leftParen) ) {
618- ( unexpectedBeforeLeftParen, leftParen) = self . expect ( . leftParen)
619- size = self . expectWithoutRecovery ( . integerLiteral)
620- comma = self . consume ( if: . comma)
621- if comma != nil {
622- alignment = self . expectWithoutRecovery ( . integerLiteral)
639+ // Unlike the other layout constraints, _Trivial's argument list
640+ // is optional.
641+ if hasArguments && ( layoutSpecifier != . _Trivial || self . at ( . leftParen) ) {
642+ ( unexpectedBeforeLeftParen, leftParen) = self . expect ( . leftParen)
643+ size = self . expectWithoutRecovery ( . integerLiteral)
644+ comma = self . consume ( if: . comma)
645+ if comma != nil {
646+ alignment = self . expectWithoutRecovery ( . integerLiteral)
647+ } else {
648+ alignment = nil
649+ }
650+ ( unexpectedBeforeRightParen, rightParen) = self . expect ( . rightParen)
623651 } else {
652+ unexpectedBeforeLeftParen = nil
653+ leftParen = nil
654+ size = nil
655+ comma = nil
624656 alignment = nil
657+ unexpectedBeforeRightParen = nil
658+ rightParen = nil
625659 }
626- ( unexpectedBeforeRightParen, rightParen) = self . expect ( . rightParen)
660+
661+ requirement = . layoutRequirement(
662+ RawLayoutRequirementSyntax (
663+ type: firstType,
664+ colon: colon,
665+ layoutSpecifier: specifier,
666+ unexpectedBeforeLeftParen,
667+ leftParen: leftParen,
668+ size: size,
669+ comma: comma,
670+ alignment: alignment,
671+ unexpectedBeforeRightParen,
672+ rightParen: rightParen,
673+ arena: self . arena
674+ )
675+ )
627676 } else {
628- unexpectedBeforeLeftParen = nil
629- leftParen = nil
630- size = nil
631- comma = nil
632- alignment = nil
633- unexpectedBeforeRightParen = nil
634- rightParen = nil
677+ // Parse the protocol or composition.
678+ let secondType = self . parseType ( )
679+ requirement = . conformanceRequirement(
680+ RawConformanceRequirementSyntax (
681+ leftType: firstType,
682+ colon: colon,
683+ rightType: secondType,
684+ arena: self . arena
685+ )
686+ )
635687 }
636-
637- requirement = . layoutRequirement(
638- RawLayoutRequirementSyntax (
639- type: firstType,
640- colon: colon,
641- layoutSpecifier: specifier,
642- unexpectedBeforeLeftParen,
643- leftParen: leftParen,
644- size: size,
645- comma: comma,
646- alignment: alignment,
647- unexpectedBeforeRightParen,
648- rightParen: rightParen,
688+ case ( . binaryOperator, let handle) ? ,
689+ ( . postfixOperator, let handle) ? ,
690+ ( . prefixOperator, let handle) ? :
691+ let equal = self . eat ( handle)
692+ let secondArgument = self . parseGenericArgumentType ( )
693+ requirement = . sameTypeRequirement(
694+ RawSameTypeRequirementSyntax (
695+ leftType: firstArgument,
696+ equal: equal,
697+ rightType: secondArgument,
649698 arena: self . arena
650699 )
651700 )
652- } else {
653- // Parse the protocol or composition.
654- let secondType = self . parseType ( )
655- requirement = . conformanceRequirement(
656- RawConformanceRequirementSyntax (
657- leftType: firstType,
658- colon: colon,
659- rightType: secondType,
701+ case nil :
702+ requirement = . sameTypeRequirement(
703+ RawSameTypeRequirementSyntax (
704+ leftType: firstArgument,
705+ equal: RawTokenSyntax ( missing: . binaryOperator, text: " == " , arena: self . arena) ,
706+ rightType: RawGenericArgumentTypeSyntax (
707+ value: . type( RawTypeSyntax ( RawMissingTypeSyntax ( arena: self . arena) ) ) ,
708+ arena: self . arena
709+ ) ,
660710 arena: self . arena
661711 )
662712 )
663713 }
664- case ( . binaryOperator, let handle) ? ,
665- ( . postfixOperator, let handle) ? ,
666- ( . prefixOperator, let handle) ? :
667- let equal = self . eat ( handle)
668- let secondType = self . parseType ( )
669- requirement = . sameTypeRequirement(
670- RawSameTypeRequirementSyntax (
671- leftType: firstType,
672- equal: equal,
673- rightType: secondType,
674- arena: self . arena
675- )
676- )
677- case nil :
678- requirement = . sameTypeRequirement(
679- RawSameTypeRequirementSyntax (
680- leftType: firstType,
681- equal: RawTokenSyntax ( missing: . binaryOperator, text: " == " , arena: self . arena) ,
682- rightType: RawMissingTypeSyntax ( arena: self . arena) ,
683- arena: self . arena
684- )
685- )
686714 }
687715
688716 keepGoing = self . consume ( if: . comma)
0 commit comments