From 9a6c0f81526c632022349dd33431cb79e048cbcc Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 25 Dec 2016 16:38:18 +0700 Subject: [PATCH 1/2] 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. --- .../dotty/tools/dotc/parsing/Parsers.scala | 20 +++++++++++-------- tests/pending/neg/i1716.scala | 9 +++++++++ 2 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 tests/pending/neg/i1716.scala diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 57dd1ea20b07..1e8fb9d26ffb 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 diff --git a/tests/pending/neg/i1716.scala b/tests/pending/neg/i1716.scala new file mode 100644 index 000000000000..1a3fd71d0a77 --- /dev/null +++ b/tests/pending/neg/i1716.scala @@ -0,0 +1,9 @@ +object Fail { + def f(m: Option[Int]): Unit = { + m match { + case x @ Some[_] => // error + case _ => + } + } + Some[_] // error +} From 09e15bdcbc4a9b4bb67c8f0651fd37539748f7cd Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 26 Dec 2016 14:50:06 +0700 Subject: [PATCH 2/2] Move test into the right directory --- tests/{pending => }/neg/i1716.scala | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/{pending => }/neg/i1716.scala (100%) diff --git a/tests/pending/neg/i1716.scala b/tests/neg/i1716.scala similarity index 100% rename from tests/pending/neg/i1716.scala rename to tests/neg/i1716.scala