diff options
author | Martin Odersky <odersky@gmail.com> | 2013-11-06 18:23:41 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-11-06 18:23:41 +0100 |
commit | 044c498b08428d16ee88aadb73588a7a3337d545 (patch) | |
tree | 0f4a3ae7deead3394e18bbf19f3bbb655a3125eb /src/dotty/tools/dotc/ast/Desugar.scala | |
parent | 2617235fdb1b569bc4069f51b1cc9fa2557d10c4 (diff) | |
download | dotty-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.scala | 43 |
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`. */ |