Skip to content

Commit fa92143

Browse files
oderskymichelou
authored andcommitted
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 scala#14858
1 parent a4ec6c9 commit fa92143

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
@@ -4209,7 +4209,7 @@ object Types {
42094209
* This is the case if tycon is higher-kinded. This means
42104210
* it is a subtype of a hk-lambda, but not a match alias.
42114211
* (normal parameterized aliases are removed in `appliedTo`).
4212-
* Applications of hgher-kinded type constructors to wildcard arguments
4212+
* Applications of higher-kinded type constructors to wildcard arguments
42134213
* are equivalent to existential types, which are not supported.
42144214
*/
42154215
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
@@ -515,16 +515,28 @@ class TreeUnpickler(reader: TastyReader,
515515
flags
516516
}
517517

518-
def isAbstractType(ttag: Int)(using Context): Boolean = nextUnsharedTag match {
518+
def isAbstractType(name: Name)(using Context): Boolean = nextByte match
519+
case SHAREDtype =>
520+
val lookAhead = fork
521+
lookAhead.reader.readByte()
522+
val sharedReader = forkAt(lookAhead.reader.readAddr())
523+
sharedReader.isAbstractType(name)
519524
case LAMBDAtpt =>
520525
val rdr = fork
521526
rdr.reader.readByte() // tag
522527
rdr.reader.readNat() // length
523528
rdr.skipParams() // tparams
524-
rdr.isAbstractType(rdr.nextUnsharedTag)
525-
case TYPEBOUNDS | TYPEBOUNDStpt => true
529+
rdr.isAbstractType(name)
530+
case TYPEBOUNDS =>
531+
val rdr = fork
532+
rdr.reader.readByte() // tag
533+
val end = rdr.reader.readEnd()
534+
rdr.skipTree() // alias, or lower bound
535+
val res = !rdr.nothingButMods(end)
536+
//if !res then println(i"NOT ABSTRACT $name, ${rdr.reader.nextByte}")
537+
res
538+
case TYPEBOUNDStpt => true
526539
case _ => false
527-
}
528540

529541
/** Create symbol of definition node and enter in symAtAddr map
530542
* @return the created symbol
@@ -569,15 +581,15 @@ class TreeUnpickler(reader: TastyReader,
569581
if (tag == TYPEDEF || tag == TYPEPARAM) name = name.toTypeName
570582
skipParams()
571583
val ttag = nextUnsharedTag
572-
val isAbsType = isAbstractType(ttag)
584+
val isAbsType = isAbstractType(name)
573585
val isClass = ttag == TEMPLATE
574586
val templateStart = currentAddr
575587
skipTree() // tpt
576588
val rhsStart = currentAddr
577589
val rhsIsEmpty = nothingButMods(end)
578590
if (!rhsIsEmpty) skipTree()
579591
val (givenFlags, annotFns, privateWithin) = readModifiers(end)
580-
pickling.println(i"creating symbol $name at $start with flags $givenFlags")
592+
pickling.println(i"creating symbol $name at $start with flags ${givenFlags.flagsString}, isAbsType = $isAbsType, $ttag")
581593
val flags = normalizeFlags(tag, givenFlags, name, isAbsType, rhsIsEmpty)
582594
def adjustIfModule(completer: LazyType) =
583595
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)