summaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2012-11-13 11:21:17 +0100
committerJason Zaugg <jzaugg@gmail.com>2012-11-13 18:40:30 +0100
commitb9e3ea7f070806631fd318e43082bc0653a79410 (patch)
tree178c70bda0a06a6f828738196b27dbaf6ac0c76d /src/reflect
parent8b2caf0746fd4405f2d47b54d17d484e6603c89d (diff)
downloadscala-b9e3ea7f070806631fd318e43082bc0653a79410.tar.gz
scala-b9e3ea7f070806631fd318e43082bc0653a79410.tar.bz2
scala-b9e3ea7f070806631fd318e43082bc0653a79410.zip
SI-6646 `ident` or Ident is always new binding.
The previous commit regressed in these cases: // no withFilter for (X <- List("A single ident is always a pattern")) println(X) for (`x` <- List("A single ident is always a pattern")) println(`x`) At the top level of the LHS of a <-, such identifiers represent new bindings, not stable identifier patterns.
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala84
1 files changed, 59 insertions, 25 deletions
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 56a0bac72b..90f4f6fc8f 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -245,31 +245,65 @@ abstract class TreeInfo {
isSelfConstrCall(tree1) || isSuperConstrCall(tree1)
}
- /** Is this tree comprised of nothing but identifiers,
- * but possibly in bindings or tuples? For instance:
- *
- * {{{
- * foo @ (bar, (baz, quux))
- * }}}
- *
- * is a variable pattern; if the structure matches,
- * then the remainder is inevitable.
- *
- * The following are not variable patterns.
- *
- * {{{
- * foo @ (bar, (`baz`, Quux))
- * foo @ (bar, Quux)
- * }}}
- */
- def isVarPatternDeep(tree: Tree): Boolean = tree match {
- case Bind(name, pat) => isVarPatternDeep(pat)
- case Ident(name) => isVarPattern(tree)
- case Apply(sel, args) =>
- ( isReferenceToScalaMember(sel, TupleClass(args.size).name.toTermName)
- && (args forall isVarPatternDeep)
- )
- case _ => false
+ /**
+ * Does this tree represent an irrefutable pattern match
+ * in the position `for { <tree> <- expr }` based only
+ * on information at the `parser` phase? To qualify, there
+ * may be no Stable Identifier Patterns.
+ *
+ * For instance:
+ *
+ * {{{
+ * foo @ (bar, (baz, quux))
+ * }}}
+ *
+ * is a variable pattern; if the structure matches,
+ * then the remainder is inevitable.
+ *
+ * The following are not variable patterns.
+ *
+ * {{{
+ * foo @ (bar, (`baz`, quux)) // back quoted ident, not at top level
+ * foo @ (bar, Quux) // UpperCase ident, not at top level
+ * }}}
+ *
+ * If the pattern is a simple identifier, it is always
+ * a variable pattern. For example, the following
+ * introduce new bindings:
+ *
+ * {{{
+ * for { X <- xs } yield X
+ * for { `backquoted` <- xs } yield `backquoted`
+ * }}}
+ *
+ * Note that this differs from a case clause:
+ *
+ * {{{
+ * object X
+ * scrut match {
+ * case X => // case _ if scrut == X
+ * }
+ * }}}
+ *
+ * Background: [[https://groups.google.com/d/msg/scala-internals/qwa_XOw_7Ks/IktkeTBYqg0J]]
+ *
+ */
+ def isVarPatternDeep(tree: Tree): Boolean = {
+ def isVarPatternDeep0(tree: Tree): Boolean = {
+ tree match {
+ case Bind(name, pat) => isVarPatternDeep0(pat)
+ case Ident(name) => isVarPattern(tree)
+ case Apply(sel, args) =>
+ ( isReferenceToScalaMember(sel, TupleClass(args.size).name.toTermName)
+ && (args forall isVarPatternDeep0)
+ )
+ case _ => false
+ }
+ }
+ tree match {
+ case Ident(name) => true
+ case _ => isVarPatternDeep0(tree)
+ }
}
/** Is tree a variable pattern? */