From d8b8fc1af183ec9e074640179a1b97c343f0c14e Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 6 Apr 2021 10:42:32 +0200 Subject: [PATCH] Allow by-name types in using clauses Fixes #11997 --- .../src/dotty/tools/dotc/parsing/Parsers.scala | 14 +++++++------- docs/docs/internals/syntax.md | 11 ++++++----- docs/docs/reference/syntax.md | 11 ++++++----- tests/pos/i11997.scala | 3 +++ 4 files changed, 22 insertions(+), 17 deletions(-) create mode 100644 tests/pos/i11997.scala diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index cec916a4b826..f5db937f8684 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -1324,9 +1324,9 @@ object Parsers { * | MatchType * | InfixType * FunType ::= (MonoFunType | PolyFunType) - * MonoFunType ::= FunArgTypes (‘=>’ | ‘?=>’) Type + * MonoFunType ::= FunTypeArgs (‘=>’ | ‘?=>’) Type * PolyFunType ::= HKTypeParamClause '=>' Type - * FunArgTypes ::= InfixType + * FunTypeArgs ::= InfixType * | `(' [ [ ‘[using]’ ‘['erased'] FunArgType {`,' FunArgType } ] `)' * | '(' [ ‘[using]’ ‘['erased'] TypedFunParam {',' TypedFunParam } ')' */ @@ -1364,7 +1364,7 @@ object Parsers { else Function(params, t) } - def funArgTypesRest(first: Tree, following: () => Tree) = { + def funTypeArgsRest(first: Tree, following: () => Tree) = { val buf = new ListBuffer[Tree] += first while (in.token == COMMA) { in.nextToken() @@ -1387,11 +1387,11 @@ object Parsers { val ts = funArgType() match { case Ident(name) if name != tpnme.WILDCARD && in.isColon() => isValParamList = true - funArgTypesRest( + funTypeArgsRest( typedFunParam(paramStart, name.toTermName, imods), () => typedFunParam(in.offset, ident(), imods)) case t => - funArgTypesRest(t, funArgType) + funTypeArgsRest(t, funArgType) } accept(RPAREN) if isValParamList || in.isArrow then @@ -2907,10 +2907,10 @@ object Parsers { def typeParamClauseOpt(ownerKind: ParamOwner.Value): List[TypeDef] = if (in.token == LBRACKET) typeParamClause(ownerKind) else Nil - /** ContextTypes ::= Type {‘,’ Type} + /** ContextTypes ::= FunArgType {‘,’ FunArgType} */ def contextTypes(ofClass: Boolean, nparams: Int, impliedMods: Modifiers): List[ValDef] = - val tps = commaSeparated(typ) + val tps = commaSeparated(funArgType) var counter = nparams def nextIdx = { counter += 1; counter } val paramFlags = if ofClass then Private | Local | ParamAccessor else Param diff --git a/docs/docs/internals/syntax.md b/docs/docs/internals/syntax.md index 388d0ed6971f..4ecefb4bdb83 100644 --- a/docs/docs/internals/syntax.md +++ b/docs/docs/internals/syntax.md @@ -162,10 +162,10 @@ Type ::= FunType | FunParamClause ‘=>>’ Type TermLambdaTypeTree(ps, t) | MatchType | InfixType -FunType ::= FunArgTypes (‘=>’ | ‘?=>’) Type Function(ts, t) +FunType ::= FunTypeArgs (‘=>’ | ‘?=>’) Type Function(ts, t) | HKTypeParamClause '=>' Type PolyFunction(ps, t) -FunArgTypes ::= InfixType - | ‘(’ [ FunArgType {‘,’ FunArgType } ] ‘)’ +FunTypeArgs ::= InfixType + | ‘(’ [ FunArgTypes ] ‘)’ | FunParamClause FunParamClause ::= ‘(’ TypedFunParam {‘,’ TypedFunParam } ‘)’ TypedFunParam ::= id ‘:’ Type @@ -191,6 +191,7 @@ Singleton ::= SimpleRef Singletons ::= Singleton { ‘,’ Singleton } FunArgType ::= Type | ‘=>’ Type PrefixOp(=>, t) +FunArgTypes ::= FunArgType { ‘,’ FunArgType } ParamType ::= [‘=>’] ParamValueType ParamValueType ::= Type [‘*’] PostfixOp(t, "*") TypeArgs ::= ‘[’ Types ‘]’ ts @@ -323,7 +324,7 @@ HkTypeParam ::= {Annotation} [‘+’ | ‘-’] (id [HkTypeParamClause] ClsParamClauses ::= {ClsParamClause} [[nl] ‘(’ [‘implicit’] ClsParams ‘)’] ClsParamClause ::= [nl] ‘(’ ClsParams ‘)’ - | [nl] ‘(’ ‘using’ (ClsParams | Types) ‘)’ + | [nl] ‘(’ ‘using’ (ClsParams | FunArgTypes) ‘)’ ClsParams ::= ClsParam {‘,’ ClsParam} ClsParam ::= {Annotation} ValDef(mods, id, tpe, expr) -- point of mods on val/var [{Modifier} (‘val’ | ‘var’) | ‘inline’] Param @@ -331,7 +332,7 @@ Param ::= id ‘:’ ParamType [‘=’ Expr] DefParamClauses ::= {DefParamClause} [[nl] ‘(’ [‘implicit’] DefParams ‘)’] DefParamClause ::= [nl] ‘(’ DefParams ‘)’ | UsingParamClause -UsingParamClause ::= [nl] ‘(’ ‘using’ (DefParams | Types) ‘)’ +UsingParamClause ::= [nl] ‘(’ ‘using’ (DefParams | FunArgTypes) ‘)’ DefParams ::= DefParam {‘,’ DefParam} DefParam ::= {Annotation} [‘inline’] Param ValDef(mods, id, tpe, expr) -- point of mods at id. ``` diff --git a/docs/docs/reference/syntax.md b/docs/docs/reference/syntax.md index c3915a1676fc..ddb523efd9ea 100644 --- a/docs/docs/reference/syntax.md +++ b/docs/docs/reference/syntax.md @@ -161,10 +161,10 @@ Type ::= FunType | FunParamClause ‘=>>’ Type | MatchType | InfixType -FunType ::= FunArgTypes (‘=>’ | ‘?=>’) Type +FunType ::= FunTypeArgs (‘=>’ | ‘?=>’) Type | HKTypeParamClause '=>' Type -FunArgTypes ::= InfixType - | ‘(’ [ FunArgType {‘,’ FunArgType } ] ‘)’ +FunTypeArgs ::= InfixType + | ‘(’ [ FunArgTypes ] ‘)’ | FunParamClause FunParamClause ::= ‘(’ TypedFunParam {‘,’ TypedFunParam } ‘)’ TypedFunParam ::= id ‘:’ Type @@ -189,6 +189,7 @@ Singleton ::= SimpleRef FunArgType ::= Type | ‘=>’ Type +FunArgTypes ::= FunArgType { ‘,’ FunArgType } ParamType ::= [‘=>’] ParamValueType ParamValueType ::= Type [‘*’] TypeArgs ::= ‘[’ Types ‘]’ @@ -311,14 +312,14 @@ HkTypeParam ::= {Annotation} [‘+’ | ‘-’] (id [HkTypeParamClause] ClsParamClauses ::= {ClsParamClause} [[nl] ‘(’ [‘implicit’] ClsParams ‘)’] ClsParamClause ::= [nl] ‘(’ ClsParams ‘)’ - | [nl] ‘(’ ‘using’ (ClsParams | Types) ‘)’ + | [nl] ‘(’ ‘using’ (ClsParams | FunArgTypes) ‘)’ ClsParams ::= ClsParam {‘,’ ClsParam} ClsParam ::= {Annotation} [{Modifier} (‘val’ | ‘var’) | ‘inline’] Param Param ::= id ‘:’ ParamType [‘=’ Expr] DefParamClauses ::= {DefParamClause} [[nl] ‘(’ [‘implicit’] DefParams ‘)’] DefParamClause ::= [nl] ‘(’ DefParams ‘)’ | UsingParamClause -UsingParamClause ::= [nl] ‘(’ ‘using’ (DefParams | Types) ‘)’ +UsingParamClause ::= [nl] ‘(’ ‘using’ (DefParams | FunArgTypes) ‘)’ DefParams ::= DefParam {‘,’ DefParam} DefParam ::= {Annotation} [‘inline’] Param ``` diff --git a/tests/pos/i11997.scala b/tests/pos/i11997.scala new file mode 100644 index 000000000000..e6941affedff --- /dev/null +++ b/tests/pos/i11997.scala @@ -0,0 +1,3 @@ +def a(using i: => Int ) = () // ok +def b(using => Int ) = () // ok +