From 099b91b8c6aa38614ca19e1e0312c770b842d44a Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Fri, 4 Aug 2017 13:42:44 +0200 Subject: [PATCH 1/5] Fix #2944: propagate information from GADT bounds to normal info. This allows all other parts of pipeline to be less aware of existence of the GADT bounds. In particular, it makes us pickle them as normal type bounds. --- .../src/dotty/tools/dotc/transform/PostTyper.scala | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala index 9db297324014..144eb45d856c 100644 --- a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala +++ b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala @@ -45,6 +45,8 @@ import reporting.diagnostic.messages.SuperCallsNotAllowedInline * (11) Minimizes `call` fields of `Inline` nodes to just point to the toplevel * class from which code was inlined. * + * (12) Converts GADT bounds into normal type bounds + * * The reason for making this a macro transform is that some functions (in particular * super and protected accessors and instantiation checks) are naturally top-down and * don't lend themselves to the bottom-up approach of a mini phase. The other two functions @@ -52,10 +54,17 @@ import reporting.diagnostic.messages.SuperCallsNotAllowedInline * mini-phase or subfunction of a macro phase equally well. But taken by themselves * they do not warrant their own group of miniphases before pickling. */ -class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTransformer => +class PostTyper extends MacroTransform with SymTransformer { thisTransformer => + import tpd._ + def transformSym(sym: SymDenotation)(implicit ctx: Context): SymDenotation = { + if (sym.is(BindDefinedType) && ctx.gadt.bounds.contains(sym.symbol)) { + sym.copySymDenotation(info = ctx.gadt.bounds.apply(sym.symbol) & sym.info) + } else sym + } + /** the following two members override abstract members in Transform */ override def phaseName: String = "posttyper" From bfa3d69e2bf9b834d7c04a0e37ff12a84f4916d9 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Fri, 4 Aug 2017 13:59:02 +0200 Subject: [PATCH 2/5] Add testfile for #2944. --- tests/pos/i2944.scala | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 tests/pos/i2944.scala diff --git a/tests/pos/i2944.scala b/tests/pos/i2944.scala new file mode 100644 index 000000000000..a6c7a92c7b2d --- /dev/null +++ b/tests/pos/i2944.scala @@ -0,0 +1,10 @@ +trait Map2[K] { + def get(k: K): K = k + def foo: K = { + this match { + case that: Map2[b] => that.get(3.asInstanceOf[b]) + //case that: Map2[c] => that.get(4.asInstanceOf[K]) + case _ => get(5.asInstanceOf[K]) + } + } +} From c45a3bcde09a6672f01829482225b4aab8d031af Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Fri, 4 Aug 2017 16:41:43 +0200 Subject: [PATCH 3/5] Fix Binds being read from tasty as if they were type trees. binds are "shared" as type trees would be shared, see https://github.com/lampepfl/dotty/pull/2510 But they are not type trees, as you can't have them inside TypeApply. See i2944a.scala. --- .../src/dotty/tools/dotc/core/tasty/TastyFormat.scala | 3 ++- .../dotty/tools/dotc/core/tasty/TreeUnpickler.scala | 10 +++++++++- tests/pos/i2944.scala | 1 - tests/pos/i2944a.scala | 8 ++++++++ 4 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 tests/pos/i2944a.scala diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala index df8caa1b8653..d0bad5bd316d 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala @@ -434,7 +434,8 @@ object TastyFormat { | ANDtpt | ORtpt | BYNAMEtpt - | BIND => true + | BIND => true // Dmitry: binds are "shared" as type trees would be shared, see https://github.com/lampepfl/dotty/pull/2510 + // But they are not type trees, as you can't have them inside TypeApply. See i2944a.scala case _ => false } diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index bf3b593b9a94..f0bc7c5b640f 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -1029,7 +1029,15 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi } def readTpt()(implicit ctx: Context) = - if (isTypeTreeTag(nextUnsharedTag)) readTerm() + if (isTypeTreeTag(nextUnsharedTag)) { + val isShared = nextByte == SHARED + val term = readTerm() + term match { + case a: DefTree if isShared => + ref(a.namedType) + case _ => term + } + } else { val start = currentAddr val tp = readType() diff --git a/tests/pos/i2944.scala b/tests/pos/i2944.scala index a6c7a92c7b2d..80c1a0906ebc 100644 --- a/tests/pos/i2944.scala +++ b/tests/pos/i2944.scala @@ -3,7 +3,6 @@ trait Map2[K] { def foo: K = { this match { case that: Map2[b] => that.get(3.asInstanceOf[b]) - //case that: Map2[c] => that.get(4.asInstanceOf[K]) case _ => get(5.asInstanceOf[K]) } } diff --git a/tests/pos/i2944a.scala b/tests/pos/i2944a.scala new file mode 100644 index 000000000000..179890e11a9a --- /dev/null +++ b/tests/pos/i2944a.scala @@ -0,0 +1,8 @@ +trait Map2[K] { + def get(k: K): K = k + def foo: K = { + this match { + case that: Map2[c] => that.get(4.asInstanceOf[K]) + } + } +} From 01396735fa6d3034faf041ceaf32890bf440a54c Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 31 Aug 2017 10:12:49 +0200 Subject: [PATCH 4/5] Revert "Fix Binds being read from tasty as if they were type trees." This reverts commit 30ec34f5758a64c952f3c5535ec8a5522360aba0. --- .../src/dotty/tools/dotc/core/tasty/TastyFormat.scala | 3 +-- .../dotty/tools/dotc/core/tasty/TreeUnpickler.scala | 10 +--------- tests/pos/i2944.scala | 1 + tests/pos/i2944a.scala | 8 -------- 4 files changed, 3 insertions(+), 19 deletions(-) delete mode 100644 tests/pos/i2944a.scala diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala index d0bad5bd316d..df8caa1b8653 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala @@ -434,8 +434,7 @@ object TastyFormat { | ANDtpt | ORtpt | BYNAMEtpt - | BIND => true // Dmitry: binds are "shared" as type trees would be shared, see https://github.com/lampepfl/dotty/pull/2510 - // But they are not type trees, as you can't have them inside TypeApply. See i2944a.scala + | BIND => true case _ => false } diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index f0bc7c5b640f..bf3b593b9a94 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -1029,15 +1029,7 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi } def readTpt()(implicit ctx: Context) = - if (isTypeTreeTag(nextUnsharedTag)) { - val isShared = nextByte == SHARED - val term = readTerm() - term match { - case a: DefTree if isShared => - ref(a.namedType) - case _ => term - } - } + if (isTypeTreeTag(nextUnsharedTag)) readTerm() else { val start = currentAddr val tp = readType() diff --git a/tests/pos/i2944.scala b/tests/pos/i2944.scala index 80c1a0906ebc..a6c7a92c7b2d 100644 --- a/tests/pos/i2944.scala +++ b/tests/pos/i2944.scala @@ -3,6 +3,7 @@ trait Map2[K] { def foo: K = { this match { case that: Map2[b] => that.get(3.asInstanceOf[b]) + //case that: Map2[c] => that.get(4.asInstanceOf[K]) case _ => get(5.asInstanceOf[K]) } } diff --git a/tests/pos/i2944a.scala b/tests/pos/i2944a.scala deleted file mode 100644 index 179890e11a9a..000000000000 --- a/tests/pos/i2944a.scala +++ /dev/null @@ -1,8 +0,0 @@ -trait Map2[K] { - def get(k: K): K = k - def foo: K = { - this match { - case that: Map2[c] => that.get(4.asInstanceOf[K]) - } - } -} From 1c0f63f3d1cc7493eab6901a7b3ec52784e1ea87 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 31 Aug 2017 10:14:37 +0200 Subject: [PATCH 5/5] Change argument name --- compiler/src/dotty/tools/dotc/transform/PostTyper.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala index 144eb45d856c..7a4213bac17a 100644 --- a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala +++ b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala @@ -59,10 +59,10 @@ class PostTyper extends MacroTransform with SymTransformer { thisTransformer => import tpd._ - def transformSym(sym: SymDenotation)(implicit ctx: Context): SymDenotation = { - if (sym.is(BindDefinedType) && ctx.gadt.bounds.contains(sym.symbol)) { - sym.copySymDenotation(info = ctx.gadt.bounds.apply(sym.symbol) & sym.info) - } else sym + def transformSym(ref: SymDenotation)(implicit ctx: Context): SymDenotation = { + if (ref.is(BindDefinedType) && ctx.gadt.bounds.contains(ref.symbol)) { + ref.copySymDenotation(info = ctx.gadt.bounds.apply(ref.symbol) & ref.info) + } else ref } /** the following two members override abstract members in Transform */