Skip to content

Commit f6812a1

Browse files
committed
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
1 parent 8c404b1 commit f6812a1

File tree

4 files changed

+32
-7
lines changed

4 files changed

+32
-7
lines changed

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4206,7 +4206,7 @@ object Types {
42064206
* This is the case if tycon is higher-kinded. This means
42074207
* it is a subtype of a hk-lambda, but not a match alias.
42084208
* (normal parameterized aliases are removed in `appliedTo`).
4209-
* Applications of hgher-kinded type constructors to wildcard arguments
4209+
* Applications of higher-kinded type constructors to wildcard arguments
42104210
* are equivalent to existential types, which are not supported.
42114211
*/
42124212
def isUnreducibleWild(using Context): Boolean =

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -500,16 +500,28 @@ class TreeUnpickler(reader: TastyReader,
500500
flags
501501
}
502502

503-
def isAbstractType(ttag: Int)(using Context): Boolean = nextUnsharedTag match {
503+
def isAbstractType(name: Name)(using Context): Boolean = nextByte match
504+
case SHAREDtype =>
505+
val lookAhead = fork
506+
lookAhead.reader.readByte()
507+
val sharedReader = forkAt(lookAhead.reader.readAddr())
508+
sharedReader.isAbstractType(name)
504509
case LAMBDAtpt =>
505510
val rdr = fork
506511
rdr.reader.readByte() // tag
507512
rdr.reader.readNat() // length
508513
rdr.skipParams() // tparams
509-
rdr.isAbstractType(rdr.nextUnsharedTag)
510-
case TYPEBOUNDS | TYPEBOUNDStpt => true
514+
rdr.isAbstractType(name)
515+
case TYPEBOUNDS =>
516+
val rdr = fork
517+
rdr.reader.readByte() // tag
518+
val end = rdr.reader.readEnd()
519+
rdr.skipTree() // alias, or lower bound
520+
val res = !rdr.nothingButMods(end)
521+
//if !res then println(i"NOT ABSTRACT $name, ${rdr.reader.nextByte}")
522+
res
523+
case TYPEBOUNDStpt => true
511524
case _ => false
512-
}
513525

514526
/** Create symbol of definition node and enter in symAtAddr map
515527
* @return the created symbol
@@ -554,15 +566,15 @@ class TreeUnpickler(reader: TastyReader,
554566
if (tag == TYPEDEF || tag == TYPEPARAM) name = name.toTypeName
555567
skipParams()
556568
val ttag = nextUnsharedTag
557-
val isAbsType = isAbstractType(ttag)
569+
val isAbsType = isAbstractType(name)
558570
val isClass = ttag == TEMPLATE
559571
val templateStart = currentAddr
560572
skipTree() // tpt
561573
val rhsStart = currentAddr
562574
val rhsIsEmpty = nothingButMods(end)
563575
if (!rhsIsEmpty) skipTree()
564576
val (givenFlags, annotFns, privateWithin) = readModifiers(end)
565-
pickling.println(i"creating symbol $name at $start with flags $givenFlags")
577+
pickling.println(i"creating symbol $name at $start with flags ${givenFlags.flagsString}, isAbsType = $isAbsType, $ttag")
566578
val flags = normalizeFlags(tag, givenFlags, name, isAbsType, rhsIsEmpty)
567579
def adjustIfModule(completer: LazyType) =
568580
if (flags.is(Module)) adjustModuleCompleter(completer, name) else completer

tests/pos/i14858/A_2.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import p.*
2+
3+
type NAME2 = C[?]

tests/pos/i14858/M_1.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package p
2+
3+
object M {
4+
class C[N]()
5+
}
6+
7+
export M.*
8+
9+
type CC[N] = M.C[N]
10+
type CCC = M.C[Int]

0 commit comments

Comments
 (0)