@@ -19,6 +19,7 @@ import ast.Trees._
1919import StdNames ._
2020import util .Spans ._
2121import Constants ._
22+ import Symbols .defn
2223import ScriptParsers ._
2324import Decorators ._
2425import scala .tasty .util .Chars .isIdentifierStart
@@ -955,7 +956,7 @@ object Parsers {
955956
956957 in.token match {
957958 case ARROW => functionRest(t :: Nil )
958- case MATCH => matchType(EmptyTree , t)
959+ case MATCH => matchType(t)
959960 case FORSOME => syntaxError(ExistentialTypesNoLongerSupported ()); t
960961 case _ =>
961962 if (imods.is(ImplicitOrGiven ) && ! t.isInstanceOf [FunctionWithMods ])
@@ -1481,9 +1482,9 @@ object Parsers {
14811482
14821483 /** `match' { TypeCaseClauses }
14831484 */
1484- def matchType (bound : Tree , t : Tree ): MatchTypeTree =
1485- atSpan(( if (bound.isEmpty) t else bound) .span.start, accept(MATCH )) {
1486- inBraces(MatchTypeTree (bound , t, caseClauses(typeCaseClause)))
1485+ def matchType (t : Tree ): MatchTypeTree =
1486+ atSpan(t .span.start, accept(MATCH )) {
1487+ inBraces(MatchTypeTree (EmptyTree , t, caseClauses(typeCaseClause)))
14871488 }
14881489
14891490 /** FunParams ::= Bindings
@@ -2075,6 +2076,7 @@ object Parsers {
20752076 * Modifier ::= LocalModifier
20762077 * | AccessModifier
20772078 * | override
2079+ * | opaque
20782080 * LocalModifier ::= abstract | final | sealed | implicit | lazy | erased | inline
20792081 */
20802082 def modifiers (allowed : BitSet = modifierTokens, start : Modifiers = Modifiers ()): Modifiers = {
@@ -2617,8 +2619,7 @@ object Parsers {
26172619 Block (stats, Literal (Constant (())))
26182620 }
26192621
2620- /** TypeDcl ::= id [TypeParamClause] (TypeBounds | ‘=’ Type)
2621- * | id [TypeParamClause] <: Type = MatchType
2622+ /** TypeDcl ::= id [TypeParamClause] TypeBounds [‘=’ Type]
26222623 */
26232624 def typeDefOrDcl (start : Offset , mods : Modifiers ): Tree = {
26242625 newLinesOpt()
@@ -2631,15 +2632,33 @@ object Parsers {
26312632 case EQUALS =>
26322633 in.nextToken()
26332634 makeTypeDef(toplevelTyp())
2634- case SUBTYPE =>
2635- in.nextToken()
2636- val bound = toplevelTyp()
2635+ case SUBTYPE | SUPERTYPE =>
2636+ val bounds = typeBounds()
26372637 if (in.token == EQUALS ) {
2638- in.nextToken()
2639- makeTypeDef(matchType(bound, infixType()))
2638+ val eqOffset = in.skipToken()
2639+ var rhs = toplevelTyp()
2640+ rhs match {
2641+ case mtt : MatchTypeTree =>
2642+ bounds match {
2643+ case TypeBoundsTree (EmptyTree , upper) =>
2644+ rhs = MatchTypeTree (upper, mtt.selector, mtt.cases)
2645+ case _ =>
2646+ syntaxError(i " cannot combine lower bound and match type alias " , eqOffset)
2647+ }
2648+ case _ =>
2649+ if (mods.is(Opaque )) {
2650+ val annotType = AppliedTypeTree (
2651+ TypeTree (defn.WithBoundsAnnotType ),
2652+ bounds.lo.orElse(TypeTree (defn.NothingType )) ::
2653+ bounds.hi.orElse(TypeTree (defn.AnyType )) :: Nil )
2654+ rhs = Annotated (rhs, ensureApplied(wrapNew(annotType)))
2655+ }
2656+ else syntaxError(i " cannot combine bound and alias " , eqOffset)
2657+ }
2658+ makeTypeDef(rhs)
26402659 }
2641- else makeTypeDef(TypeBoundsTree ( EmptyTree , bound) )
2642- case SUPERTYPE | SEMI | NEWLINE | NEWLINES | COMMA | RBRACE | EOF =>
2660+ else makeTypeDef(bounds )
2661+ case SEMI | NEWLINE | NEWLINES | COMMA | RBRACE | EOF =>
26432662 makeTypeDef(typeBounds())
26442663 case _ =>
26452664 syntaxErrorOrIncomplete(ExpectedTypeBoundOrEquals (in.token))
0 commit comments