aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/ast/Desugar.scala16
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala12
-rw-r--r--tests/disabled/not-representable/t7035.scala (renamed from tests/pending/pos/t7035.scala)2
-rw-r--r--tests/disabled/not-representable/t7228.scala (renamed from tests/pending/pos/t7228.scala)1
-rw-r--r--tests/pos/for-filter.scala12
5 files changed, 38 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala
index 346af42b8..500b28233 100644
--- a/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/src/dotty/tools/dotc/ast/Desugar.scala
@@ -8,6 +8,7 @@ import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
import Decorators._
import language.higherKinds
import collection.mutable.ListBuffer
+import util.Attachment
import config.Printers._
object desugar {
@@ -17,6 +18,11 @@ object desugar {
import untpd._
+ /** Tags a .withFilter call generated by desugaring a for expression.
+ * Such calls can alternatively be rewritten to use filter.
+ */
+ val MaybeFilter = new Attachment.Key[Unit]
+
/** Info of a variable in a pattern: The named tree and its type */
private type VarInfo = (NameTree, Tree)
@@ -773,6 +779,12 @@ object desugar {
(Bind(name, pat), Ident(name))
}
+ /** Add MaybeFilter attachment */
+ def orFilter(tree: Tree): tree.type = {
+ tree.putAttachment(MaybeFilter, ())
+ tree
+ }
+
/** Make a pattern filter:
* rhs.withFilter { case pat => true case _ => false }
*
@@ -803,7 +815,7 @@ object desugar {
val cases = List(
CaseDef(pat, EmptyTree, Literal(Constant(true))),
CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(Constant(false))))
- Apply(Select(rhs, nme.withFilter), makeCaseLambda(cases))
+ Apply(orFilter(Select(rhs, nme.withFilter)), makeCaseLambda(cases))
}
/** Is pattern `pat` irrefutable when matched against `rhs`?
@@ -858,7 +870,7 @@ object desugar {
val vfrom1 = new IrrefutableGenFrom(makeTuple(allpats), rhs1)
makeFor(mapName, flatMapName, vfrom1 :: rest1, body)
case (gen: GenFrom) :: test :: rest =>
- val filtered = Apply(rhsSelect(gen, nme.withFilter), makeLambda(gen.pat, test))
+ val filtered = Apply(orFilter(rhsSelect(gen, nme.withFilter)), makeLambda(gen.pat, test))
val genFrom =
if (isIrrefutableGenFrom(gen)) new IrrefutableGenFrom(gen.pat, filtered)
else GenFrom(gen.pat, filtered)
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 934ca556d..c9a2e4b48 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -346,11 +346,17 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
}
- if (ctx.compilationUnit.isJava && tree.name.isTypeName) {
+ def selectWithFallback(fallBack: => Tree) =
+ tryEither(tryCtx => asSelect(tryCtx))((_, _) => fallBack)
+
+ if (ctx.compilationUnit.isJava && tree.name.isTypeName)
// SI-3120 Java uses the same syntax, A.B, to express selection from the
// value A and from the type A. We have to try both.
- tryEither(tryCtx => asSelect(tryCtx))((_, _) => asJavaSelectFromTypeTree(ctx))
- } else asSelect(ctx)
+ selectWithFallback(asJavaSelectFromTypeTree(ctx))
+ else if (tree.name == nme.withFilter && tree.getAttachment(desugar.MaybeFilter).isDefined)
+ selectWithFallback(typedSelect(untpd.cpy.Select(tree)(tree.qualifier, nme.filter), pt))
+ else
+ asSelect(ctx)
}
def typedSelectFromTypeTree(tree: untpd.SelectFromTypeTree, pt: Type)(implicit ctx: Context): Tree = track("typedSelectFromTypeTree") {
diff --git a/tests/pending/pos/t7035.scala b/tests/disabled/not-representable/t7035.scala
index f45bd0a87..b1ce66cc6 100644
--- a/tests/pending/pos/t7035.scala
+++ b/tests/disabled/not-representable/t7035.scala
@@ -1,3 +1,5 @@
+// no longer works because dotty uses name-nased pattern matching for case classes
+
case class Y(final var x: Int, final private var y: String, final val z1: Boolean, final private val z2: Any) {
import Test.{y => someY}
diff --git a/tests/pending/pos/t7228.scala b/tests/disabled/not-representable/t7228.scala
index 5d936f652..525327857 100644
--- a/tests/pending/pos/t7228.scala
+++ b/tests/disabled/not-representable/t7228.scala
@@ -1,3 +1,4 @@
+// no longer works because dotty does not have a concept of weak conformance
object AdaptWithWeaklyConformantType {
implicit class D(d: Double) { def double = d*2 }
diff --git a/tests/pos/for-filter.scala b/tests/pos/for-filter.scala
new file mode 100644
index 000000000..3baac4f0c
--- /dev/null
+++ b/tests/pos/for-filter.scala
@@ -0,0 +1,12 @@
+object Test {
+
+ case class C[T](xs: List[T]) {
+ def filter(p: T => Boolean) = new C(xs.filter(p))
+ def map[U](f: T => U) = new C(xs.map(f))
+ }
+
+ def main(args: Array[String]): Unit =
+ println(for (x <- C(List(1, 2, 3)) if x % 2 == 0) yield x)
+ // println(C(List(1, 2, 3)).withFilter(_ % 2 == 0)) // error
+
+}