diff options
-rw-r--r-- | src/dotty/tools/dotc/ast/Desugar.scala | 16 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 12 | ||||
-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.scala | 12 |
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 + +} |