From 9a6c0f81526c632022349dd33431cb79e048cbcc Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 25 Dec 2016 16:38:18 +0700 Subject: Fix #1716: Don't allow wildcards as type arguments to methods Wildcards don't make sense as type arguments to methods, and I believe to keep things simple this should also apply to method type arguments in patterns. The best way to enforce this is to make use of the existing infrastructure in the parser for topLevelTypes. --- compiler/src/dotty/tools/dotc/parsing/Parsers.scala | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'compiler/src/dotty/tools/dotc/parsing/Parsers.scala') diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 57dd1ea20..1e8fb9d26 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -783,7 +783,9 @@ object Parsers { */ def simpleType(): Tree = simpleTypeRest { if (in.token == LPAREN) - atPos(in.offset) { makeTupleOrParens(inParens(argTypes())) } + atPos(in.offset) { + makeTupleOrParens(inParens(argTypes(namedOK = false, wildOK = true))) + } else if (in.token == LBRACE) atPos(in.offset) { RefinedTypeTree(EmptyTree, refinement()) } else if (isSimpleLiteral) { SingletonTypeTree(literal()) } @@ -805,7 +807,8 @@ object Parsers { private def simpleTypeRest(t: Tree): Tree = in.token match { case HASH => simpleTypeRest(typeProjection(t)) - case LBRACKET => simpleTypeRest(atPos(startOffset(t)) { AppliedTypeTree(t, typeArgs(namedOK = true)) }) + case LBRACKET => simpleTypeRest(atPos(startOffset(t)) { + AppliedTypeTree(t, typeArgs(namedOK = true, wildOK = true)) }) case _ => t } @@ -826,7 +829,7 @@ object Parsers { /** ArgTypes ::= Type {`,' Type} * | NamedTypeArg {`,' NamedTypeArg} */ - def argTypes(namedOK: Boolean = false) = { + def argTypes(namedOK: Boolean, wildOK: Boolean) = { def otherArgs(first: Tree, arg: () => Tree): List[Tree] = { val rest = if (in.token == COMMA) { @@ -836,8 +839,9 @@ object Parsers { else Nil first :: rest } + def typParser() = if (wildOK) typ() else toplevelTyp() if (namedOK && in.token == IDENTIFIER) - typ() match { + typParser() match { case Ident(name) if in.token == EQUALS => in.nextToken() otherArgs(NamedArg(name, typ()), namedTypeArg) @@ -845,7 +849,7 @@ object Parsers { if (in.token == EQUALS) println(s"??? $firstArg") otherArgs(firstArg, typ) } - else commaSeparated(typ) + else commaSeparated(typParser) } /** FunArgType ::= Type | `=>' Type @@ -873,7 +877,7 @@ object Parsers { /** TypeArgs ::= `[' Type {`,' Type} `]' * NamedTypeArgs ::= `[' NamedTypeArg {`,' NamedTypeArg} `]' */ - def typeArgs(namedOK: Boolean = false): List[Tree] = inBrackets(argTypes(namedOK)) + def typeArgs(namedOK: Boolean, wildOK: Boolean): List[Tree] = inBrackets(argTypes(namedOK, wildOK)) /** Refinement ::= `{' RefineStatSeq `}' */ @@ -1250,7 +1254,7 @@ object Parsers { in.nextToken() simpleExprRest(selector(t), canApply = true) case LBRACKET => - val tapp = atPos(startOffset(t), in.offset) { TypeApply(t, typeArgs(namedOK = true)) } + val tapp = atPos(startOffset(t), in.offset) { TypeApply(t, typeArgs(namedOK = true, wildOK = false)) } simpleExprRest(tapp, canApply = true) case LPAREN | LBRACE if canApply => val app = atPos(startOffset(t), in.offset) { Apply(t, argumentExprs()) } @@ -1501,7 +1505,7 @@ object Parsers { def simplePatternRest(t: Tree): Tree = { var p = t if (in.token == LBRACKET) - p = atPos(startOffset(t), in.offset) { TypeApply(p, typeArgs()) } + p = atPos(startOffset(t), in.offset) { TypeApply(p, typeArgs(namedOK = false, wildOK = false)) } if (in.token == LPAREN) p = atPos(startOffset(t), in.offset) { Apply(p, argumentPatterns()) } p -- cgit v1.2.3