summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSom Snytt <som.snytt@gmail.com>2016-01-30 21:53:27 -0800
committerSom Snytt <som.snytt@gmail.com>2016-05-20 16:12:03 -0700
commiteeef2602dc97f84c798713d7a2c924ea2b0d6012 (patch)
tree06a2e64b97d73f303583f82af8bdfafc75aff477
parent15189d14953335f7a3a8310861d045d21ab22d48 (diff)
downloadscala-eeef2602dc97f84c798713d7a2c924ea2b0d6012.tar.gz
scala-eeef2602dc97f84c798713d7a2c924ea2b0d6012.tar.bz2
scala-eeef2602dc97f84c798713d7a2c924ea2b0d6012.zip
SI-8044 Allow binding backquoted varid in patterns
Previously, a varid could not be backquoted, so that it was not possible to introduce variables with names such as `type` in a match expression. This commit allows backquoted varids in `case x @ _` and `case x: Int`. In neither position is a stable id accepted, that is, an id with leading uppercase. Therefore, this commit merely relaxes the backquoted varid to be taken as a normal varid in these contexts.
-rw-r--r--spec/01-lexical-syntax.md2
-rw-r--r--spec/08-pattern-matching.md4
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala15
-rw-r--r--test/files/neg/t8044.check4
-rw-r--r--test/files/neg/t8044.scala4
-rw-r--r--test/files/pos/t8044.scala7
6 files changed, 27 insertions, 9 deletions
diff --git a/spec/01-lexical-syntax.md b/spec/01-lexical-syntax.md
index 0232ed9a34..4e92c7cf7b 100644
--- a/spec/01-lexical-syntax.md
+++ b/spec/01-lexical-syntax.md
@@ -49,6 +49,8 @@ classes (Unicode general category given in parentheses):
```ebnf
op ::= opchar {opchar}
varid ::= lower idrest
+boundvarid ::= varid
+ | ‘`’ varid ‘`’
plainid ::= upper idrest
| varid
| op
diff --git a/spec/08-pattern-matching.md b/spec/08-pattern-matching.md
index 3b481eea86..6753fa3ec7 100644
--- a/spec/08-pattern-matching.md
+++ b/spec/08-pattern-matching.md
@@ -10,10 +10,10 @@ chapter: 8
```ebnf
Pattern ::= Pattern1 { ‘|’ Pattern1 }
- Pattern1 ::= varid ‘:’ TypePat
+ Pattern1 ::= boundvarid ‘:’ TypePat
| ‘_’ ‘:’ TypePat
| Pattern2
- Pattern2 ::= varid [‘@’ Pattern3]
+ Pattern2 ::= boundvarid [‘@’ Pattern3]
| Pattern3
Pattern3 ::= SimplePattern
| SimplePattern {id [nl] SimplePattern}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 9c0174d89b..1e239f91a6 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -1901,19 +1901,20 @@ self =>
}
/** {{{
- * Pattern1 ::= varid `:' TypePat
+ * Pattern1 ::= boundvarid `:' TypePat
* | `_' `:' TypePat
* | Pattern2
- * SeqPattern1 ::= varid `:' TypePat
+ * SeqPattern1 ::= boundvarid `:' TypePat
* | `_' `:' TypePat
* | [SeqPattern2]
* }}}
*/
def pattern1(): Tree = pattern2() match {
case p @ Ident(name) if in.token == COLON =>
- if (treeInfo.isVarPattern(p))
+ if (nme.isVariableName(name)) {
+ p.removeAttachment[BackquotedIdentifierAttachment.type]
atPos(p.pos.start, in.skipToken())(Typed(p, compoundType()))
- else {
+ } else {
syntaxError(in.offset, "Pattern variables must start with a lower-case letter. (SLS 8.1.1.)")
p
}
@@ -1921,9 +1922,9 @@ self =>
}
/** {{{
- * Pattern2 ::= varid [ @ Pattern3 ]
+ * Pattern2 ::= boundvarid [ @ Pattern3 ]
* | Pattern3
- * SeqPattern2 ::= varid [ @ SeqPattern3 ]
+ * SeqPattern2 ::= boundvarid [ @ SeqPattern3 ]
* | SeqPattern3
* }}}
*/
@@ -1935,7 +1936,7 @@ self =>
case Ident(nme.WILDCARD) =>
in.nextToken()
pattern3()
- case Ident(name) if treeInfo.isVarPattern(p) =>
+ case Ident(name) if nme.isVariableName(name) =>
in.nextToken()
atPos(p.pos.start) { Bind(name, pattern3()) }
case _ => p
diff --git a/test/files/neg/t8044.check b/test/files/neg/t8044.check
new file mode 100644
index 0000000000..678bf8c700
--- /dev/null
+++ b/test/files/neg/t8044.check
@@ -0,0 +1,4 @@
+t8044.scala:3: error: not found: value _
+ def f = 42 match { case `_` : Int => `_` } // doesn't leak quoted underscore
+ ^
+one error found
diff --git a/test/files/neg/t8044.scala b/test/files/neg/t8044.scala
new file mode 100644
index 0000000000..930c30c5a5
--- /dev/null
+++ b/test/files/neg/t8044.scala
@@ -0,0 +1,4 @@
+
+trait T {
+ def f = 42 match { case `_` : Int => `_` } // doesn't leak quoted underscore
+}
diff --git a/test/files/pos/t8044.scala b/test/files/pos/t8044.scala
new file mode 100644
index 0000000000..8259f06a8a
--- /dev/null
+++ b/test/files/pos/t8044.scala
@@ -0,0 +1,7 @@
+
+trait T {
+ def f = 42 match { case `x` @ _ => x }
+ def g = 42 match { case `type` @ _ => `type` }
+ def h = 42 match { case `type` : Int => `type` }
+ def i = (null: Any) match { case _: Int | _: String => 17 }
+}