@@ -532,16 +532,17 @@ extension Parser {
532
532
var keepGoing : RawTokenSyntax ? = nil
533
533
var loopProgress = LoopProgressCondition ( )
534
534
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 {
537
538
keepGoing = self . consume ( if: . comma)
538
539
elements. append (
539
540
RawGenericRequirementSyntax (
540
541
requirement: . sameTypeRequirement(
541
542
RawSameTypeRequirementSyntax (
542
- leftType: RawMissingTypeSyntax ( arena : self . arena ) ,
543
+ leftType: firstArgument ,
543
544
equal: missingToken ( . binaryOperator, text: " == " ) ,
544
- rightType: RawMissingTypeSyntax ( arena : self . arena ) ,
545
+ rightType: firstArgument ,
545
546
arena: self . arena
546
547
)
547
548
) ,
@@ -552,137 +553,164 @@ extension Parser {
552
553
continue
553
554
}
554
555
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
+ }
568
594
}
569
- }
570
595
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
+ }
577
603
}
578
604
}
579
- }
580
605
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
+ }
612
637
}
613
- }
614
638
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)
623
651
} else {
652
+ unexpectedBeforeLeftParen = nil
653
+ leftParen = nil
654
+ size = nil
655
+ comma = nil
624
656
alignment = nil
657
+ unexpectedBeforeRightParen = nil
658
+ rightParen = nil
625
659
}
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
+ )
627
676
} 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
+ )
635
687
}
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,
649
698
arena: self . arena
650
699
)
651
700
)
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
+ ) ,
660
710
arena: self . arena
661
711
)
662
712
)
663
713
}
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
- )
686
714
}
687
715
688
716
keepGoing = self . consume ( if: . comma)
0 commit comments