diff options
author | Martin Odersky <odersky@gmail.com> | 2016-12-25 16:38:18 +0700 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-12-25 16:38:18 +0700 |
commit | 9a6c0f81526c632022349dd33431cb79e048cbcc (patch) | |
tree | 78ddc5c8aad679970356069f1d13e3f48105945c /compiler/src/dotty/tools/dotc/parsing/Parsers.scala | |
parent | 119725799675ee00d6d3374771765b88e4de67bc (diff) | |
download | dotty-9a6c0f81526c632022349dd33431cb79e048cbcc.tar.gz dotty-9a6c0f81526c632022349dd33431cb79e048cbcc.tar.bz2 dotty-9a6c0f81526c632022349dd33431cb79e048cbcc.zip |
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.
Diffstat (limited to 'compiler/src/dotty/tools/dotc/parsing/Parsers.scala')
-rw-r--r-- | compiler/src/dotty/tools/dotc/parsing/Parsers.scala | 20 |
1 files changed, 12 insertions, 8 deletions
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 |