diff options
Diffstat (limited to 'src/dotty/tools/dotc/core')
-rw-r--r-- | src/dotty/tools/dotc/core/StdNames.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeApplications.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeComparer.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 10 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/classfile/ClassfileParser.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/tasty/PositionPickler.scala | 26 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/tasty/TastyFormat.scala | 153 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/tasty/TastyPickler.scala | 11 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/tasty/TreeBuffer.scala | 27 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/tasty/TreePickler.scala | 398 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala | 132 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala | 24 |
12 files changed, 449 insertions, 347 deletions
diff --git a/src/dotty/tools/dotc/core/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala index 920c9635e..c2a14b36f 100644 --- a/src/dotty/tools/dotc/core/StdNames.scala +++ b/src/dotty/tools/dotc/core/StdNames.scala @@ -735,15 +735,11 @@ object StdNames { class ScalaTypeNames extends ScalaNames[TypeName] { protected implicit def fromString(s: String): TypeName = typeName(s) - def syntheticTypeParamName(i: Int): TypeName = "T" + i - def syntheticLambdaParamName(i: Int): TypeName = "X" + i + def syntheticTypeParamName(i: Int): TypeName = "X" + i def syntheticTypeParamNames(num: Int): List[TypeName] = (0 until num).map(syntheticTypeParamName)(breakOut) - def syntheticLambdaParamNames(num: Int): List[TypeName] = - (0 until num).map(syntheticLambdaParamName)(breakOut) - final val Conforms = encode("<:<") final val Uninstantiated: TypeName = "?$" diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala index 8aaf77032..70819e590 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -340,10 +340,11 @@ class TypeApplications(val self: Type) extends AnyVal { def LambdaAbstract(tparams: List[TypeParamInfo])(implicit ctx: Context): Type = { def expand(tp: Type) = PolyType( - tpnme.syntheticLambdaParamNames(tparams.length), tparams.map(_.paramVariance))( + tparams.map(_.paramName), tparams.map(_.paramVariance))( tl => tparams.map(tparam => tl.lifted(tparams, tparam.paramBounds).bounds), tl => tl.lifted(tparams, tp)) - self match { + if (tparams.isEmpty) self + else self match { case self: TypeAlias => self.derivedTypeAlias(expand(self.alias)) case self @ TypeBounds(lo, hi) => diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index 0e1d373a8..f78820fff 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -1267,7 +1267,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { original(tp1.appliedTo(tp1.typeParams.map(_.paramBoundsAsSeenFrom(tp1))), tp2) else PolyType( - paramNames = tpnme.syntheticLambdaParamNames(tparams1.length), + paramNames = tpnme.syntheticTypeParamNames(tparams1.length), variances = (tparams1, tparams2).zipped.map((tparam1, tparam2) => (tparam1.paramVariance + tparam2.paramVariance) / 2))( paramBoundsExp = tl => (tparams1, tparams2).zipped.map((tparam1, tparam2) => diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index ae248295c..89bc21929 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -2526,7 +2526,7 @@ object Types { case _: MethodType => true case _ => false } - + /** Is this polytype a higher-kinded type lambda as opposed to a polymorphic? * method type? Only type lambdas get created with variances, that's how we can tell. */ @@ -2621,17 +2621,11 @@ object Types { unique(new PolyType(paramNames, vs)(paramBoundsExp, resultTypeExp)) } - def fromSymbols(tparams: List[Symbol], resultType: Type)(implicit ctx: Context): Type = - if (tparams.isEmpty) resultType - else apply(tparams map (_.name.asTypeName), tparams.map(_.variance))( - pt => tparams.map(tparam => pt.lifted(tparams, tparam.info).bounds), - pt => pt.lifted(tparams, resultType)) - def unapply(tl: PolyType): Some[(List[LambdaParam], Type)] = Some((tl.typeParams, tl.resType)) def any(n: Int)(implicit ctx: Context) = - apply(tpnme.syntheticLambdaParamNames(n), List.fill(n)(0))( + apply(tpnme.syntheticTypeParamNames(n), List.fill(n)(0))( pt => List.fill(n)(TypeBounds.empty), pt => defn.AnyType) } diff --git a/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala b/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala index 1570dbca0..97a82e80d 100644 --- a/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala +++ b/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala @@ -217,7 +217,7 @@ class ClassfileParser( if (isEnum) denot.info = ConstantType(Constant(sym)) if (isConstructor) stripOuterParamFromConstructor() setPrivateWithin(denot, jflags) - denot.info = depoly(parseAttributes(sym, denot.info), denot) + denot.info = translateTempPoly(parseAttributes(sym, denot.info)) if (isConstructor) normalizeConstructorInfo() if ((denot is Flags.Method) && (jflags & JAVA_ACC_VARARGS) != 0) diff --git a/src/dotty/tools/dotc/core/tasty/PositionPickler.scala b/src/dotty/tools/dotc/core/tasty/PositionPickler.scala index 4b67bc188..546894a9e 100644 --- a/src/dotty/tools/dotc/core/tasty/PositionPickler.scala +++ b/src/dotty/tools/dotc/core/tasty/PositionPickler.scala @@ -13,7 +13,7 @@ import collection.mutable import TastyBuffer._ import util.Positions._ -class PositionPickler(pickler: TastyPickler, addrsOfTree: tpd.Tree => List[Addr]) { +class PositionPickler(pickler: TastyPickler, addrOfTree: tpd.Tree => Option[Addr]) { val buf = new TastyBuffer(5000) pickler.newSection("Positions", buf) import buf._ @@ -21,21 +21,6 @@ class PositionPickler(pickler: TastyPickler, addrsOfTree: tpd.Tree => List[Addr] private val remainingAddrs = new java.util.IdentityHashMap[Tree, Iterator[Addr]] - def nextTreeAddr(tree: Tree): Option[Addr] = remainingAddrs.get(tree) match { - case null => - addrsOfTree(tree) match { - case Nil => - None - case addr :: Nil => - Some(addr) - case addrs => - remainingAddrs.put(tree, addrs.iterator) - nextTreeAddr(tree) - } - case it: Iterator[_] => - if (it.hasNext) Some(it.next) else None - } - def header(addrDelta: Int, hasStartDelta: Boolean, hasEndDelta: Boolean, hasPoint: Boolean) = { def toInt(b: Boolean) = if (b) 1 else 0 (addrDelta << 3) | (toInt(hasStartDelta) << 2) | (toInt(hasEndDelta) << 1) | toInt(hasPoint) @@ -60,8 +45,7 @@ class PositionPickler(pickler: TastyPickler, addrsOfTree: tpd.Tree => List[Addr] */ def alwaysNeedsPos(x: Positioned) = x match { case _: WithLazyField[_] // initialPos is inaccurate for trees with lazy field - | _: Trees.PackageDef[_] => true // package defs might be split into several Tasty files - case x: Trees.Tree[_] => x.isType // types are unpickled as TypeTrees, so child positions are not available + | _: Trees.PackageDef[_] => true // package defs might be split into several Tasty files case _ => false } @@ -69,7 +53,7 @@ class PositionPickler(pickler: TastyPickler, addrsOfTree: tpd.Tree => List[Addr] case x: Tree @unchecked => val pos = if (x.isInstanceOf[MemberDef]) x.pos else x.pos.toSynthetic if (pos.exists && (pos != x.initialPos.toSynthetic || alwaysNeedsPos(x))) { - nextTreeAddr(x) match { + addrOfTree(x) match { case Some(addr) => //println(i"pickling $x with $pos at $addr") pickleDeltas(addr.index, pos) @@ -79,13 +63,15 @@ class PositionPickler(pickler: TastyPickler, addrsOfTree: tpd.Tree => List[Addr] } //else if (x.pos.exists) println(i"skipping $x") x match { - case x: MemberDef @unchecked => + case x: MemberDef @unchecked => for (ann <- x.symbol.annotations) traverse(ann.tree) case _ => } traverse(x.productIterator) case xs: TraversableOnce[_] => xs.foreach(traverse) + case x: Annotation => + traverse(x.tree) case _ => } traverse(roots) diff --git a/src/dotty/tools/dotc/core/tasty/TastyFormat.scala b/src/dotty/tools/dotc/core/tasty/TastyFormat.scala index f9743d9d2..cb1b56c3c 100644 --- a/src/dotty/tools/dotc/core/tasty/TastyFormat.scala +++ b/src/dotty/tools/dotc/core/tasty/TastyFormat.scala @@ -71,10 +71,11 @@ Standard-Section: "ASTs" TopLevelStat* Term = Path Application - IDENT NameRef Type // used when ident’s type is not a TermRef + IDENT NameRef Type // used when term ident’s type is not a TermRef SELECT possiblySigned_NameRef qual_Term + QUALTHIS typeIdent_Tree NEW cls_Type - SUPER Length this_Term mixinTrait_Type? + SUPER Length this_Term mixinTypeIdent_Tree? TYPED Length expr_Term ascription_Type NAMEDARG Length paramName_NameRef arg_Term ASSIGN Length lhs_Term rhs_Term @@ -89,6 +90,17 @@ Standard-Section: "ASTs" TopLevelStat* BIND Length boundName_NameRef patType_Type pat_Term ALTERNATIVE Length alt_Term* UNAPPLY Length fun_Term ImplicitArg* pat_Type pat_Term* + IDENTtpt NameRef Type // used for all type idents + SELECTtpt NameRef qual_Term + SINGLETONtpt Path + REFINEDtpt Length underlying_Term refinement_Stat* + APPLIEDtpt Length tycon_Term arg_Term* + POLYtpt Length TypeParam* body_Term + TYPEBOUNDStpt Length low_Term high_Term + ANNOTATEDtpt Length underlying_Term fullAnnotation_Term + ANDtpt Length left_Term right_Term + ORtpt Length left_Term right_Term + BYNAMEtpt underlying_Term EMPTYTREE SHARED term_ASTRef Application = APPLY Length fn_Term arg_Term* @@ -133,7 +145,7 @@ Standard-Section: "ASTs" TopLevelStat* APPLIEDtype Length tycon_Type arg_Type* TYPEBOUNDS Length low_Type high_Type TYPEALIAS Length alias_Type (COVARIANT | CONTRAVARIANT)? - ANNOTATED Length underlying_Type fullAnnotation_Term + ANNOTATEDtype Length underlying_Type fullAnnotation_Term ANDtype Length left_Type right_Type ORtype Length left_Type right_Type BIND Length boundName_NameRef bounds_Type @@ -268,22 +280,27 @@ object TastyFormat { final val RENAMED = 79 final val THIS = 96 - final val CLASSconst = 97 - final val ENUMconst = 98 - final val BYNAMEtype = 99 - final val NEW = 100 - final val IMPLICITarg = 101 - final val PRIVATEqualified = 102 - final val PROTECTEDqualified = 103 - final val RECtype = 104 + final val QUALTHIS = 97 + final val CLASSconst = 98 + final val ENUMconst = 99 + final val BYNAMEtype = 100 + final val BYNAMEtpt = 101 + final val NEW = 102 + final val IMPLICITarg = 103 + final val PRIVATEqualified = 104 + final val PROTECTEDqualified = 105 + final val RECtype = 106 + final val SINGLETONtpt = 107 final val IDENT = 112 - final val SELECT = 113 - final val TERMREFsymbol = 114 - final val TERMREF = 115 - final val TYPEREFsymbol = 116 - final val TYPEREF = 117 - final val SELFDEF = 118 + final val IDENTtpt = 113 + final val SELECT = 114 + final val SELECTtpt = 115 + final val TERMREFsymbol = 116 + final val TERMREF = 117 + final val TYPEREFsymbol = 118 + final val TYPEREF = 119 + final val SELFDEF = 120 final val PACKAGE = 128 final val VALDEF = 129 @@ -293,39 +310,44 @@ object TastyFormat { final val TYPEPARAM = 133 final val PARAMS = 134 final val PARAM = 136 - - final val APPLY = 139 - final val TYPEAPPLY = 140 - - final val TYPED = 143 - final val NAMEDARG = 144 - final val ASSIGN = 145 - final val BLOCK = 146 - final val IF = 147 - final val LAMBDA = 148 - final val MATCH = 149 - final val RETURN = 150 - final val TRY = 151 - final val INLINED = 152 - final val REPEATED = 153 - final val BIND = 154 - final val ALTERNATIVE = 155 - final val UNAPPLY = 156 - final val ANNOTATED = 157 - final val CASEDEF = 158 - final val TEMPLATE = 160 - final val SUPER = 163 - final val SUPERtype = 166 - final val REFINEDtype = 167 - final val APPLIEDtype = 168 - final val TYPEBOUNDS = 169 - final val TYPEALIAS = 170 - final val ANDtype = 171 - final val ORtype = 172 - final val METHODtype = 174 - final val POLYtype = 175 - final val PARAMtype = 176 - final val ANNOTATION = 177 + final val APPLY = 137 + final val TYPEAPPLY = 138 + final val TYPED = 139 + final val NAMEDARG = 140 + final val ASSIGN = 141 + final val BLOCK = 142 + final val IF = 143 + final val LAMBDA = 144 + final val MATCH = 145 + final val RETURN = 146 + final val TRY = 147 + final val INLINED = 148 + final val REPEATED = 149 + final val BIND = 150 + final val ALTERNATIVE = 151 + final val UNAPPLY = 152 + final val ANNOTATEDtype = 153 + final val ANNOTATEDtpt = 154 + final val CASEDEF = 155 + final val TEMPLATE = 156 + final val SUPER = 157 + final val SUPERtype = 158 + final val REFINEDtype = 159 + final val REFINEDtpt = 160 + final val APPLIEDtype = 161 + final val APPLIEDtpt = 162 + final val TYPEBOUNDS = 163 + final val TYPEBOUNDStpt = 164 + final val TYPEALIAS = 165 + final val ANDtype = 166 + final val ANDtpt = 167 + final val ORtype = 168 + final val ORtpt = 169 + final val METHODtype = 170 + final val POLYtype = 171 + final val POLYtpt = 172 + final val PARAMtype = 173 + final val ANNOTATION = 174 final val firstSimpleTreeTag = UNITconst final val firstNatTreeTag = SHARED @@ -367,7 +389,22 @@ object TastyFormat { | PRIVATEqualified | PROTECTEDqualified => true case _ => false - } + } + + def isTypeTreeTag(tag: Int) = tag match { + case IDENTtpt + | SELECTtpt + | SINGLETONtpt + | REFINEDtpt + | APPLIEDtpt + | POLYtpt + | TYPEBOUNDStpt + | ANNOTATEDtpt + | ANDtpt + | ORtpt + | BYNAMEtpt => true + case _ => false + } def nameTagToString(tag: Int): String = tag match { case UTF8 => "UTF8" @@ -429,7 +466,9 @@ object TastyFormat { case RECtype => "RECtype" case IDENT => "IDENT" + case IDENTtpt => "IDENTtpt" case SELECT => "SELECT" + case SELECTtpt => "SELECTtpt" case TERMREFsymbol => "TERMREFsymbol" case TERMREF => "TERMREF" case TYPEREFsymbol => "TYPEREFsymbol" @@ -462,24 +501,34 @@ object TastyFormat { case BIND => "BIND" case ALTERNATIVE => "ALTERNATIVE" case UNAPPLY => "UNAPPLY" - case ANNOTATED => "ANNOTATED" + case ANNOTATEDtype => "ANNOTATEDtype" + case ANNOTATEDtpt => "ANNOTATEDtpt" case CASEDEF => "CASEDEF" case IMPLICITarg => "IMPLICITarg" case TEMPLATE => "TEMPLATE" case SELFDEF => "SELFDEF" case THIS => "THIS" + case QUALTHIS => "QUALTHIS" case SUPER => "SUPER" case CLASSconst => "CLASSconst" case ENUMconst => "ENUMconst" + case SINGLETONtpt => "SINGLETONtpt" case SUPERtype => "SUPERtype" case REFINEDtype => "REFINEDtype" + case REFINEDtpt => "REFINEDtpt" case APPLIEDtype => "APPLIEDtype" + case APPLIEDtpt => "APPLIEDtpt" case TYPEBOUNDS => "TYPEBOUNDS" + case TYPEBOUNDStpt => "TYPEBOUNDStpt" case TYPEALIAS => "TYPEALIAS" case ANDtype => "ANDtype" + case ANDtpt => "ANDtpt" case ORtype => "ORtype" + case ORtpt => "ORtpt" case BYNAMEtype => "BYNAMEtype" + case BYNAMEtpt => "BYNAMEtpt" case POLYtype => "POLYtype" + case POLYtpt => "POLYtpt" case METHODtype => "METHODtype" case PARAMtype => "PARAMtype" case ANNOTATION => "ANNOTATION" diff --git a/src/dotty/tools/dotc/core/tasty/TastyPickler.scala b/src/dotty/tools/dotc/core/tasty/TastyPickler.scala index f847dda68..c844d522e 100644 --- a/src/dotty/tools/dotc/core/tasty/TastyPickler.scala +++ b/src/dotty/tools/dotc/core/tasty/TastyPickler.scala @@ -54,14 +54,11 @@ class TastyPickler { all.bytes } - /** - * Addresses in TASTY file of trees, stored by pickling. - * Note that trees are checked for reference equality, - * so one can reliably use this function only directly after `pickler`. - * Note that a tree can have several addresses, if it is shared, - * i.e. accessible from different paths. Any such sharing is undone by pickling. + /** The address in the TASTY file of a given tree, or None if unknown. + * Note that trees are looked up by reference equality, + * so one can reliably use this function only directly after `pickler`. */ - var addrsOfTree: tpd.Tree => List[Addr] = (_ => Nil) + var addrOfTree: tpd.Tree => Option[Addr] = (_ => None) /** * Addresses in TASTY file of symbols, stored by pickling. diff --git a/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala b/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala index f2681ecde..6c7982d78 100644 --- a/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala +++ b/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala @@ -17,26 +17,17 @@ class TreeBuffer extends TastyBuffer(50000) { private var delta: Array[Int] = _ private var numOffsets = 0 - private type TreeAddrs = Any // really: Addr | List[Addr] + /** A map from trees to the address at which a tree is pickled. */ + private val treeAddrs = new java.util.IdentityHashMap[Tree, Any] // really: Addr | Null - /** A map from trees to the address(es) at which a tree is pickled. There may be several - * such addresses if the tree is shared. To keep the map compact, the value type is a - * disjunction of a single address (which is the common case) and a list of addresses. - */ - private val treeAddrs = new java.util.IdentityHashMap[Tree, TreeAddrs] + def registerTreeAddr(tree: Tree): Addr = treeAddrs.get(tree) match { + case null => treeAddrs.put(tree, currentAddr); currentAddr + case addr: Addr => addr + } - def registerTreeAddr(tree: Tree) = - treeAddrs.put(tree, - treeAddrs.get(tree) match { - case null => currentAddr - case x: Addr => x :: currentAddr :: Nil - case xs: List[_] => xs :+ currentAddr - }) - - def addrsOfTree(tree: Tree): List[Addr] = treeAddrs.get(tree) match { - case null => Nil - case addr: Addr => addr :: Nil - case addrs: List[Addr] => addrs + def addrOfTree(tree: Tree): Option[Addr] = treeAddrs.get(tree) match { + case null => None + case addr: Addr => Some(addr) } private def offset(i: Int): Addr = Addr(offsets(i)) diff --git a/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/src/dotty/tools/dotc/core/tasty/TreePickler.scala index 9dfb78798..80270aa25 100644 --- a/src/dotty/tools/dotc/core/tasty/TreePickler.scala +++ b/src/dotty/tools/dotc/core/tasty/TreePickler.scala @@ -10,6 +10,7 @@ import Contexts._, Symbols._, Types._, Names._, Constants._, Decorators._, Annot import collection.mutable import typer.Inliner import NameOps._ +import StdNames.nme import TastyBuffer._ import TypeApplications._ @@ -49,10 +50,6 @@ class TreePickler(pickler: TastyPickler) { case None => } } - - def rhs(tdef: TypeDef)(implicit ctx: Context) = - if (tdef.symbol.isClass) tdef.rhs - else TypeTree(tdef.symbol.info).withPos(tdef.rhs.pos) private def pickleName(name: Name): Unit = writeNat(nameIndex(name).index) private def pickleName(name: TastyName): Unit = writeNat(nameIndex(name).index) @@ -157,11 +154,6 @@ class TreePickler(pickler: TastyPickler) { throw ex } - def pickleTypeWithPos(tpe: Type, tree: Tree)(implicit ctx: Context): Unit = { - registerTreeAddr(tree) - pickleType(tpe) - } - private def pickleNewType(tpe: Type, richTypes: Boolean)(implicit ctx: Context): Unit = try { tpe match { case AppliedType(tycon, args) => writeByte(APPLIEDtype) @@ -253,7 +245,7 @@ class TreePickler(pickler: TastyPickler) { writeByte(TYPEBOUNDS) withLength { pickleType(tpe.lo, richTypes); pickleType(tpe.hi, richTypes) } case tpe: AnnotatedType => - writeByte(ANNOTATED) + writeByte(ANNOTATEDtype) withLength { pickleType(tpe.tpe, richTypes); pickleTree(tpe.annot.tree) } case tpe: AndOrType => writeByte(if (tpe.isAnd) ANDtype else ORtype) @@ -310,7 +302,7 @@ class TreePickler(pickler: TastyPickler) { } def pickleTpt(tpt: Tree)(implicit ctx: Context): Unit = - pickleTypeWithPos(tpt.tpe, tpt) // TODO correlate with original when generating positions + pickleTree(tpt) def pickleTreeUnlessEmpty(tree: Tree)(implicit ctx: Context): Unit = if (!tree.isEmpty) pickleTree(tree) @@ -336,7 +328,7 @@ class TreePickler(pickler: TastyPickler) { tree match { case tree: ValDef => pickleDef(PARAM, tree.symbol, tree.tpt) case tree: DefDef => pickleDef(PARAM, tree.symbol, tree.tpt, tree.rhs) - case tree: TypeDef => pickleDef(TYPEPARAM, tree.symbol, rhs(tree)) + case tree: TypeDef => pickleDef(TYPEPARAM, tree.symbol, tree.rhs) } } @@ -350,181 +342,231 @@ class TreePickler(pickler: TastyPickler) { stats.foreach(stat => if (!stat.isEmpty) pickleTree(stat)) } - def pickleTree(tree: Tree)(implicit ctx: Context): Unit = try { - registerTreeAddr(tree) - tree match { - case tree if tree.isType => - pickleTpt(tree) - case Ident(name) => - tree.tpe match { - case tp: TermRef => pickleType(tp) - case _ => - writeByte(IDENT) - pickleName(name) - pickleType(tree.tpe) - } - case This(_) => - pickleType(tree.tpe) - case Select(qual, name) => - writeByte(SELECT) - val realName = tree.tpe match { - case tp: NamedType if tp.name.isShadowedName => tp.name - case _ => name - } - val sig = tree.tpe.signature - if (sig == Signature.NotAMethod) pickleName(realName) - else pickleNameAndSig(realName, sig) - pickleTree(qual) - case Apply(fun, args) => - writeByte(APPLY) - withLength { - pickleTree(fun) - args.foreach(pickleTree) - } - case TypeApply(fun, args) => - writeByte(TYPEAPPLY) - withLength { - pickleTree(fun) - args.foreach(pickleTpt) - } - case Literal(const1) => - pickleConstant { + def pickleTree(tree: Tree)(implicit ctx: Context): Unit = { + val addr = registerTreeAddr(tree) + if (addr != currentAddr) { + writeByte(SHARED) + writeRef(addr) + } + else + try tree match { + case Ident(name) => tree.tpe match { - case ConstantType(const2) => const2 - case _ => const1 + case tp: TermRef if name != nme.WILDCARD => + // wildcards are pattern bound, need to be preserved as ids. + pickleType(tp) + case _ => + writeByte(if (tree.isType) IDENTtpt else IDENT) + pickleName(name) + pickleType(tree.tpe) } - } - case Super(qual, mix) => - writeByte(SUPER) - withLength { - pickleTree(qual); - if (!mix.isEmpty) { - val SuperType(_, mixinType) = tree.tpe - pickleType(mixinType) + case This(qual) => + if (qual.isEmpty) pickleType(tree.tpe) + else { + writeByte(QUALTHIS) + val ThisType(tref) = tree.tpe + pickleTree(qual.withType(tref)) } - } - case New(tpt) => - writeByte(NEW) - pickleTpt(tpt) - case Typed(expr, tpt) => - writeByte(TYPED) - withLength { pickleTree(expr); pickleTpt(tpt) } - case NamedArg(name, arg) => - writeByte(NAMEDARG) - withLength { pickleName(name); pickleTree(arg) } - case Assign(lhs, rhs) => - writeByte(ASSIGN) - withLength { pickleTree(lhs); pickleTree(rhs) } - case Block(stats, expr) => - writeByte(BLOCK) - stats.foreach(preRegister) - withLength { pickleTree(expr); stats.foreach(pickleTree) } - case If(cond, thenp, elsep) => - writeByte(IF) - withLength{ pickleTree(cond); pickleTree(thenp); pickleTree(elsep) } - case Closure(env, meth, tpt) => - writeByte(LAMBDA) - assert(env.isEmpty) - withLength{ - pickleTree(meth) - if (tpt.tpe.exists) pickleTpt(tpt) - } - case Match(selector, cases) => - writeByte(MATCH) - withLength { pickleTree(selector); cases.foreach(pickleTree) } - case CaseDef(pat, guard, rhs) => - writeByte(CASEDEF) - withLength { pickleTree(pat); pickleTree(rhs); pickleTreeUnlessEmpty(guard) } - case Return(expr, from) => - writeByte(RETURN) - withLength { pickleSymRef(from.symbol); pickleTreeUnlessEmpty(expr) } - case Try(block, cases, finalizer) => - writeByte(TRY) - withLength { pickleTree(block); cases.foreach(pickleTree); pickleTreeUnlessEmpty(finalizer) } - case SeqLiteral(elems, elemtpt) => - writeByte(REPEATED) - withLength { pickleTree(elemtpt); elems.foreach(pickleTree) } - case Inlined(call, bindings, expansion) => - writeByte(INLINED) - bindings.foreach(preRegister) - withLength { pickleTree(call); pickleTree(expansion); bindings.foreach(pickleTree) } - case Bind(name, body) => - registerDef(tree.symbol) - writeByte(BIND) - withLength { pickleName(name); pickleType(tree.symbol.info); pickleTree(body) } - case Alternative(alts) => - writeByte(ALTERNATIVE) - withLength { alts.foreach(pickleTree) } - case UnApply(fun, implicits, patterns) => - writeByte(UNAPPLY) - withLength { - pickleTree(fun) - for (implicitArg <- implicits) { - writeByte(IMPLICITarg) - pickleTree(implicitArg) + case Select(qual, name) => + writeByte(if (name.isTypeName) SELECTtpt else SELECT) + val realName = tree.tpe match { + case tp: NamedType if tp.name.isShadowedName => tp.name + case _ => name } - pickleType(tree.tpe) - patterns.foreach(pickleTree) - } - case tree: ValDef => - pickleDef(VALDEF, tree.symbol, tree.tpt, tree.rhs) - case tree: DefDef => - def pickleAllParams = { - pickleParams(tree.tparams) - for (vparams <- tree.vparamss) { - writeByte(PARAMS) - withLength { pickleParams(vparams) } + val sig = tree.tpe.signature + if (sig == Signature.NotAMethod) pickleName(realName) + else pickleNameAndSig(realName, sig) + pickleTree(qual) + case Apply(fun, args) => + writeByte(APPLY) + withLength { + pickleTree(fun) + args.foreach(pickleTree) } - } - pickleDef(DEFDEF, tree.symbol, tree.tpt, tree.rhs, pickleAllParams) - case tree: TypeDef => - pickleDef(TYPEDEF, tree.symbol, rhs(tree)) - case tree: Template => - registerDef(tree.symbol) - writeByte(TEMPLATE) - val (params, rest) = tree.body partition { - case stat: TypeDef => stat.symbol is Flags.Param - case stat: ValOrDefDef => - stat.symbol.is(Flags.ParamAccessor) && !stat.symbol.isSetter - case _ => false - } - withLength { - pickleParams(params) - tree.parents.foreach(pickleTree) - val cinfo @ ClassInfo(_, _, _, _, selfInfo) = tree.symbol.owner.info - if ((selfInfo ne NoType) || !tree.self.isEmpty) { - writeByte(SELFDEF) - pickleName(tree.self.name) - if (!tree.self.isEmpty) registerTreeAddr(tree.self.tpt) - pickleType { - cinfo.selfInfo match { - case sym: Symbol => sym.info - case tp: Type => tp + case TypeApply(fun, args) => + writeByte(TYPEAPPLY) + withLength { + pickleTree(fun) + args.foreach(pickleTpt) + } + case Literal(const1) => + pickleConstant { + tree.tpe match { + case ConstantType(const2) => const2 + case _ => const1 + } + } + case Super(qual, mix) => + writeByte(SUPER) + withLength { + pickleTree(qual); + if (!mix.isEmpty) { + val SuperType(_, mixinType: TypeRef) = tree.tpe + pickleTree(mix.withType(mixinType)) + } + } + case New(tpt) => + writeByte(NEW) + pickleTpt(tpt) + case Typed(expr, tpt) => + writeByte(TYPED) + withLength { pickleTree(expr); pickleTpt(tpt) } + case NamedArg(name, arg) => + writeByte(NAMEDARG) + withLength { pickleName(name); pickleTree(arg) } + case Assign(lhs, rhs) => + writeByte(ASSIGN) + withLength { pickleTree(lhs); pickleTree(rhs) } + case Block(stats, expr) => + writeByte(BLOCK) + stats.foreach(preRegister) + withLength { pickleTree(expr); stats.foreach(pickleTree) } + case If(cond, thenp, elsep) => + writeByte(IF) + withLength { pickleTree(cond); pickleTree(thenp); pickleTree(elsep) } + case Closure(env, meth, tpt) => + writeByte(LAMBDA) + assert(env.isEmpty) + withLength { + pickleTree(meth) + if (tpt.tpe.exists) pickleTpt(tpt) + } + case Match(selector, cases) => + writeByte(MATCH) + withLength { pickleTree(selector); cases.foreach(pickleTree) } + case CaseDef(pat, guard, rhs) => + writeByte(CASEDEF) + withLength { pickleTree(pat); pickleTree(rhs); pickleTreeUnlessEmpty(guard) } + case Return(expr, from) => + writeByte(RETURN) + withLength { pickleSymRef(from.symbol); pickleTreeUnlessEmpty(expr) } + case Try(block, cases, finalizer) => + writeByte(TRY) + withLength { pickleTree(block); cases.foreach(pickleTree); pickleTreeUnlessEmpty(finalizer) } + case SeqLiteral(elems, elemtpt) => + writeByte(REPEATED) + withLength { pickleTree(elemtpt); elems.foreach(pickleTree) } + case Inlined(call, bindings, expansion) => + writeByte(INLINED) + bindings.foreach(preRegister) + withLength { pickleTree(call); pickleTree(expansion); bindings.foreach(pickleTree) } + case Bind(name, body) => + registerDef(tree.symbol) + writeByte(BIND) + withLength { pickleName(name); pickleType(tree.symbol.info); pickleTree(body) } + case Alternative(alts) => + writeByte(ALTERNATIVE) + withLength { alts.foreach(pickleTree) } + case UnApply(fun, implicits, patterns) => + writeByte(UNAPPLY) + withLength { + pickleTree(fun) + for (implicitArg <- implicits) { + writeByte(IMPLICITarg) + pickleTree(implicitArg) + } + pickleType(tree.tpe) + patterns.foreach(pickleTree) + } + case tree: ValDef => + pickleDef(VALDEF, tree.symbol, tree.tpt, tree.rhs) + case tree: DefDef => + def pickleAllParams = { + pickleParams(tree.tparams) + for (vparams <- tree.vparamss) { + writeByte(PARAMS) + withLength { pickleParams(vparams) } + } + } + pickleDef(DEFDEF, tree.symbol, tree.tpt, tree.rhs, pickleAllParams) + case tree: TypeDef => + pickleDef(TYPEDEF, tree.symbol, tree.rhs) + case tree: Template => + registerDef(tree.symbol) + writeByte(TEMPLATE) + val (params, rest) = tree.body partition { + case stat: TypeDef => stat.symbol is Flags.Param + case stat: ValOrDefDef => + stat.symbol.is(Flags.ParamAccessor) && !stat.symbol.isSetter + case _ => false + } + withLength { + pickleParams(params) + tree.parents.foreach(pickleTree) + val cinfo @ ClassInfo(_, _, _, _, selfInfo) = tree.symbol.owner.info + if ((selfInfo ne NoType) || !tree.self.isEmpty) { + writeByte(SELFDEF) + pickleName(tree.self.name) + + if (!tree.self.tpt.isEmpty) pickleTree(tree.self.tpt) + else { + if (!tree.self.isEmpty) registerTreeAddr(tree.self) + pickleType { + cinfo.selfInfo match { + case sym: Symbol => sym.info + case tp: Type => tp + } + } } } + pickleStats(tree.constr :: rest) } - pickleStats(tree.constr :: rest) - } - case Import(expr, selectors) => - writeByte(IMPORT) - withLength { - pickleTree(expr) - selectors foreach { - case Thicket((from @ Ident(_)) :: (to @ Ident(_)) :: Nil) => - pickleSelector(IMPORTED, from) - pickleSelector(RENAMED, to) - case id @ Ident(_) => - pickleSelector(IMPORTED, id) + case Import(expr, selectors) => + writeByte(IMPORT) + withLength { + pickleTree(expr) + selectors foreach { + case Thicket((from @ Ident(_)) :: (to @ Ident(_)) :: Nil) => + pickleSelector(IMPORTED, from) + pickleSelector(RENAMED, to) + case id @ Ident(_) => + pickleSelector(IMPORTED, id) + } } - } - case PackageDef(pid, stats) => - writeByte(PACKAGE) - withLength { pickleType(pid.tpe); pickleStats(stats) } - }} - catch { - case ex: AssertionError => - println(i"error when pickling tree $tree") - throw ex + case PackageDef(pid, stats) => + writeByte(PACKAGE) + withLength { pickleType(pid.tpe); pickleStats(stats) } + case tree: TypeTree => + pickleType(tree.tpe) + case SingletonTypeTree(ref) => + writeByte(SINGLETONtpt) + pickleTree(ref) + case RefinedTypeTree(parent, refinements) => + if (refinements.isEmpty) pickleTree(parent) + else { + val refineCls = refinements.head.symbol.owner.asClass + pickledTypes.put(refineCls.typeRef, currentAddr) + writeByte(REFINEDtpt) + refinements.foreach(preRegister) + withLength { pickleTree(parent); refinements.foreach(pickleTree) } + } + case AppliedTypeTree(tycon, args) => + writeByte(APPLIEDtpt) + withLength { pickleTree(tycon); args.foreach(pickleTree) } + case AndTypeTree(tp1, tp2) => + writeByte(ANDtpt) + withLength { pickleTree(tp1); pickleTree(tp2) } + case OrTypeTree(tp1, tp2) => + writeByte(ORtpt) + withLength { pickleTree(tp1); pickleTree(tp2) } + case ByNameTypeTree(tp) => + writeByte(BYNAMEtpt) + pickleTree(tp) + case Annotated(tree, annot) => + writeByte(ANNOTATEDtpt) + withLength { pickleTree(tree); pickleTree(annot.tree) } + case PolyTypeTree(tparams, body) => + writeByte(POLYtpt) + withLength { pickleParams(tparams); pickleTree(body) } + case TypeBoundsTree(lo, hi) => + writeByte(TYPEBOUNDStpt) + withLength { pickleTree(lo); pickleTree(hi) } + } + catch { + case ex: AssertionError => + println(i"error when pickling tree $tree") + throw ex + } } def pickleSelector(tag: Int, id: untpd.Ident)(implicit ctx: Context): Unit = { diff --git a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index d2605afea..eba9ab533 100644 --- a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -256,7 +256,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle else if (nextByte == CONTRAVARIANT) { readByte(); -1 } else 0 TypeAlias(alias, variance) - case ANNOTATED => + case ANNOTATEDtype => AnnotatedType(readType(), Annotation(readTerm())) case ANDtype => AndType(readType(), readType()) @@ -368,7 +368,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle private def readPackageRef()(implicit ctx: Context): TermSymbol = { val name = readName() - if (name == nme.ROOT) defn.RootPackage + if (name == nme.ROOT || name == nme.ROOTPKG) defn.RootPackage else if (name == nme.EMPTY_PACKAGE) defn.EmptyPackageVal else ctx.requiredPackage(name) } @@ -389,11 +389,11 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle if (owner.isClass) lctx.setScope(owner.unforcedDecls) else lctx.setNewScope } - private def normalizeFlags(tag: Int, givenFlags: FlagSet, name: Name, isAbstractType: Boolean, rhsIsEmpty: Boolean)(implicit ctx: Context): FlagSet = { + private def normalizeFlags(tag: Int, givenFlags: FlagSet, name: Name, isAbsType: Boolean, rhsIsEmpty: Boolean)(implicit ctx: Context): FlagSet = { val lacksDefinition = rhsIsEmpty && name.isTermName && !name.isConstructorName && !givenFlags.is(ParamOrAccessor) || - isAbstractType + isAbsType var flags = givenFlags if (lacksDefinition && tag != PARAM) flags |= Deferred if (tag == DEFDEF) flags |= Method @@ -407,6 +407,17 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle flags } + def isAbstractType(ttag: Int)(implicit ctx: Context): Boolean = nextUnsharedTag match { + case POLYtpt => + val rdr = fork + rdr.reader.readByte() // tag + rdr.reader.readNat() // length + rdr.skipParams() // tparams + rdr.isAbstractType(rdr.nextUnsharedTag) + case TYPEBOUNDS | TYPEBOUNDStpt => true + case _ => false + } + /** Create symbol of definition node and enter in symAtAddr map * @return the created symbol */ @@ -433,7 +444,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle if (tag == TYPEDEF || tag == TYPEPARAM) name = name.toTypeName skipParams() val ttag = nextUnsharedTag - val isAbstractType = ttag == TYPEBOUNDS + val isAbsType = isAbstractType(ttag) val isClass = ttag == TEMPLATE val templateStart = currentAddr skipTree() // tpt @@ -447,7 +458,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle case _ => EmptyFlags } pickling.println(i"creating symbol $name at $start with flags $givenFlags") - val flags = normalizeFlags(tag, givenFlags | nameFlags(rawName), name, isAbstractType, rhsIsEmpty) + val flags = normalizeFlags(tag, givenFlags | nameFlags(rawName), name, isAbsType, rhsIsEmpty) def adjustIfModule(completer: LazyType) = if (flags is Module) ctx.adjustModuleCompleter(completer, name) else completer val sym = @@ -623,11 +634,6 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle val tag = readByte() val end = readEnd() - def readParams[T <: MemberDef](tag: Int)(implicit ctx: Context): List[T] = { - fork.indexParams(tag)(localContext(sym)) - readIndexedParams(tag) - } - def readParamss(implicit ctx: Context): List[List[ValDef]] = { collectWhile(nextByte == PARAMS) { readByte() @@ -696,7 +702,10 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle TypeDef(readTemplate(localCtx)) } else { val rhs = readTpt() - sym.info = rhs.tpe + sym.info = rhs.tpe match { + case _: TypeBounds | _: ClassInfo => rhs.tpe + case _ => TypeAlias(rhs.tpe, sym.variance) + } TypeDef(rhs) } case PARAM => @@ -846,9 +855,14 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle def readIndexedParams[T <: MemberDef](tag: Int)(implicit ctx: Context): List[T] = collectWhile(nextByte == tag) { readIndexedDef().asInstanceOf[T] } -// ------ Reading terms ----------------------------------------------------- + def readParams[T <: MemberDef](tag: Int)(implicit ctx: Context): List[T] = { + fork.indexParams(tag) + readIndexedParams(tag) + } - def readTerm()(implicit ctx: Context): Tree = { +// ------ Reading trees ----------------------------------------------------- + + def readTerm()(implicit ctx: Context): Tree = { // TODO: rename to readTree val start = currentAddr val tag = readByte() pickling.println(s"reading term ${astTagToString(tag)} at $start") @@ -856,34 +870,52 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle def readPathTerm(): Tree = { goto(start) readType() match { + case path: TypeRef => TypeTree(path) case path: TermRef => ref(path) case path: ThisType => This(path.cls) case path: ConstantType => Literal(path.value) } } + def completeSelect(name: Name, tpf: Type => Type): Select = { + val localCtx = + if (name == nme.CONSTRUCTOR) ctx.addMode(Mode.InSuperCall) else ctx + val qual = readTerm()(localCtx) + val unshadowed = if (name.isShadowedName) name.revertShadowed else name + untpd.Select(qual, unshadowed).withType(tpf(qual.tpe.widenIfUnstable)) + } + + def readQualId(): (untpd.Ident, TypeRef) = { + val qual = readTerm().asInstanceOf[untpd.Ident] + (untpd.Ident(qual.name).withPos(qual.pos), qual.tpe.asInstanceOf[TypeRef]) + } + def readSimpleTerm(): Tree = tag match { + case SHARED => + forkAt(readAddr()).readTerm() case IDENT => untpd.Ident(readName()).withType(readType()) + case IDENTtpt => + untpd.Ident(readName().toTypeName).withType(readType()) case SELECT => - def readQual(name: Name) = { - val localCtx = - if (name == nme.CONSTRUCTOR) ctx.addMode(Mode.InSuperCall) else ctx - readTerm()(localCtx) - } - def readRest(name: Name, sig: Signature) = { - val unshadowed = if (name.isShadowedName) name.revertShadowed else name - val qual = readQual(name) - untpd.Select(qual, unshadowed) - .withType(TermRef.withSig(qual.tpe.widenIfUnstable, name.asTermName, sig)) - } + def readRest(name: Name, sig: Signature) = + completeSelect(name, TermRef.withSig(_, name.asTermName, sig)) readNameSplitSig match { case name: Name => readRest(name, Signature.NotAMethod) case (name: Name, sig: Signature) => readRest(name, sig) } - + case SELECTtpt => + val name = readName().toTypeName + completeSelect(name, TypeRef(_, name)) + case QUALTHIS => + val (qual, tref) = readQualId() + untpd.This(qual).withType(ThisType.raw(tref)) case NEW => New(readTpt()) + case SINGLETONtpt => + SingletonTypeTree(readTerm()) + case BYNAMEtpt => + ByNameTypeTree(readTpt()) case _ => readPathTerm() } @@ -891,10 +923,15 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle def readLengthTerm(): Tree = { val end = readEnd() + def localNonClassCtx = { + val ctx1 = ctx.fresh.setNewScope + if (ctx.owner.isClass) ctx1.setOwner(ctx1.newLocalDummy(ctx.owner)) else ctx1 + } + def readBlock(mkTree: (List[Tree], Tree) => Tree): Tree = { val exprReader = fork skipTree() - val localCtx = ctx.fresh.setNewScope + val localCtx = localNonClassCtx val stats = readStats(ctx.owner, end)(localCtx) val expr = exprReader.readTerm()(localCtx) mkTree(stats, expr) @@ -904,9 +941,8 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle (tag: @switch) match { case SUPER => val qual = readTerm() - val mixClass = ifBefore(end)(readType().typeSymbol, NoSymbol) - val mixName = if (mixClass.exists) mixClass.name.asTypeName else tpnme.EMPTY - tpd.Super(qual, mixName, ctx.mode.is(Mode.InSuperCall), mixClass) + val (mixId, mixTpe) = ifBefore(end)(readQualId(), (untpd.EmptyTypeIdent, NoType)) + tpd.Super(qual, mixId, ctx.mode.is(Mode.InSuperCall), mixTpe.typeSymbol) case APPLY => val fn = readTerm() val isJava = fn.symbol.is(JavaDefined) @@ -934,7 +970,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle case BLOCK => readBlock(Block) case INLINED => - val call = setPos(currentAddr, TypeTree(readType())) + val call = readTerm() readBlock((defs, expr) => Inlined(call, defs.asInstanceOf[List[MemberDef]], expr)) case IF => If(readTerm(), readTerm(), readTerm()) @@ -971,6 +1007,28 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle val patType = readType() val argPats = until(end)(readTerm()) UnApply(fn, implicitArgs, argPats, patType) + case REFINEDtpt => + val refineCls = ctx.newCompleteClassSymbol( + ctx.owner, tpnme.REFINE_CLASS, Fresh, parents = Nil) + typeAtAddr(start) = refineCls.typeRef + val parent = readTpt() + val refinements = readStats(refineCls, end)(localContext(refineCls)) + RefinedTypeTree(parent, refinements, refineCls) + case APPLIEDtpt => + AppliedTypeTree(readTpt(), until(end)(readTpt())) + case ANDtpt => + AndTypeTree(readTpt(), readTpt()) + case ORtpt => + OrTypeTree(readTpt(), readTpt()) + case ANNOTATEDtpt => + Annotated(readTpt(), readTerm()) + case POLYtpt => + val localCtx = localNonClassCtx + val tparams = readParams[TypeDef](TYPEPARAM)(localCtx) + val body = readTpt()(localCtx) + PolyTypeTree(tparams, body) + case TYPEBOUNDStpt => + TypeBoundsTree(readTpt(), readTpt()) case _ => readPathTerm() } @@ -983,11 +1041,13 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle setPos(start, tree) } - def readTpt()(implicit ctx: Context) = { - val start = currentAddr - val tp = readType() - if (tp.exists) setPos(start, TypeTree(tp)) else EmptyTree - } + def readTpt()(implicit ctx: Context) = + if (isTypeTreeTag(nextUnsharedTag)) readTerm() + else { + val start = currentAddr + val tp = readType() + if (tp.exists) setPos(start, TypeTree(tp)) else EmptyTree + } def readCases(end: Addr)(implicit ctx: Context): List[CaseDef] = collectWhile(nextByte == CASEDEF && currentAddr != end) { readCase()(ctx.fresh.setNewScope) } diff --git a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala index 70148b3e2..b01f6cc6a 100644 --- a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala +++ b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala @@ -40,29 +40,15 @@ object Scala2Unpickler { /** Temporary type for classinfos, will be decomposed on completion of the class */ case class TempClassInfoType(parentTypes: List[Type], decls: Scope, clazz: Symbol) extends UncachedGroundType - /** Convert temp poly type to some native Dotty idiom. - * @param denot The denotation that gets the converted type as info. - * If `denot` is not an abstract type, this simply returns an equivalent `PolyType`. - * If `denot` is an abstract type, it converts a - * - * TempPolyType(List(v_1 T_1, ..., v_n T_n), lo .. hi) - * - * to a type lambda using `parameterizeWith/LambdaAbstract`. - */ - def depoly(tp: Type, denot: SymDenotation)(implicit ctx: Context): Type = tp match { - case TempPolyType(tparams, restpe) => - if (denot.isType) { - assert(!denot.isClass) - restpe.LambdaAbstract(tparams) - } - else - PolyType.fromSymbols(tparams, restpe) + /** Convert temp poly type to poly type and leave other types alone. */ + def translateTempPoly(tp: Type)(implicit ctx: Context): Type = tp match { + case TempPolyType(tparams, restpe) => restpe.LambdaAbstract(tparams) case tp => tp } def addConstructorTypeParams(denot: SymDenotation)(implicit ctx: Context) = { assert(denot.isConstructor) - denot.info = PolyType.fromSymbols(denot.owner.typeParams, denot.info) + denot.info = denot.info.LambdaAbstract(denot.owner.typeParams) } /** Convert array parameters denoting a repeated parameter of a Java method @@ -549,7 +535,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas val selfInfo = if (atEnd) NoType else readTypeRef() setClassInfo(denot, tp, selfInfo) case denot => - val tp1 = depoly(tp, denot) + val tp1 = translateTempPoly(tp) denot.info = if (tag == ALIASsym) TypeAlias(tp1) else if (denot.isType) checkNonCyclic(denot.symbol, tp1, reportErrors = false) |