@@ -5,6 +5,8 @@ import scala.annotation.{switch, tailrec}
55import scala .collection .mutable
66import scala .reflect .io .AbstractFile
77import Names .TastyName
8+ import scala .reflect .internal .Variance
9+ import scala .util .chaining ._
810
911/** Unpickler for typed trees
1012 * @param reader the reader from which to unpickle
@@ -29,18 +31,13 @@ class TreeUnpickler[Tasty <: TastyUniverse](
2931 import TastyFlags ._
3032 import Signature ._
3133 import Contexts ._
32- import TypeOps ._
3334
3435 @ inline
3536 final protected def assertTasty (cond : Boolean , msg : => String )(implicit ctx : Context ): Unit =
3637 if (! cond) {
3738 errorTasty(msg)
3839 }
3940
40- @ inline
41- final protected def errorTasty (msg : String )(implicit ctx : Context ): Unit =
42- reporter.error(noPosition, s " Scala 2 incompatible TASTy signature of ${ctx.source.name} in ${ctx.owner}: $msg" )
43-
4441 /** A map from addresses of definition entries to the symbols they define */
4542 private val symAtAddr = new mutable.HashMap [Addr , Symbol ]
4643
@@ -127,6 +124,12 @@ class TreeUnpickler[Tasty <: TastyUniverse](
127124 override def complete (sym : Symbol ): Unit = throw new UnsupportedOperationException (" complete" )
128125 }
129126
127+ final class ErrorCompleter (msg : Symbol => String ) extends TastyLazyType {
128+ override def complete (sym : Symbol ): Unit = {
129+ throw new symbolTable.TypeError (msg(sym))
130+ }
131+ }
132+
130133 class TreeReader (val reader : TastyReader ) {
131134 import reader ._
132135
@@ -294,38 +297,27 @@ class TreeUnpickler[Tasty <: TastyUniverse](
294297 val tag = readByte()
295298 ctx.log(s " reading type ${astTagToString(tag)} at $start" )
296299
297- def registeringType [T ](tp : Type , op : => T ): T = {
300+ def registeringTypeWith [T ](tp : Type , op : => T ): T = {
298301 typeAtAddr(start) = tp
299302 op
300303 }
301304
302305 def readLengthType (): Type = {
303306 val end = readEnd()
304307
305- def readMethodic [N <: Name , PInfo <: Type , LT <: LambdaType ]
306- (companion : LambdaTypeCompanion [N , PInfo , LT ], nameMap : TastyName => N )(implicit ctx : Context ): Type = {
307- val complete = typeAtAddr.contains(start)
308- val stored = typeAtAddr.getOrElse(start, {
308+ def readMethodic [N <: Name , PInfo <: Type , LT <: LambdaType , Res <: Type ]
309+ (companion : LambdaTypeCompanion [N , PInfo , LT , Res ], nameMap : TastyName => N )(implicit ctx : Context ): Res = {
310+ val result = typeAtAddr.getOrElse(start, {
309311 val nameReader = fork
310312 nameReader.skipTree() // skip result
311313 val paramReader = nameReader.fork
312- val paramNames = nameReader.readParamNames(end).map(nameMap)
313- companion(paramNames)(
314- pt => registeringType (pt, paramReader.readParamTypes[PInfo ](end)),
315- pt => readType())
314+ val paramNames = nameReader.readParamNames(end)
315+ companion(paramNames)(nameMap,
316+ pt => registeringTypeWith (pt, paramReader.readParamTypes[PInfo ](end)),
317+ pt => readType()).tap(typeAtAddr(start) = _)
316318 })
317319 goto(end)
318- val canonical = {
319- if (complete) {
320- stored
321- }
322- else {
323- val canonical = stored.asInstanceOf [LT ].canonicalForm
324- typeAtAddr.update(start, canonical)
325- canonical
326- }
327- }
328- canonical
320+ result.asInstanceOf [Res ]
329321 }
330322
331323 val result =
@@ -357,12 +349,11 @@ class TreeUnpickler[Tasty <: TastyUniverse](
357349 // // Note that the lambda "rt => ..." is not equivalent to a wildcard closure!
358350 // // Eta expansion of the latter puts readType() out of the expression.
359351 case APPLIEDtype =>
360- val tpe = readType()
361- mkTypeRef(tpe.typeSymbolDirect.owner.tpe, tpe.typeSymbolDirect, until(end)(readType()))
352+ boundedAppliedType(readType(), until(end)(readType()))
362353 case TYPEBOUNDS =>
363354 val lo = readType()
364355 val hi = readType()
365- mkTypeBounds (lo, hi) // if (lo.isMatch && (lo `eq` hi)) MatchAlias(lo) else TypeBounds(lo, hi)
356+ TypeBounds .bounded (lo, hi) // if (lo.isMatch && (lo `eq` hi)) MatchAlias(lo) else TypeBounds(lo, hi)
366357 case ANNOTATEDtype =>
367358 mkAnnotatedType(readType(), mkAnnotation(readTerm()))
368359 case ANDtype =>
@@ -388,9 +379,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
388379 case TYPELAMBDAtype =>
389380 readMethodic(HKTypeLambda , _.toEncodedTermName.toTypeName)
390381 case PARAMtype =>
391- readTypeRef() match {
392- case binder : LambdaType => binder.paramRefs(readNat())
393- }
382+ readTypeRef().typeParams(readNat()).ref
394383 }
395384 assert(currentAddr === end, s " $start $currentAddr $end ${astTagToString(tag)}" )
396385 result
@@ -399,32 +388,21 @@ class TreeUnpickler[Tasty <: TastyUniverse](
399388 def readSimpleType (): Type = {
400389 (tag : @ switch) match {
401390 case TYPEREFdirect | TERMREFdirect =>
402- mkTypeRef(noPrefix, readSymRef(), Nil )
391+ readSymRef().termRef
403392 case TYPEREFsymbol | TERMREFsymbol =>
404393 readSymNameRef()
405394 case TYPEREFpkg =>
406- readPackageRef().moduleClass.typeRef
395+ readPackageRef().moduleClass.ref
407396 case TERMREFpkg =>
408397 readPackageRef().termRef
409398 case TYPEREF =>
410399 val name = readTastyName()
411400 val pre = readType()
412- if (pre.typeSymbol === defn.ScalaPackage && ( name === nme.And || name === nme.Or ) ) {
413- if (name === nme.And ) {
414- AndType
415- }
416- else {
417- errorTasty(s " Union types are not currently supported, [found reference to scala. $name at Addr( $start) in ${ctx.classRoot}] " )
418- errorType
419- }
420- }
421- else {
422- mkTypeRef(pre, name, selectingTerm = false )
423- }
401+ selectType(pre, name)
424402 case TERMREF =>
425- val sname = readTastyName()
403+ val name = readTastyName()
426404 val prefix = readType()
427- mkTypeRef (prefix, sname, selectingTerm = true )
405+ selectTerm (prefix, name )
428406 case THIS =>
429407 val sym = readType() match {
430408 case tpe : TypeRef => tpe.sym
@@ -447,7 +425,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
447425 val ref = readAddr()
448426 typeAtAddr.getOrElseUpdate(ref, forkAt(ref).readType())
449427 case BYNAMEtype =>
450- mkAppliedType( defn.ByNameParamClass , readType()) // ExprType(readType())
428+ defn.ByNameParamClass .ref( readType() :: Nil ) // ExprType(readType())
451429 case ENUMconst =>
452430 errorTasty(" Enum Constant" ) // Constant(readTypeRef().termSymbol)
453431 errorType
@@ -462,14 +440,14 @@ class TreeUnpickler[Tasty <: TastyUniverse](
462440 private def readSymNameRef ()(implicit ctx : Context ): Type = {
463441 val sym = readSymRef()
464442 val prefix = readType()
465- val res = NamedType (prefix, sym)
466- prefix match {
467- case prefix : ThisType if (prefix.sym `eq` sym.owner) && sym.isTypeParameter /* && !sym.is(Opaque)*/ =>
468- mkTypeRef(noPrefix, sym, Nil )
469- // without this precaution we get an infinite cycle when unpickling pos/extmethods.scala
470- // the problem arises when a self type of a trait is a type parameter of the same trait.
471- case _ => res
472- }
443+ // TODO tasty: restore this if github:lampepfl/dotty/tests/pos/extmethods.scala causes infinite loop
444+ // prefix match {
445+ // case prefix: ThisType if (prefix.sym `eq` sym.owner) && sym.isTypeParameter /*&& !sym.is(Opaque)*/ =>
446+ // mkAppliedType( sym, Nil)
447+ // // without this precaution we get an infinite cycle when unpickling pos/extmethods.scala
448+ // // the problem arises when a self type of a trait is a type parameter of the same trait.
449+ // }
450+ NamedType (prefix, sym)
473451 }
474452
475453 private def readPackageRef ()(implicit ctx : Context ): TermSymbol = {
@@ -869,10 +847,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
869847 val unsupported = completer.tastyFlagSet &~ supported
870848 assertTasty(! unsupported, s " unsupported Scala 3 flags on $sym: ${show(unsupported)}" )
871849 if (completer.tastyFlagSet.is(Inline )) {
872- sym.addAnnotation(
873- symbolTable.symbolOf[annotation.compileTimeOnly],
874- Literal (Constant (s " Unsupported Scala 3 inline $sym" ))
875- )
850+ attachCompiletimeOnly(sym, s " Unsupported Scala 3 inline $sym" )
876851 }
877852 if (completer.tastyFlagSet.is(Extension )) ctx.log(s " $name is a Scala 3 extension method. " )
878853 val typeParams = {
@@ -886,24 +861,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
886861 }
887862 val vparamss = readParamss(localCtx)
888863 val tpt = readTpt()(localCtx)
889- val valueParamss = ctx.normalizeIfConstructor(
890- vparamss.map(_.map(symFromNoCycle)), name === nme.CONSTRUCTOR )
891- // if (tname === TastyName.SimpleName("apply")
892- // && sym.is(Synthetic)) {
893- // sym.flags = sym.flags | Case
894- // }
895- // val retType =
896- // if (tname === TastyName.SimpleName("unapply")
897- // && sym.is(Synthetic)) {
898- // sym.flags = sym.flags | Case
899- // sym.owner.companion.caseFieldAccessors.map(_.tpe) match {
900- // case Nil => defn.BooleanTpe
901- // case value :: Nil => defn.optionType(dropNullaryMethod(value))
902- // case values => defn.optionType(defn.tupleType(values.map(dropNullaryMethod)))
903- // }
904- // } else {
905- // tpt.tpe
906- // }
864+ val valueParamss = ctx.normalizeIfConstructor(vparamss.map(_.map(symFromNoCycle)), name === nme.CONSTRUCTOR )
907865 val resType = ctx.effectiveResultType(sym, typeParams, tpt.tpe)
908866 sym.info = ctx.methodType(if (name === nme.CONSTRUCTOR ) Nil else typeParams, valueParamss, resType)
909867 NoCycle (at = symAddr)
@@ -923,15 +881,22 @@ class TreeUnpickler[Tasty <: TastyUniverse](
923881 readTemplate(symAddr)(localCtx)
924882 }
925883 else {
926- sym.info = emptyTypeBounds // needed to avoid cyclic references when unpickling rhs, see i3816.scala
884+ sym.info = TypeBounds .empty // needed to avoid cyclic references when unpickling rhs, see i3816.scala
927885 // sym.setFlag(Provisional)
928886 val rhs = readTpt()(localCtx)
929887 sym.info = new NoCompleter {
930888 override def completerTypeParams (sym : Symbol )(implicit ctx : Context ) =
931889 rhs.tpe.typeParams
932890 }
933891 // TODO check for cycles
934- sym.info = rhs.tpe.stripLowerBoundsIfPoly
892+ sym.info = rhs.tpe match {
893+ case bounds @ TypeBounds (lo : PolyType , hi : PolyType ) if ! (mergeableParams(lo,hi)) =>
894+ new ErrorCompleter (owner =>
895+ s " $owner has diverging type lambdas as bounds: $bounds" )
896+ case tpe : TypeBounds => normaliseBounds(tpe)
897+ case tpe => tpe
898+ }
899+ if (sym.is(Param )) sym.flags &= ~ (Private | Protected )
935900 // sym.normalizeOpaque()
936901 // sym.resetFlag(Provisional)
937902 NoCycle (at = symAddr)
@@ -949,7 +914,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
949914 }
950915 case _ => sys.error(s " Reading new member with tag ${astTagToString(tag)}" )
951916 }
952- ctx.log(s " typed ${showSym(sym)} : ${sym.tpe} in owner ${showSym(sym.owner)}" )
917+ ctx.log(s " typed ${showSym(sym)} : ${if ( sym.isClass) sym. tpe else sym.info } in owner ${showSym(sym.owner)}" )
953918 goto(end)
954919 noCycle
955920 }
@@ -1277,7 +1242,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
12771242 val selector = if (isTerm) encoded else encoded.toTypeName
12781243 val localCtx = ctx // if (name === nme.CONSTRUCTOR) ctx.addMode(Mode.) else ctx
12791244 def tpeFun (localCtx : Context , selector : Name , qualType : Type ): Type =
1280- if (sig `eq` NotAMethod ) mkTypeRef (qualType, name, isTerm)
1245+ if (sig `eq` NotAMethod ) selectFromPrefix (qualType, name, isTerm)
12811246 else selectFromSig(qualType, selector, sig)(localCtx)
12821247 f(localCtx, selector, tpeFun)
12831248 }
@@ -1480,8 +1445,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
14801445 val tpe = mkIntersectionType(args.map(_.tpe))
14811446 CompoundTypeTree (args).setType(tpe)
14821447 } else {
1483- val ownType = mkTypeRef(tycon.tpe.prefix, tycon.tpe.typeSymbolDirect, args.map(_.tpe))
1484- AppliedTypeTree (tycon, args).setType(ownType)
1448+ AppliedTypeTree (tycon, args).setType(boundedAppliedType(tycon.tpe, args.map(_.tpe)))
14851449 }
14861450 case ANNOTATEDtpt =>
14871451 val tpt = readTpt()
@@ -1490,7 +1454,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
14901454 case LAMBDAtpt =>
14911455 val tparams = readParams[NoCycle ](TYPEPARAM )
14921456 val body = readTpt()
1493- TypeTree (TypeParamLambda (tparams.map(symFromNoCycle), body.tpe).canonicalForm ) // LambdaTypeTree(tparams, body)
1457+ TypeTree (mkLambdaFromParams (tparams.map(symFromNoCycle), body.tpe)) // LambdaTypeTree(tparams, body)
14941458// case MATCHtpt =>
14951459// val fst = readTpt()
14961460// val (bound, scrut) =
@@ -1499,7 +1463,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
14991463 case TYPEBOUNDStpt =>
15001464 val lo = readTpt()
15011465 val hi = if (currentAddr === end) lo else readTpt()
1502- TypeBoundsTree (lo, hi).setType(mkTypeBounds (lo.tpe, hi.tpe))
1466+ TypeBoundsTree (lo, hi).setType(TypeBounds .bounded (lo.tpe, hi.tpe))
15031467// case HOLE =>
15041468// readHole(end, isType = false)
15051469// case _ =>
0 commit comments