aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/ast/Desugar.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-11-06 18:23:41 +0100
committerMartin Odersky <odersky@gmail.com>2013-11-06 18:23:41 +0100
commit044c498b08428d16ee88aadb73588a7a3337d545 (patch)
tree0f4a3ae7deead3394e18bbf19f3bbb655a3125eb /src/dotty/tools/dotc/ast/Desugar.scala
parent2617235fdb1b569bc4069f51b1cc9fa2557d10c4 (diff)
downloaddotty-044c498b08428d16ee88aadb73588a7a3337d545.tar.gz
dotty-044c498b08428d16ee88aadb73588a7a3337d545.tar.bz2
dotty-044c498b08428d16ee88aadb73588a7a3337d545.zip
Changing for-expansion for irrefutable patterns.
p <- xs for irrefutable pattern `p` used to be expanded to `xs.withFilterIfRefutable`, now is expanded to just `xs.withFilter`.
Diffstat (limited to 'src/dotty/tools/dotc/ast/Desugar.scala')
-rw-r--r--src/dotty/tools/dotc/ast/Desugar.scala43
1 files changed, 33 insertions, 10 deletions
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala
index d3ffa0c91..cbac66b6b 100644
--- a/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/src/dotty/tools/dotc/ast/Desugar.scala
@@ -416,6 +416,39 @@ object desugar {
case _ => Bind(ctx.freshName().toTermName, pat)
}
+ /** Make a pattern filter:
+ * rhs.withFilter { case pat => true case _ => false }
+ *
+ * On handling irrefutable patterns:
+ * The idea is to wait until the pattern matcher sees a call
+ *
+ * xs withFilter { cases }
+ *
+ * where cases can be proven to be refutable i.e. cases would be
+ * equivalent to { case _ => true }
+ *
+ * In that case, compile to
+ *
+ * xs withFilter alwaysTrue
+ *
+ * where `alwaysTrue` is a predefined function value:
+ *
+ * val alwaysTrue: Any => Boolean = true
+ *
+ * In the libraries operations can take advantage of alwaysTrue to shortcircuit the
+ * withFilter call.
+ *
+ * def withFilter(f: Elem => Boolean) =
+ * if (f eq alwaysTrue) this // or rather identity filter monadic applied to this
+ * else real withFilter
+ */
+ def makePatFilter(rhs: Tree, pat: Tree): Tree = {
+ val cases = List(
+ CaseDef(pat, EmptyTree, Literal(Constant(true))),
+ CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(Constant(false))))
+ Apply(Select(rhs, nme.withFilter), Match(EmptyTree, cases))
+ }
+
/** Is pattern `pat` irrefutable when matched against `rhs`?
* We only can do a simple syntactic check here; a more refined check
* is done later prompted by the presence of a "withFilterIfRefutable" call.
@@ -439,16 +472,6 @@ object desugar {
}
}
- /** Make a pattern filter:
- * rhs.withFilterIfRefutable { case pat => true case _ => false }
- */
- def makePatFilter(rhs: Tree, pat: Tree): Tree = {
- val cases = List(
- CaseDef(pat, EmptyTree, Literal(Constant(true))),
- CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(Constant(false))))
- Apply(Select(rhs, nme.withFilterIfRefutable), Match(EmptyTree, cases))
- }
-
/** rhs.name with a pattern filter on rhs unless `pat` is irrefutable when
* matched against `rhs`.
*/