diff options
-rw-r--r-- | src/dotty/tools/dotc/ast/Desugar.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/TreeInfo.scala | 17 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/Trees.scala | 27 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/untpd.scala | 23 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/tasty/TreePickler.scala | 8 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/parsing/JavaParsers.scala | 9 | ||||
-rw-r--r-- | src/dotty/tools/dotc/parsing/Parsers.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/printing/RefinedPrinter.scala | 25 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/TreeTransform.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 16 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 12 | ||||
-rw-r--r-- | test/test/DeSugarTest.scala | 2 |
13 files changed, 77 insertions, 80 deletions
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala index 349fbfb2c..3c510c7b9 100644 --- a/src/dotty/tools/dotc/ast/Desugar.scala +++ b/src/dotty/tools/dotc/ast/Desugar.scala @@ -234,7 +234,7 @@ object desugar { if (tdef.mods is PrivateLocalParam) { val tparam = cpy.TypeDef(tdef)(name = tdef.name.expandedName(ctx.owner)) .withMods(tdef.mods &~ PrivateLocal | ExpandedName) - val alias = cpy.TypeDef(tdef)(rhs = refOfDef(tparam), tparams = Nil) + val alias = cpy.TypeDef(tdef)(rhs = refOfDef(tparam)) .withMods(tdef.mods & VarianceFlags | PrivateLocalParamAccessor | Synthetic) Thicket(tparam, alias) } @@ -461,8 +461,7 @@ object desugar { val vparamAccessors = derivedVparamss.flatten.map(_.withMods(originalVparams.next.mods | caseAccessor)) cpy.TypeDef(cdef)( rhs = cpy.Template(impl)(constr, parents1, self1, - tparamAccessors ::: vparamAccessors ::: normalizedBody ::: caseClassMeths), - tparams = Nil) + tparamAccessors ::: vparamAccessors ::: normalizedBody ::: caseClassMeths)) } // install the watch on classTycon diff --git a/src/dotty/tools/dotc/ast/TreeInfo.scala b/src/dotty/tools/dotc/ast/TreeInfo.scala index 8b2915174..d1e6bd38a 100644 --- a/src/dotty/tools/dotc/ast/TreeInfo.scala +++ b/src/dotty/tools/dotc/ast/TreeInfo.scala @@ -272,7 +272,12 @@ trait UntypedTreeInfo extends TreeInfo[Untyped] { self: Trees.Instance[Untyped] case mdef: ValOrDefDef => mdef.unforcedRhs == EmptyTree && !mdef.name.isConstructorName && !mdef.mods.is(ParamAccessor) case mdef: TypeDef => - mdef.rhs.isEmpty || mdef.rhs.isInstanceOf[TypeBoundsTree] + def isBounds(rhs: Tree): Boolean = rhs match { + case _: TypeBoundsTree => true + case PolyTypeTree(_, body) => isBounds(body) + case _ => false + } + mdef.rhs.isEmpty || isBounds(mdef.rhs) case _ => false } @@ -382,9 +387,9 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] => def isIdempotentRef(tree: Tree)(implicit ctx: Context) = refPurity(tree) >= Idempotent - /** If `tree` is a constant expression, its value as a Literal, + /** If `tree` is a constant expression, its value as a Literal, * or `tree` itself otherwise. - * + * * Note: Demanding idempotency instead of purity in literalize is strictly speaking too loose. * Example * @@ -410,11 +415,11 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] => * * Revisit this issue once we have implemented `inline`. Then we can demand * purity of the prefix unless the selection goes to an inline val. - * + * * Note: This method should be applied to all term tree nodes that are not literals, * that can be idempotent, and that can have constant types. So far, only nodes - * of the following classes qualify: - * + * of the following classes qualify: + * * Ident * Select * TypeApply diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala index 9108a4d22..78ac66812 100644 --- a/src/dotty/tools/dotc/ast/Trees.scala +++ b/src/dotty/tools/dotc/ast/Trees.scala @@ -60,18 +60,18 @@ object Trees { with Cloneable { if (Stats.enabled) ntrees += 1 - + private def nxId = { nextId += 1 //assert(nextId != 199, this) - nextId + nextId } /** A unique identifier for this tree. Used for debugging, and potentially * tracking presentation compiler interactions */ private var myUniqueId: Int = nxId - + def uniqueId = myUniqueId /** The type constructor at the root of the tree */ @@ -192,7 +192,7 @@ object Trees { override def hashCode(): Int = uniqueId // for debugging; was: System.identityHashCode(this) override def equals(that: Any) = this eq that.asInstanceOf[AnyRef] - + override def clone: Tree[T] = { val tree = super.clone.asInstanceOf[Tree[T]] tree.myUniqueId = nxId @@ -653,12 +653,6 @@ object Trees { /** Is this a definition of a class? */ def isClassDef = rhs.isInstanceOf[Template[_]] - - /** If this a non-class type definition, its type parameters. - * Can be different from Nil only for PolyTypeDefs, which are always - * untyped and get eliminated during desugaring. - */ - def tparams: List[untpd.TypeDef] = Nil } /** extends parents { self => body } */ @@ -1023,9 +1017,9 @@ object Trees { case tree: DefDef if (name == tree.name) && (tparams eq tree.tparams) && (vparamss eq tree.vparamss) && (tpt eq tree.tpt) && (rhs eq tree.unforcedRhs) => tree case _ => finalize(tree, untpd.DefDef(name, tparams, vparamss, tpt, rhs)) } - def TypeDef(tree: Tree)(name: TypeName, rhs: Tree, tparams: List[untpd.TypeDef]): TypeDef = tree match { - case tree: TypeDef if (name == tree.name) && (rhs eq tree.rhs) && (tparams eq tree.tparams) => tree - case _ => finalize(tree, untpd.TypeDef(name, tparams, rhs)) + def TypeDef(tree: Tree)(name: TypeName, rhs: Tree): TypeDef = tree match { + case tree: TypeDef if (name == tree.name) && (rhs eq tree.rhs) => tree + case _ => finalize(tree, untpd.TypeDef(name, rhs)) } def Template(tree: Tree)(constr: DefDef, parents: List[Tree], self: ValDef, body: LazyTreeList): Template = tree match { case tree: Template if (constr eq tree.constr) && (parents eq tree.parents) && (self eq tree.self) && (body eq tree.unforcedBody) => tree @@ -1064,8 +1058,8 @@ object Trees { ValDef(tree: Tree)(name, tpt, rhs) def DefDef(tree: DefDef)(name: TermName = tree.name, tparams: List[TypeDef] = tree.tparams, vparamss: List[List[ValDef]] = tree.vparamss, tpt: Tree = tree.tpt, rhs: LazyTree = tree.unforcedRhs): DefDef = DefDef(tree: Tree)(name, tparams, vparamss, tpt, rhs) - def TypeDef(tree: TypeDef)(name: TypeName = tree.name, rhs: Tree = tree.rhs, tparams: List[untpd.TypeDef] = tree.tparams): TypeDef = - TypeDef(tree: Tree)(name, rhs, tparams) + def TypeDef(tree: TypeDef)(name: TypeName = tree.name, rhs: Tree = tree.rhs): TypeDef = + TypeDef(tree: Tree)(name, rhs) def Template(tree: Template)(constr: DefDef = tree.constr, parents: List[Tree] = tree.parents, self: ValDef = tree.self, body: LazyTreeList = tree.unforcedBody): Template = Template(tree: Tree)(constr, parents, self, body) } @@ -1146,7 +1140,7 @@ object Trees { case tree @ DefDef(name, tparams, vparamss, tpt, _) => cpy.DefDef(tree)(name, transformSub(tparams), vparamss mapConserve (transformSub(_)), transform(tpt), transform(tree.rhs)) case tree @ TypeDef(name, rhs) => - cpy.TypeDef(tree)(name, transform(rhs), tree.tparams) + cpy.TypeDef(tree)(name, transform(rhs)) case tree @ Template(constr, parents, self, _) => cpy.Template(tree)(transformSub(constr), transform(parents), transformSub(self), transformStats(tree.body)) case Import(expr, selectors) => @@ -1294,7 +1288,6 @@ object Trees { case tree: Bind => cpy.Bind(tree)(newName, tree.body) case tree: ValDef => cpy.ValDef(tree)(name = newName.asTermName) case tree: DefDef => cpy.DefDef(tree)(name = newName.asTermName) - case tree: untpd.PolyTypeDef => untpd.cpy.PolyTypeDef(tree)(newName.asTypeName, tree.tparams, tree.rhs).withMods(tree.rawMods) case tree: TypeDef => cpy.TypeDef(tree)(name = newName.asTypeName) } }.asInstanceOf[tree.ThisTree[T]] diff --git a/src/dotty/tools/dotc/ast/untpd.scala b/src/dotty/tools/dotc/ast/untpd.scala index f259bdc57..ac35ad09c 100644 --- a/src/dotty/tools/dotc/ast/untpd.scala +++ b/src/dotty/tools/dotc/ast/untpd.scala @@ -80,9 +80,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { case class ContextBounds(bounds: TypeBoundsTree, cxBounds: List[Tree]) extends TypTree case class PatDef(mods: Modifiers, pats: List[Tree], tpt: Tree, rhs: Tree) extends DefTree - class PolyTypeDef(name: TypeName, override val tparams: List[TypeDef], rhs: Tree) - extends TypeDef(name, rhs) - /** A block arising from a right-associative infix operation, where, e.g. * * a +: b @@ -310,9 +307,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { def TypeTree(tpe: Type)(implicit ctx: Context): TypedSplice = TypedSplice(TypeTree().withTypeUnchecked(tpe)) - def TypeDef(name: TypeName, tparams: List[TypeDef], rhs: Tree): TypeDef = - if (tparams.isEmpty) TypeDef(name, rhs) else new PolyTypeDef(name, tparams, rhs) - def unitLiteral = Literal(Constant(())) def ref(tp: NamedType)(implicit ctx: Context): Tree = @@ -348,6 +342,9 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { def makeSyntheticParameter(n: Int = 1, tpt: Tree = TypeTree())(implicit ctx: Context): ValDef = ValDef(nme.syntheticParamName(n), tpt, EmptyTree).withFlags(SyntheticTermParam) + def lambdaAbstract(tparams: List[TypeDef], tpt: Tree)(implicit ctx: Context) = + if (tparams.isEmpty) tpt else PolyTypeTree(tparams, tpt) + /** A reference to given definition. If definition is a repeated * parameter, the reference will be a repeated argument. */ @@ -392,10 +389,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { if (expr eq tree.expr) && (handler eq tree.handler) && (finalizer eq tree.finalizer) => tree case _ => untpd.ParsedTry(expr, handler, finalizer).withPos(tree.pos) } - def PolyTypeDef(tree: Tree)(name: TypeName, tparams: List[TypeDef], rhs: Tree) = tree match { - case tree: PolyTypeDef if (name eq tree.name) && (tparams eq tree.tparams) && (rhs eq tree.rhs) => tree - case _ => new PolyTypeDef(name, tparams, rhs).withPos(tree.pos) - } def SymbolLit(tree: Tree)(str: String) = tree match { case tree: SymbolLit if str == tree.str => tree case _ => untpd.SymbolLit(str).withPos(tree.pos) @@ -506,8 +499,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { cpy.ContextBounds(tree)(transformSub(bounds), transform(cxBounds)) case PatDef(mods, pats, tpt, rhs) => cpy.PatDef(tree)(mods, transform(pats), transform(tpt), transform(rhs)) - case tree: PolyTypeDef => - cpy.PolyTypeDef(tree)(tree.name, transformSub(tree.tparams), transform(tree.rhs)) case _ => super.transform(tree) } @@ -553,8 +544,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { this(this(x, bounds), cxBounds) case PatDef(mods, pats, tpt, rhs) => this(this(this(x, pats), tpt), rhs) - case tree: PolyTypeDef => - this(this(x, tree.tparams), tree.rhs) case TypedSplice(tree) => this(x, tree) case _ => @@ -566,10 +555,4 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { class UntypedDeepFolder[X](f: (X, Tree) => X) extends UntypedTreeAccumulator[X] { def apply(x: X, tree: Tree)(implicit ctx: Context): X = foldOver(f(x, tree), tree) } - - override def rename(tree: NameTree, newName: Name)(implicit ctx: Context): tree.ThisTree[Untyped] = tree match { - case t: PolyTypeDef => - cpy.PolyTypeDef(t)(newName.asTypeName, t.tparams, t.rhs).asInstanceOf[tree.ThisTree[Untyped]] - case _ => super.rename(tree, newName) - } } diff --git a/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/src/dotty/tools/dotc/core/tasty/TreePickler.scala index 9dfb78798..98a369f25 100644 --- a/src/dotty/tools/dotc/core/tasty/TreePickler.scala +++ b/src/dotty/tools/dotc/core/tasty/TreePickler.scala @@ -49,10 +49,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) @@ -336,7 +332,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) } } @@ -478,7 +474,7 @@ class TreePickler(pickler: TastyPickler) { } pickleDef(DEFDEF, tree.symbol, tree.tpt, tree.rhs, pickleAllParams) case tree: TypeDef => - pickleDef(TYPEDEF, tree.symbol, rhs(tree)) + pickleDef(TYPEDEF, tree.symbol, tree.rhs) case tree: Template => registerDef(tree.symbol) writeByte(TEMPLATE) diff --git a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index d2605afea..90f718402 100644 --- a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -696,7 +696,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 => diff --git a/src/dotty/tools/dotc/parsing/JavaParsers.scala b/src/dotty/tools/dotc/parsing/JavaParsers.scala index b6a423dc7..0f63b25bb 100644 --- a/src/dotty/tools/dotc/parsing/JavaParsers.scala +++ b/src/dotty/tools/dotc/parsing/JavaParsers.scala @@ -417,7 +417,7 @@ object JavaParsers { atPos(in.offset) { val name = identForType() val hi = if (in.token == EXTENDS) { in.nextToken() ; bound() } else EmptyTree - TypeDef(name, Nil, TypeBoundsTree(EmptyTree, hi)).withMods(Modifiers(flags)) + TypeDef(name, TypeBoundsTree(EmptyTree, hi)).withMods(Modifiers(flags)) } def bound(): Tree = @@ -625,8 +625,7 @@ object JavaParsers { val template = cdef.rhs.asInstanceOf[Template] cpy.TypeDef(cdef)(cdef.name, cpy.Template(template)(template.constr, template.parents, template.self, - importCompanionObject(cdef) :: template.body), - cdef.tparams).withMods(cdef.mods) + importCompanionObject(cdef) :: template.body)).withMods(cdef.mods) } List(makeCompanionObject(cdefNew, statics), cdefNew) @@ -715,7 +714,7 @@ object JavaParsers { val (statics, body) = typeBody(INTERFACE, name, tparams) val iface = atPos(start, nameOffset) { TypeDef( - name, tparams, + name, makeTemplate(parents, body, tparams, false)).withMods(mods | Flags.Trait | Flags.JavaInterface | Flags.Abstract) } addCompanionObject(statics, iface) @@ -830,7 +829,7 @@ object JavaParsers { Select(New(javaLangDot(tpnme.Enum)), nme.CONSTRUCTOR), List(enumType)), List(Literal(Constant(null)),Literal(Constant(0)))) val enum = atPos(start, nameOffset) { - TypeDef(name, List(), + TypeDef(name, makeTemplate(superclazz :: interfaces, body, List(), true)).withMods(mods | Flags.Enum) } addCompanionObject(consts ::: statics ::: predefs, enum) diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala index f442c13b3..e0c6be8c8 100644 --- a/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/src/dotty/tools/dotc/parsing/Parsers.scala @@ -1646,7 +1646,7 @@ object Parsers { val bounds = if (isConcreteOwner) typeParamBounds(name) else typeBounds() - TypeDef(name, hkparams, bounds).withMods(mods) + TypeDef(name, lambdaAbstract(hkparams, bounds)).withMods(mods) } } commaSeparated(typeParam) @@ -1956,9 +1956,9 @@ object Parsers { in.token match { case EQUALS => in.nextToken() - TypeDef(name, tparams, typ()).withMods(mods).setComment(docstring) + TypeDef(name, lambdaAbstract(tparams, typ())).withMods(mods).setComment(docstring) case SUPERTYPE | SUBTYPE | SEMI | NEWLINE | NEWLINES | COMMA | RBRACE | EOF => - TypeDef(name, tparams, typeBounds()).withMods(mods).setComment(docstring) + TypeDef(name, lambdaAbstract(tparams, typeBounds())).withMods(mods).setComment(docstring) case _ => syntaxErrorOrIncomplete("`=', `>:', or `<:' expected") EmptyTree diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala index 7aaf2e190..39a21b17b 100644 --- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -351,7 +351,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { case SeqLiteral(elems, elemtpt) => "[" ~ toTextGlobal(elems, ",") ~ " : " ~ toText(elemtpt) ~ "]" case tree @ Inlined(call, bindings, body) => - (("/* inlined from " ~ toText(call) ~ "*/ ") provided !homogenizedView) ~ + (("/* inlined from " ~ toText(call) ~ "*/ ") provided !homogenizedView) ~ blockText(bindings :+ body) case tpt: untpd.DerivedTypeTree => "<derived typetree watching " ~ summarized(toText(tpt.watched)) ~ ">" @@ -402,24 +402,27 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { } } case tree @ TypeDef(name, rhs) => - def typeDefText(rhsText: Text) = + def typeDefText(tparamsText: => Text, rhsText: => Text) = dclTextOr { modText(tree.mods, "type") ~~ (varianceText(tree.mods) ~ nameIdText(tree)) ~ withEnclosingDef(tree) { - val rhsText1 = if (tree.hasType) toText(tree.symbol.info) else rhsText - tparamsText(tree.tparams) ~ rhsText1 + if (tree.hasType) toText(tree.symbol.info) // TODO: always print RHS, once we pickle/unpickle type trees + else tparamsText ~ rhsText } } - rhs match { + def recur(rhs: Tree, tparamsTxt: => Text): Text = rhs match { case impl: Template => modText(tree.mods, if ((tree).mods is Trait) "trait" else "class") ~~ nameIdText(tree) ~ withEnclosingDef(tree) { toTextTemplate(impl) } ~ (if (tree.hasType && ctx.settings.verbose.value) i"[decls = ${tree.symbol.info.decls}]" else "") case rhs: TypeBoundsTree => - typeDefText(toText(rhs)) - case _ => - typeDefText(optText(rhs)(" = " ~ _)) + typeDefText(tparamsTxt, toText(rhs)) + case PolyTypeTree(tparams, body) => + recur(body, tparamsText(tparams)) + case rhs => + typeDefText(tparamsTxt, optText(rhs)(" = " ~ _)) } + recur(rhs, "") case Import(expr, selectors) => def selectorText(sel: Tree): Text = sel match { case Thicket(l :: r :: Nil) => toTextGlobal(l) ~ " => " ~ toTextGlobal(r) @@ -525,11 +528,11 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { if (tree.isType) txt = toText(tp) else if (!tree.isDef) txt = ("<" ~ txt ~ ":" ~ toText(tp) ~ ">").close } - else if (homogenizedView && tree.isType) + else if (homogenizedView && tree.isType) txt = toText(tree.typeOpt) if (ctx.settings.Yprintpos.value && !tree.isInstanceOf[WithoutTypeOrPos[_]]) { - val pos = - if (homogenizedView && !tree.isInstanceOf[MemberDef]) tree.pos.toSynthetic + val pos = + if (homogenizedView && !tree.isInstanceOf[MemberDef]) tree.pos.toSynthetic else tree.pos val clsStr = "" // DEBUG: if (tree.isType) tree.getClass.toString else "" txt = (txt ~ "@" ~ pos.toString ~ clsStr).close diff --git a/src/dotty/tools/dotc/transform/TreeTransform.scala b/src/dotty/tools/dotc/transform/TreeTransform.scala index a1ccf0e63..5385ca720 100644 --- a/src/dotty/tools/dotc/transform/TreeTransform.scala +++ b/src/dotty/tools/dotc/transform/TreeTransform.scala @@ -977,7 +977,7 @@ object TreeTransforms { if (mutatedInfo eq null) tree else { val rhs = transform(tree.rhs, mutatedInfo, cur)(localContext(tree.symbol)) - goTypeDef(cpy.TypeDef(tree)(tree.name, rhs, tree.tparams), mutatedInfo.nx.nxTransTypeDef(cur)) + goTypeDef(cpy.TypeDef(tree)(tree.name, rhs), mutatedInfo.nx.nxTransTypeDef(cur)) } case _ => tree diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 77f8ff786..3876fdf15 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -293,7 +293,7 @@ class Namer { typer: Typer => val inSuperCall1 = if (tree.mods is ParamOrAccessor) EmptyFlags else inSuperCall // suppress inSuperCall for constructor parameters val higherKinded = tree match { - case tree: TypeDef if tree.tparams.nonEmpty && isDeferred => HigherKinded + case TypeDef(_, PolyTypeTree(_, _)) if isDeferred => HigherKinded case _ => EmptyFlags } @@ -605,8 +605,12 @@ class Namer { typer: Typer => nestedCtx = localContext(sym).setNewScope myTypeParams = { implicit val ctx: Context = nestedCtx - completeParams(original.tparams) - original.tparams.map(symbolOfTree(_).asType) + val tparams = original.rhs match { + case PolyTypeTree(tparams, _) => tparams + case _ => Nil + } + completeParams(tparams) + tparams.map(symbolOfTree(_).asType) } } myTypeParams @@ -1005,7 +1009,11 @@ class Namer { typer: Typer => // inspects a TypeRef's info, instead of simply dealiasing alias types. val isDerived = tdef.rhs.isInstanceOf[untpd.DerivedTypeTree] - val rhsBodyType = typedAheadType(tdef.rhs).tpe + val rhs = tdef.rhs match { + case PolyTypeTree(_, body) => body + case rhs => rhs + } + val rhsBodyType = typedAheadType(rhs).tpe val rhsType = if (isDerived) rhsBodyType else abstracted(rhsBodyType) val unsafeInfo = rhsType match { case bounds: TypeBounds => bounds diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 6b69a859e..a72c1d5f2 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -1185,7 +1185,15 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit def typedTypeDef(tdef: untpd.TypeDef, sym: Symbol)(implicit ctx: Context): Tree = track("typedTypeDef") { val TypeDef(name, rhs) = tdef completeAnnotations(tdef, sym) - assignType(cpy.TypeDef(tdef)(name, typedType(rhs), Nil), sym) + val rhs1 = tdef.rhs match { + case rhs @ PolyTypeTree(tparams, body) => + val tparams1 = tparams.map(typed(_)).asInstanceOf[List[TypeDef]] + val body1 = typedType(body) + assignType(cpy.PolyTypeTree(rhs)(tparams1, body1), tparams1, body1) + case rhs => + typedType(rhs) + } + assignType(cpy.TypeDef(tdef)(name, rhs1), sym) } def typedClassDef(cdef: untpd.TypeDef, cls: ClassSymbol)(implicit ctx: Context) = track("typedClassDef") { @@ -1250,7 +1258,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit .withType(dummy.nonMemberTermRef) checkVariance(impl1) if (!cls.is(AbstractOrTrait) && !ctx.isAfterTyper) checkRealizableBounds(cls.typeRef, cdef.namePos) - val cdef1 = assignType(cpy.TypeDef(cdef)(name, impl1, Nil), cls) + val cdef1 = assignType(cpy.TypeDef(cdef)(name, impl1), cls) if (ctx.phase.isTyper && cdef1.tpe.derivesFrom(defn.DynamicClass) && !ctx.dynamicsEnabled) { val isRequired = parents1.exists(_.tpe.isRef(defn.DynamicClass)) ctx.featureWarning(nme.dynamics.toString, "extension of type scala.Dynamic", isScala2Feature = true, diff --git a/test/test/DeSugarTest.scala b/test/test/DeSugarTest.scala index 1365f3222..d7a056e42 100644 --- a/test/test/DeSugarTest.scala +++ b/test/test/DeSugarTest.scala @@ -62,7 +62,7 @@ class DeSugarTest extends ParserTest { case tree1 @ DefDef(name, tparams, vparamss, tpt, _) => cpy.DefDef(tree1)(name, transformSub(tparams), vparamss mapConserve (transformSub(_)), transform(tpt, Type), transform(tree1.rhs)) case tree1 @ TypeDef(name, rhs) => - cpy.TypeDef(tree1)(name, transform(rhs, Type), transformSub(tree1.tparams)) + cpy.TypeDef(tree1)(name, transform(rhs, Type)) case impl @ Template(constr, parents, self, _) => cpy.Template(tree1)(transformSub(constr), transform(parents), transformSub(self), transform(impl.body, Expr)) case Thicket(trees) => |