diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 5d36bd230b7e..091077a7a195 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -54,9 +54,9 @@ object Parsers { enum ParamOwner: case Class // class or trait or enum case CaseClass // case class or enum case - case Type // type alias or abstract type - case TypeParam // type parameter case Def // method + case Type // type alias or abstract type or polyfunction type/expr + case Hk // type parameter (i.e. current parameter is higher-kinded) case Given // given definition case ExtensionPrefix // extension clause, up to and including extension parameter case ExtensionFollow // extension clause, following extension parameter @@ -66,7 +66,11 @@ object Parsers { def takesOnlyUsingClauses = // only using clauses allowed for this owner this == Given || this == ExtensionFollow def acceptsVariance = - this == Class || this == CaseClass || this == Type + this == Class || this == CaseClass || this == Hk + def acceptsCtxBounds = + !(this == Type || this == Hk) + def acceptsWildcard = + this == Type || this == Hk end ParamOwner @@ -1569,15 +1573,15 @@ object Parsers { else core() /** Type ::= FunType - * | HkTypeParamClause ‘=>>’ Type + * | TypTypeParamClause ‘=>>’ Type * | FunParamClause ‘=>>’ Type * | MatchType * | InfixType * FunType ::= (MonoFunType | PolyFunType) * MonoFunType ::= FunTypeArgs (‘=>’ | ‘?=>’) Type - * | (‘->’ | ‘?->’ ) [CaptureSet] Type -- under pureFunctions - * PolyFunType ::= HKTypeParamClause '=>' Type - * | HKTypeParamClause ‘->’ [CaptureSet] Type -- under pureFunctions + * | (‘->’ | ‘?->’ ) [CaptureSet] Type -- under pureFunctions + * PolyFunType ::= TypTypeParamClause '=>' Type + * | TypTypeParamClause ‘->’ [CaptureSet] Type -- under pureFunctions * FunTypeArgs ::= InfixType * | `(' [ FunArgType {`,' FunArgType } ] `)' * | '(' [ TypedFunParam {',' TypedFunParam } ')' @@ -1743,7 +1747,7 @@ object Parsers { simpleTypeRest(tuple) else if in.token == LBRACKET then val start = in.offset - val tparams = typeParamClause(ParamOwner.TypeParam) + val tparams = typeParamClause(ParamOwner.Type) if in.token == TLARROW then atSpan(start, in.skipToken()): LambdaTypeTree(tparams, toplevelTyp()) @@ -2296,7 +2300,7 @@ object Parsers { t /** Expr ::= [`implicit'] FunParams (‘=>’ | ‘?=>’) Expr - * | HkTypeParamClause ‘=>’ Expr + * | TypTypeParamClause ‘=>’ Expr * | Expr1 * FunParams ::= Bindings * | id @@ -2304,7 +2308,7 @@ object Parsers { * ExprInParens ::= PostfixExpr `:' Type * | Expr * BlockResult ::= [‘implicit’] FunParams (‘=>’ | ‘?=>’) Block - * | HkTypeParamClause ‘=>’ Block + * | TypTypeParamClause ‘=>’ Block * | Expr1 * Expr1 ::= [‘inline’] `if' `(' Expr `)' {nl} Expr [[semi] else Expr] * | [‘inline’] `if' Expr `then' Expr [[semi] else Expr] @@ -2340,7 +2344,7 @@ object Parsers { closure(start, location, modifiers(BitSet(IMPLICIT))) case LBRACKET => val start = in.offset - val tparams = typeParamClause(ParamOwner.TypeParam) + val tparams = typeParamClause(ParamOwner.Type) val arrowOffset = accept(ARROW) val body = expr(location) atSpan(start, arrowOffset) { @@ -2673,7 +2677,7 @@ object Parsers { * ColonArgument ::= colon [LambdaStart] * indent (CaseClauses | Block) outdent * LambdaStart ::= FunParams (‘=>’ | ‘?=>’) - * | HkTypeParamClause ‘=>’ + * | TypTypeParamClause ‘=>’ * ColonArgBody ::= indent (CaseClauses | Block) outdent * Quoted ::= ‘'’ ‘{’ Block ‘}’ * | ‘'’ ‘[’ Type ‘]’ @@ -3390,17 +3394,19 @@ object Parsers { /** ClsTypeParamClause::= ‘[’ ClsTypeParam {‘,’ ClsTypeParam} ‘]’ * ClsTypeParam ::= {Annotation} [‘+’ | ‘-’] - * id [HkTypeParamClause] TypeParamBounds + * id [HkTypeParamClause] TypeAndCtxBounds * * DefTypeParamClause::= ‘[’ DefTypeParam {‘,’ DefTypeParam} ‘]’ * DefTypeParam ::= {Annotation} - * id [HkTypeParamClause] TypeParamBounds + * id [HkTypeParamClause] TypeAndCtxBounds * * TypTypeParamClause::= ‘[’ TypTypeParam {‘,’ TypTypeParam} ‘]’ - * TypTypeParam ::= {Annotation} id [HkTypePamClause] TypeBounds + * TypTypeParam ::= {Annotation} + * (id | ‘_’) [HkTypeParamClause] TypeBounds * * HkTypeParamClause ::= ‘[’ HkTypeParam {‘,’ HkTypeParam} ‘]’ - * HkTypeParam ::= {Annotation} [‘+’ | ‘-’] (id [HkTypePamClause] | ‘_’) TypeBounds + * HkTypeParam ::= {Annotation} [‘+’ | ‘-’] + * (id | ‘_’) [HkTypePamClause] TypeBounds */ def typeParamClause(paramOwner: ParamOwner): List[TypeDef] = inBracketsWithCommas { @@ -3411,7 +3417,6 @@ object Parsers { ok def typeParam(): TypeDef = { - val isAbstractOwner = paramOwner == ParamOwner.Type || paramOwner == ParamOwner.TypeParam val start = in.offset var mods = annotsAsMods() | Param if paramOwner.isClass then @@ -3422,13 +3427,13 @@ object Parsers { mods |= Contravariant atSpan(start, nameStart) { val name = - if (isAbstractOwner && in.token == USCORE) { + if paramOwner.acceptsWildcard && in.token == USCORE then in.nextToken() WildcardParamName.fresh().toTypeName - } else ident().toTypeName - val hkparams = typeParamClauseOpt(ParamOwner.Type) - val bounds = if (isAbstractOwner) typeBounds() else typeAndCtxBounds(name) + val hkparams = typeParamClauseOpt(ParamOwner.Hk) + val bounds = + if paramOwner.acceptsCtxBounds then typeAndCtxBounds(name) else typeBounds() TypeDef(name, lambdaAbstract(hkparams, bounds)).withMods(mods) } } @@ -3938,14 +3943,14 @@ object Parsers { argumentExprss(mkApply(Ident(nme.CONSTRUCTOR), argumentExprs())) } - /** TypeDef ::= id [TypeParamClause] {FunParamClause} TypeAndCtxBounds [‘=’ Type] + /** TypeDef ::= id [HkTypeParamClause] {FunParamClause} TypeAndCtxBounds [‘=’ Type] */ def typeDefOrDcl(start: Offset, mods: Modifiers): Tree = { newLinesOpt() atSpan(start, nameStart) { val nameIdent = typeIdent() val tname = nameIdent.name.asTypeName - val tparams = typeParamClauseOpt(ParamOwner.Type) + val tparams = typeParamClauseOpt(ParamOwner.Hk) val vparamss = funParamClauses() def makeTypeDef(rhs: Tree): Tree = { diff --git a/docs/_docs/internals/syntax.md b/docs/_docs/internals/syntax.md index 1036397eed7b..941951ab9916 100644 --- a/docs/_docs/internals/syntax.md +++ b/docs/_docs/internals/syntax.md @@ -177,12 +177,12 @@ ClassQualifier ::= ‘[’ id ‘]’ ### Types ```ebnf Type ::= FunType - | HkTypeParamClause ‘=>>’ Type LambdaTypeTree(ps, t) + | TypTypeParamClause ‘=>>’ Type LambdaTypeTree(ps, t) | FunParamClause ‘=>>’ Type TermLambdaTypeTree(ps, t) | MatchType | InfixType FunType ::= FunTypeArgs (‘=>’ | ‘?=>’) Type Function(ts, t) | FunctionWithMods(ts, t, mods, erasedParams) - | HKTypeParamClause '=>' Type PolyFunction(ps, t) + | TypTypeParamClause '=>' Type PolyFunction(ps, t) FunTypeArgs ::= InfixType | ‘(’ [ FunArgTypes ] ‘)’ | FunParamClause @@ -233,10 +233,10 @@ NameAndType ::= id ':' Type ### Expressions ```ebnf Expr ::= FunParams (‘=>’ | ‘?=>’) Expr Function(args, expr), Function(ValDef([implicit], id, TypeTree(), EmptyTree), expr) - | HkTypeParamClause ‘=>’ Expr PolyFunction(ts, expr) + | TypTypeParamClause ‘=>’ Expr PolyFunction(ts, expr) | Expr1 BlockResult ::= FunParams (‘=>’ | ‘?=>’) Block - | HkTypeParamClause ‘=>’ Block + | TypTypeParamClause ‘=>’ Block | Expr1 FunParams ::= Bindings | id @@ -286,7 +286,7 @@ SimpleExpr ::= SimpleRef ColonArgument ::= colon [LambdaStart] indent (CaseClauses | Block) outdent LambdaStart ::= FunParams (‘=>’ | ‘?=>’) - | HkTypeParamClause ‘=>’ + | TypTypeParamClause ‘=>’ Quoted ::= ‘'’ ‘{’ Block ‘}’ | ‘'’ ‘[’ TypeBlock ‘]’ ExprSplice ::= spliceId -- if inside quoted block @@ -364,11 +364,14 @@ ClsTypeParamClause::= ‘[’ ClsTypeParam {‘,’ ClsTypeParam} ‘]’ ClsTypeParam ::= {Annotation} [‘+’ | ‘-’] TypeDef(Modifiers, name, tparams, bounds) id [HkTypeParamClause] TypeAndCtxBounds Bound(below, above, context) +DefTypeParamClause::= [nl] ‘[’ DefTypeParam {‘,’ DefTypeParam} ‘]’ +DefTypeParam ::= {Annotation} id [HkTypeParamClause] TypeAndCtxBounds + TypTypeParamClause::= ‘[’ TypTypeParam {‘,’ TypTypeParam} ‘]’ -TypTypeParam ::= {Annotation} id [HkTypeParamClause] TypeBounds +TypTypeParam ::= {Annotation} (id | ‘_’) [HkTypeParamClause] TypeBounds HkTypeParamClause ::= ‘[’ HkTypeParam {‘,’ HkTypeParam} ‘]’ -HkTypeParam ::= {Annotation} [‘+’ | ‘-’] (id [HkTypeParamClause] | ‘_’) +HkTypeParam ::= {Annotation} [‘+’ | ‘-’] (id | ‘_’) [HkTypeParamClause] TypeBounds ClsParamClauses ::= {ClsParamClause} [[nl] ‘(’ [‘implicit’] ClsParams ‘)’] @@ -385,9 +388,6 @@ DefParamClause ::= DefTypeParamClause TypelessClauses ::= TypelessClause {TypelessClause} TypelessClause ::= DefTermParamClause | UsingParamClause - -DefTypeParamClause::= [nl] ‘[’ DefTypeParam {‘,’ DefTypeParam} ‘]’ -DefTypeParam ::= {Annotation} id [HkTypeParamClause] TypeAndCtxBounds DefTermParamClause::= [nl] ‘(’ [DefTermParams] ‘)’ UsingParamClause ::= [nl] ‘(’ ‘using’ (DefTermParams | FunArgTypes) ‘)’ DefImplicitClause ::= [nl] ‘(’ ‘implicit’ DefTermParams ‘)’ @@ -458,7 +458,7 @@ PatDef ::= ids [‘:’ Type] [‘=’ Expr] DefDef ::= DefSig [‘:’ Type] [‘=’ Expr] DefDef(_, name, paramss, tpe, expr) | ‘this’ TypelessClauses [DefImplicitClause] ‘=’ ConstrExpr DefDef(_, , vparamss, EmptyTree, expr | Block) DefSig ::= id [DefParamClauses] [DefImplicitClause] -TypeDef ::= id [TypeParamClause] {FunParamClause} TypeAndCtxBounds TypeDefTree(_, name, tparams, bound +TypeDef ::= id [HkTypeParamClause] {FunParamClause} TypeAndCtxBounds TypeDefTree(_, name, tparams, bound [‘=’ Type] TmplDef ::= ([‘case’] ‘class’ | ‘trait’) ClassDef diff --git a/docs/_docs/reference/syntax.md b/docs/_docs/reference/syntax.md index 36970bb95306..5d984c762a89 100644 --- a/docs/_docs/reference/syntax.md +++ b/docs/_docs/reference/syntax.md @@ -178,12 +178,11 @@ ClassQualifier ::= ‘[’ id ‘]’ ### Types ``` Type ::= FunType - | HkTypeParamClause ‘=>>’ Type - | FunParamClause ‘=>>’ Type + | TypTypeParamClause ‘=>>’ Type | MatchType | InfixType FunType ::= FunTypeArgs (‘=>’ | ‘?=>’) Type - | HKTypeParamClause '=>' Type + | TypTypeParamClause '=>' Type FunTypeArgs ::= InfixType | ‘(’ [ FunArgTypes ] ‘)’ | FunParamClause @@ -215,17 +214,17 @@ ParamValueType ::= Type [‘*’] TypeArgs ::= ‘[’ Types ‘]’ Refinement ::= :<<< [RefineDcl] {semi [RefineDcl]} >>> TypeBounds ::= [‘>:’ Type] [‘<:’ Type] -TypeParamBounds ::= TypeBounds {‘:’ Type} +TypeAndCtxBounds ::= TypeBounds {‘:’ Type} Types ::= Type {‘,’ Type} ``` ### Expressions ``` Expr ::= FunParams (‘=>’ | ‘?=>’) Expr - | HkTypeParamClause ‘=>’ Expr + | TypTypeParamClause ‘=>’ Expr | Expr1 BlockResult ::= FunParams (‘=>’ | ‘?=>’) Block - | HkTypeParamClause ‘=>’ Block + | TypTypeParamClause ‘=>’ Block | Expr1 FunParams ::= Bindings | id @@ -273,7 +272,7 @@ SimpleExpr ::= SimpleRef ColonArgument ::= colon [LambdaStart] indent (CaseClauses | Block) outdent LambdaStart ::= FunParams (‘=>’ | ‘?=>’) - | HkTypeParamClause ‘=>’ + | TypTypeParamClause ‘=>’ Quoted ::= ‘'’ ‘{’ Block ‘}’ | ‘'’ ‘[’ TypeBlock ‘]’ ExprSplice ::= spliceId -- if inside quoted block @@ -339,13 +338,16 @@ ArgumentPatterns ::= ‘(’ [Patterns] ‘)’ ### Type and Value Parameters ``` ClsTypeParamClause::= ‘[’ ClsTypeParam {‘,’ ClsTypeParam} ‘]’ -ClsTypeParam ::= {Annotation} [‘+’ | ‘-’] id [HkTypeParamClause] TypeParamBounds +ClsTypeParam ::= {Annotation} [‘+’ | ‘-’] id [HkTypeParamClause] TypeAndCtxBounds + +DefTypeParamClause::= [nl] ‘[’ DefTypeParam {‘,’ DefTypeParam} ‘]’ +DefTypeParam ::= {Annotation} id [HkTypeParamClause] TypeAndCtxBounds TypTypeParamClause::= ‘[’ TypTypeParam {‘,’ TypTypeParam} ‘]’ -TypTypeParam ::= {Annotation} id [HkTypeParamClause] TypeBounds +TypTypeParam ::= {Annotation} (id | ‘_’) [HkTypeParamClause] TypeBounds HkTypeParamClause ::= ‘[’ HkTypeParam {‘,’ HkTypeParam} ‘]’ -HkTypeParam ::= {Annotation} [‘+’ | ‘-’] (id [HkTypeParamClause] | ‘_’) TypeBounds +HkTypeParam ::= {Annotation} [‘+’ | ‘-’] (id | ‘_’) [HkTypeParamClause] TypeBounds ClsParamClauses ::= {ClsParamClause} [[nl] ‘(’ [‘implicit’] ClsParams ‘)’] ClsParamClause ::= [nl] ‘(’ ClsParams ‘)’ @@ -361,8 +363,6 @@ TypelessClauses ::= TypelessClause {TypelessClause} TypelessClause ::= DefTermParamClause | UsingParamClause -DefTypeParamClause::= [nl] ‘[’ DefTypeParam {‘,’ DefTypeParam} ‘]’ -DefTypeParam ::= {Annotation} id [HkTypeParamClause] TypeParamBounds DefTermParamClause::= [nl] ‘(’ [DefTermParams] ‘)’ UsingParamClause ::= [nl] ‘(’ ‘using’ (DefTermParams | FunArgTypes) ‘)’ DefImplicitClause ::= [nl] ‘(’ ‘implicit’ DefTermParams ‘)’ @@ -431,7 +431,7 @@ PatDef ::= ids [‘:’ Type] [‘=’ Expr] DefDef ::= DefSig [‘:’ Type] [‘=’ Expr] DefDef(_, name, paramss, tpe, expr) | ‘this’ TypelessClauses [DefImplicitClause] ‘=’ ConstrExpr DefDef(_, , vparamss, EmptyTree, expr | Block) DefSig ::= id [DefParamClauses] [DefImplicitClause] -TypeDef ::= id [TypeParamClause] {FunParamClause} TypeBounds TypeDefTree(_, name, tparams, bound +TypeDef ::= id [HkTypeParamClause] {FunParamClause}TypeBounds TypeDefTree(_, name, tparams, bound [‘=’ Type] TmplDef ::= ([‘case’] ‘class’ | ‘trait’) ClassDef