From f4ab855b03e9fc0fac31018bf9383220d2399697 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 18 Aug 2016 09:08:34 +0200 Subject: [PATCH 1/3] Fixes in comparisons between singleton types Needed to address problem shown by z1720.scala. Another fix to avoidance is needed to make it pass completely. --- src/dotty/tools/dotc/core/TypeComparer.scala | 12 ++++-------- tests/{pending => }/pos/z1720.scala | 0 2 files changed, 4 insertions(+), 8 deletions(-) rename tests/{pending => }/pos/z1720.scala (100%) diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index 0757c8187cf4..8d7e9d1641cc 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -525,14 +525,10 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { /** if `tp2 == p.type` and `p: q.type` then try `tp1 <:< q.type` as a last effort.*/ def comparePaths = tp2 match { case tp2: TermRef => - tp2.info match { - case tp2i: TermRef => - isSubType(tp1, tp2i) - case ExprType(tp2i: TermRef) if (ctx.phase.id > ctx.gettersPhase.id) => - // After getters, val x: T becomes def x: T - isSubType(tp1, tp2i) - case _ => - false + tp2.info.widenExpr match { + case tp2i: SingletonType => + isSubType(tp1, tp2i) // see z1720.scala for a case where this can arise even in typer. + case _ => false } case _ => false diff --git a/tests/pending/pos/z1720.scala b/tests/pos/z1720.scala similarity index 100% rename from tests/pending/pos/z1720.scala rename to tests/pos/z1720.scala From f006688d34e18553c8df800951cfa73c1aee4ea7 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 18 Aug 2016 09:12:04 +0200 Subject: [PATCH 2/3] Fix to avoidance of singleton type arguments Bring in line with comparisons. Fixes z1720 for good. --- src/dotty/tools/dotc/typer/TypeAssigner.scala | 5 ++++- tests/pending/pos/spec-t5545/S_1.scala | 4 ---- tests/pending/pos/spec-t5545/S_2.scala | 4 ---- 3 files changed, 4 insertions(+), 9 deletions(-) delete mode 100644 tests/pending/pos/spec-t5545/S_1.scala delete mode 100644 tests/pending/pos/spec-t5545/S_2.scala diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala index e0a9dbafc4b6..a6e2deb237cb 100644 --- a/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -59,7 +59,10 @@ trait TypeAssigner { case _ => false } def apply(tp: Type): Type = tp match { - case tp: TermRef if toAvoid(tp) && variance > 0 => + case tp: TermRef + if toAvoid(tp) && (variance > 0 || tp.info.widenExpr <:< tp) => + // Can happen if `x: y.type`, then `x.type =:= y.type`, hence we can widen `x.type` + // to y.type in all contexts, not just covariant ones. apply(tp.info.widenExpr) case tp: TypeRef if toAvoid(tp) => tp.info match { diff --git a/tests/pending/pos/spec-t5545/S_1.scala b/tests/pending/pos/spec-t5545/S_1.scala deleted file mode 100644 index 59ec1fd851a5..000000000000 --- a/tests/pending/pos/spec-t5545/S_1.scala +++ /dev/null @@ -1,4 +0,0 @@ -trait F[@specialized(Int) T1, R] { - def f(v1: T1): R - def g = v1 => f(v1) -} diff --git a/tests/pending/pos/spec-t5545/S_2.scala b/tests/pending/pos/spec-t5545/S_2.scala deleted file mode 100644 index 59ec1fd851a5..000000000000 --- a/tests/pending/pos/spec-t5545/S_2.scala +++ /dev/null @@ -1,4 +0,0 @@ -trait F[@specialized(Int) T1, R] { - def f(v1: T1): R - def g = v1 => f(v1) -} From b8bb504035b5178dfe82cc42e818e3e8fb591465 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 18 Aug 2016 17:03:12 +0200 Subject: [PATCH 3/3] Add passing test Needs to be done in pos-special because junit tests do not recognize _1, _2. --- test/dotc/tests.scala | 7 +++++++ tests/pos-special/spec-t5545/S_1.scala | 4 ++++ tests/pos-special/spec-t5545/S_2.scala | 4 ++++ 3 files changed, 15 insertions(+) create mode 100644 tests/pos-special/spec-t5545/S_1.scala create mode 100644 tests/pos-special/spec-t5545/S_2.scala diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala index ad4846c18f7d..31e74fa97cf8 100644 --- a/test/dotc/tests.scala +++ b/test/dotc/tests.scala @@ -111,6 +111,13 @@ class tests extends CompilerTest { @Test def pos_859 = compileFile(posSpecialDir, "i859", scala2mode)(allowDeepSubtypes) + @Test def pos_t5545 = { + // compile by hand in two batches, since junit lacks the infrastructure to + // compile files in multiple batches according to _1, _2, ... suffixes. + compileFile(posSpecialDir, "spec-t5545/S_1") + compileFile(posSpecialDir, "spec-t5545/S_2") + } + @Test def new_all = compileFiles(newDir, twice) @Test def repl_all = replFiles(replDir) diff --git a/tests/pos-special/spec-t5545/S_1.scala b/tests/pos-special/spec-t5545/S_1.scala new file mode 100644 index 000000000000..59ec1fd851a5 --- /dev/null +++ b/tests/pos-special/spec-t5545/S_1.scala @@ -0,0 +1,4 @@ +trait F[@specialized(Int) T1, R] { + def f(v1: T1): R + def g = v1 => f(v1) +} diff --git a/tests/pos-special/spec-t5545/S_2.scala b/tests/pos-special/spec-t5545/S_2.scala new file mode 100644 index 000000000000..59ec1fd851a5 --- /dev/null +++ b/tests/pos-special/spec-t5545/S_2.scala @@ -0,0 +1,4 @@ +trait F[@specialized(Int) T1, R] { + def f(v1: T1): R + def g = v1 => f(v1) +}