From f6812a170841a525c19d1b8c59a938cf88fde606 Mon Sep 17 00:00:00 2001 From: odersky Date: Wed, 6 Apr 2022 14:07:19 +0200 Subject: [PATCH] Fix isAbsType prediction in TreeUnpickler TreeUnpickler assumed that a type was an abstract type if its RHS was a TypeBounds tree. But TypeBounds trees also encode alias types, so this needs to be refined. Fixes #14858 --- .../src/dotty/tools/dotc/core/Types.scala | 2 +- .../tools/dotc/core/tasty/TreeUnpickler.scala | 24 ++++++++++++++----- tests/pos/i14858/A_2.scala | 3 +++ tests/pos/i14858/M_1.scala | 10 ++++++++ 4 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 tests/pos/i14858/A_2.scala create mode 100644 tests/pos/i14858/M_1.scala diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index c71ad928a7d2..9cd882cfab37 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -4206,7 +4206,7 @@ object Types { * This is the case if tycon is higher-kinded. This means * it is a subtype of a hk-lambda, but not a match alias. * (normal parameterized aliases are removed in `appliedTo`). - * Applications of hgher-kinded type constructors to wildcard arguments + * Applications of higher-kinded type constructors to wildcard arguments * are equivalent to existential types, which are not supported. */ def isUnreducibleWild(using Context): Boolean = diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index 06dc4872c7f3..ced7557bb7c9 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -500,16 +500,28 @@ class TreeUnpickler(reader: TastyReader, flags } - def isAbstractType(ttag: Int)(using Context): Boolean = nextUnsharedTag match { + def isAbstractType(name: Name)(using Context): Boolean = nextByte match + case SHAREDtype => + val lookAhead = fork + lookAhead.reader.readByte() + val sharedReader = forkAt(lookAhead.reader.readAddr()) + sharedReader.isAbstractType(name) case LAMBDAtpt => val rdr = fork rdr.reader.readByte() // tag rdr.reader.readNat() // length rdr.skipParams() // tparams - rdr.isAbstractType(rdr.nextUnsharedTag) - case TYPEBOUNDS | TYPEBOUNDStpt => true + rdr.isAbstractType(name) + case TYPEBOUNDS => + val rdr = fork + rdr.reader.readByte() // tag + val end = rdr.reader.readEnd() + rdr.skipTree() // alias, or lower bound + val res = !rdr.nothingButMods(end) + //if !res then println(i"NOT ABSTRACT $name, ${rdr.reader.nextByte}") + res + case TYPEBOUNDStpt => true case _ => false - } /** Create symbol of definition node and enter in symAtAddr map * @return the created symbol @@ -554,7 +566,7 @@ class TreeUnpickler(reader: TastyReader, if (tag == TYPEDEF || tag == TYPEPARAM) name = name.toTypeName skipParams() val ttag = nextUnsharedTag - val isAbsType = isAbstractType(ttag) + val isAbsType = isAbstractType(name) val isClass = ttag == TEMPLATE val templateStart = currentAddr skipTree() // tpt @@ -562,7 +574,7 @@ class TreeUnpickler(reader: TastyReader, val rhsIsEmpty = nothingButMods(end) if (!rhsIsEmpty) skipTree() val (givenFlags, annotFns, privateWithin) = readModifiers(end) - pickling.println(i"creating symbol $name at $start with flags $givenFlags") + pickling.println(i"creating symbol $name at $start with flags ${givenFlags.flagsString}, isAbsType = $isAbsType, $ttag") val flags = normalizeFlags(tag, givenFlags, name, isAbsType, rhsIsEmpty) def adjustIfModule(completer: LazyType) = if (flags.is(Module)) adjustModuleCompleter(completer, name) else completer diff --git a/tests/pos/i14858/A_2.scala b/tests/pos/i14858/A_2.scala new file mode 100644 index 000000000000..1335f4795508 --- /dev/null +++ b/tests/pos/i14858/A_2.scala @@ -0,0 +1,3 @@ +import p.* + +type NAME2 = C[?] \ No newline at end of file diff --git a/tests/pos/i14858/M_1.scala b/tests/pos/i14858/M_1.scala new file mode 100644 index 000000000000..6f431d0b523e --- /dev/null +++ b/tests/pos/i14858/M_1.scala @@ -0,0 +1,10 @@ +package p + +object M { + class C[N]() +} + +export M.* + +type CC[N] = M.C[N] +type CCC = M.C[Int]