@@ -528,11 +528,12 @@ class TreeUnpickler[Tasty <: TastyUniverse](
528528 private def localContext (owner : Symbol )(implicit ctx : Context ): Context =
529529 ctx.fresh.setOwner(owner)
530530
531- private def normalizeFlags (tag : Int , owner : Symbol , givenFlags : FlagSet , name : Name , tname : TastyName , isAbsType : Boolean , rhsIsEmpty : Boolean )(implicit ctx : Context ): FlagSet = {
531+ private def normalizeFlags (tag : Int , owner : Symbol , givenFlags : FlagSet , tastyFlags : TastyFlagSet , name : Name , tname : TastyName , isAbsType : Boolean , isClass : Boolean , rhsIsEmpty : Boolean )(implicit ctx : Context ): FlagSet = {
532532 val lacksDefinition =
533533 rhsIsEmpty &&
534534 name.isTermName && ! name.isConstructorName && ! givenFlags.isOneOf(TermParamOrAccessor ) ||
535- isAbsType
535+ isAbsType ||
536+ tastyFlags.is(Opaque ) && ! isClass
536537 var flags = givenFlags
537538 if (lacksDefinition && tag != PARAM ) flags |= Deferred
538539 if (tag === DEFDEF ) flags |= Method
@@ -622,7 +623,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
622623 if (! rhsIsEmpty) skipTree()
623624 val (givenFlags, tastyFlagSet, annotFns, privateWithin) =
624625 readModifiers(end, readTypedAnnot, readTypedWithin, noSymbol)
625- val flags = normalizeFlags(tag, ctx.owner, givenFlags, name, tname, isAbsType, rhsIsEmpty)
626+ val flags = normalizeFlags(tag, ctx.owner, givenFlags, tastyFlagSet, name, tname, isAbsType, isClass , rhsIsEmpty)
626627 def showFlags = {
627628 if (! tastyFlagSet)
628629 show(flags)
@@ -765,6 +766,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
765766 case EXTENSION => addTastyFlag(Extension )
766767 case GIVEN => addFlag(Implicit ) // addTastyFlag(Given)
767768 case PARAMsetter => addFlag(ParamAccessor )
769+ case PARAMalias => addTastyFlag(SuperParamAlias )
768770 case EXPORTED => addTastyFlag(Exported )
769771 case OPEN => addTastyFlag(Open )
770772 case PRIVATEqualified =>
@@ -927,7 +929,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
927929 NoCycle (at = symAddr)
928930 case VALDEF => // valdef in TASTy is either a module value or a method forwarder to a local value.
929931 val isInline = completer.tastyFlagSet.is(Inline )
930- val unsupported = completer.tastyFlagSet &~ (Inline | Enum )
932+ val unsupported = completer.tastyFlagSet &~ (Inline | Enum | Extension )
931933 assertTasty(! unsupported, s " unsupported Scala 3 flags on $sym: ${show(unsupported)}" )
932934 val tpe = readTpt()(localCtx).tpe
933935 if (isInline) assertTasty(isConstantType(tpe), s " inline val ${sym.nameString} with non-constant type $tpe" )
@@ -938,21 +940,19 @@ class TreeUnpickler[Tasty <: TastyUniverse](
938940 }
939941 NoCycle (at = symAddr)
940942 case TYPEDEF | TYPEPARAM =>
941- val unsupported = completer.tastyFlagSet &~ Enum
943+ val unsupported = completer.tastyFlagSet &~ ( Enum | Open | Opaque )
942944 assertTasty(! unsupported, s " unsupported Scala 3 flags on $sym: ${show(unsupported)}" )
943945 if (sym.isClass) {
944946 sym.owner.ensureCompleted()
945947 readTemplate(symAddr)(localCtx)
946948 }
947949 else {
948- sym.info = TypeBounds .empty // needed to avoid cyclic references when unpickling rhs, see i3816.scala
949- // sym.setFlag(Provisional)
950+ sym.info = TypeBounds .empty // needed to avoid cyclic references when unpickling rhs, see https://github.com/lampepfl/dotty/blob/master/tests/pos/ i3816.scala
951+ // sym.setFlag(Provisional) // TODO [tasty]: is there an equivalent in scala 2?
950952 val rhs = readTpt()(localCtx)
951- sym.info = new NoCompleter {
952- override def completerTypeParams (sym : Symbol )(implicit ctx : Context ) =
953- rhs.tpe.typeParams
954- }
955- // TODO check for cycles
953+ sym.info = new NoCompleter {}
954+ // TODO [tasty]: if opaque type alias will be supported, unwrap `type bounds with alias` to bounds and then
955+ // refine self type of the owner to be aware of the alias.
956956 sym.info = rhs.tpe match {
957957 case bounds @ TypeBounds (lo : PolyType , hi : PolyType ) if ! (mergeableParams(lo,hi)) =>
958958 new ErrorCompleter (owner =>
@@ -961,12 +961,13 @@ class TreeUnpickler[Tasty <: TastyUniverse](
961961 case tpe => tpe
962962 }
963963 if (sym.is(Param )) sym.flags &= ~ (Private | Protected )
964- // sym.normalizeOpaque()
964+ // if sym.isOpaqueAlias then sym.typeRef.recomputeDenot() // make sure we see the new bounds from now on
965965 // sym.resetFlag(Provisional)
966966 NoCycle (at = symAddr)
967967 }
968968 case PARAM =>
969- assertTasty(! completer.tastyFlagSet, s " unsupported Scala 3 flags on parameter $sym: ${show(completer.tastyFlagSet)}" )
969+ val unsupported = completer.tastyFlagSet &~ SuperParamAlias
970+ assertTasty(! unsupported, s " unsupported Scala 3 flags on parameter $sym: ${show(unsupported)}" )
970971 val tpt = readTpt()(localCtx)
971972 if (nothingButMods(end) && sym.not(ParamAccessor )) {
972973 sym.info = tpt.tpe
@@ -1040,6 +1041,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
10401041 readIndexedMember() // ctor
10411042 cls.info = {
10421043 val classInfo = new ClassInfoType (parentTypes, cls.rawInfo.decls, cls.asType)
1044+ // TODO [tasty]: if support opaque types, refine the self type with any opaque members here
10431045 if (tparams.isEmpty) classInfo
10441046 else new PolyType (tparams.map(symFromNoCycle), classInfo)
10451047 }
@@ -1565,9 +1567,11 @@ class TreeUnpickler[Tasty <: TastyUniverse](
15651567// if (nextUnsharedTag === CASEDEF) (EmptyTree, fst) else (fst, readTpt())
15661568// MatchTypeTree(bound, scrut, readCases(end))
15671569 case TYPEBOUNDStpt =>
1568- val lo = readTpt()
1569- val hi = if (currentAddr === end) lo else readTpt()
1570- TypeBoundsTree (lo, hi).setType(TypeBounds .bounded(lo.tpe, hi.tpe))
1570+ val lo = readTpt()
1571+ val hi = if (currentAddr == end) lo else readTpt()
1572+ val alias = if (currentAddr == end) emptyTree else readTpt()
1573+ if (alias != emptyTree) alias // only for opaque type alias
1574+ else TypeBoundsTree (lo, hi).setType(TypeBounds .bounded(lo.tpe, hi.tpe))
15711575// case HOLE =>
15721576// readHole(end, isType = false)
15731577// case _ =>
0 commit comments