diff options
-rw-r--r-- | src/dotty/tools/dotc/ast/CheckTrees.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/TreeInfo.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/Trees.scala | 20 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/TypedTrees.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 19 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/UnPickler.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/printing/RefinedPrinter.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 3 | ||||
-rw-r--r-- | test/test/DeSugarTest.scala | 4 |
9 files changed, 47 insertions, 25 deletions
diff --git a/src/dotty/tools/dotc/ast/CheckTrees.scala b/src/dotty/tools/dotc/ast/CheckTrees.scala index 670dd3730..8dbd5a015 100644 --- a/src/dotty/tools/dotc/ast/CheckTrees.scala +++ b/src/dotty/tools/dotc/ast/CheckTrees.scala @@ -121,11 +121,11 @@ object CheckTrees { case Throw(expr) => check(expr.isValue) check(expr.tpe.derivesFrom(defn.ThrowableClass)) - case SeqLiteral(elemtpt, elems) => - check(elemtpt.isValueType); + case SeqLiteral(elems) => + val elemtp = tree.tpe.elemType for (elem <- elems) { check(elem.isValue) - check(elem.tpe <:< elemtpt.tpe) + check(elem.tpe <:< elemtp) } case TypeTree(original) => if (!original.isEmpty) { diff --git a/src/dotty/tools/dotc/ast/TreeInfo.scala b/src/dotty/tools/dotc/ast/TreeInfo.scala index a3af19263..e43fd66cb 100644 --- a/src/dotty/tools/dotc/ast/TreeInfo.scala +++ b/src/dotty/tools/dotc/ast/TreeInfo.scala @@ -366,9 +366,9 @@ abstract class TreeInfo { /** Is this pattern node a sequence-valued pattern? */ def isSequenceValued(tree: Tree[_ >: Untyped]): Boolean = unbind(tree) match { - case Alternative(ts) => ts exists isSequenceValued - case SeqLiteral(_, _) => true - case _ => false + case Alternative(ts) => ts exists isSequenceValued + case SeqLiteral(_) => true + case _ => false } /** The underlying pattern ignoring any bindings */ diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala index 69bc91f5a..dc37d5655 100644 --- a/src/dotty/tools/dotc/ast/Trees.scala +++ b/src/dotty/tools/dotc/ast/Trees.scala @@ -469,7 +469,7 @@ object Trees { } /** Array[elemtpt](elems) */ - case class SeqLiteral[T >: Untyped](elemtpt: Tree[T], elems: List[Tree[T]]) + case class SeqLiteral[T >: Untyped](elems: List[Tree[T]]) extends Tree[T] { type ThisTree[T >: Untyped] = SeqLiteral[T] } @@ -827,9 +827,9 @@ object Trees { case tree: Throw[_] if (expr eq tree.expr) => tree case _ => Throw(expr).copyAttr(tree) } - def derivedSeqLiteral(elemtpt: Tree[T], elems: List[Tree[T]]): SeqLiteral[T] = tree match { - case tree: SeqLiteral[_] if (elemtpt eq tree.elemtpt) && (elems eq tree.elems) => tree - case _ => SeqLiteral(elemtpt, elems).copyAttr(tree) + def derivedSeqLiteral(elems: List[Tree[T]]): SeqLiteral[T] = tree match { + case tree: SeqLiteral[_] if (elems eq tree.elems) => tree + case _ => SeqLiteral(elems).copyAttr(tree) } def derivedSingletonTypeTree(ref: Tree[T]): SingletonTypeTree[T] = tree match { case tree: SingletonTypeTree[_] if (ref eq tree.ref) => tree @@ -957,8 +957,8 @@ object Trees { finishTry(tree.derivedTry(transform(block, c), transform(handler, c), transform(finalizer, c)), tree, c, plugins) case Throw(expr) => finishThrow(tree.derivedThrow(transform(expr, c)), tree, c, plugins) - case SeqLiteral(elemtpt, elems) => - finishSeqLiteral(tree.derivedSeqLiteral(transform(elemtpt, c), transform(elems, c)), tree, c, plugins) + case SeqLiteral(elems) => + finishSeqLiteral(tree.derivedSeqLiteral(transform(elems, c)), tree, c, plugins) case TypeTree(original) => finishTypeTree(tree, tree, c, plugins) case SingletonTypeTree(ref) => @@ -1136,8 +1136,8 @@ object Trees { tree.derivedTry(transform(block), transform(handler), transform(finalizer)) case Throw(expr) => tree.derivedThrow(transform(expr)) - case SeqLiteral(elemtpt, elems) => - tree.derivedSeqLiteral(transform(elemtpt), transform(elems)) + case SeqLiteral(elems) => + tree.derivedSeqLiteral(transform(elems)) case TypeTree(original) => tree case SingletonTypeTree(ref) => @@ -1241,8 +1241,8 @@ object Trees { this(this(this(x, block), handler), finalizer) case Throw(expr) => this(x, expr) - case SeqLiteral(elemtpt, elems) => - this(this(x, elemtpt), elems) + case SeqLiteral(elems) => + this(x, elems) case TypeTree(original) => x case SingletonTypeTree(ref) => diff --git a/src/dotty/tools/dotc/ast/TypedTrees.scala b/src/dotty/tools/dotc/ast/TypedTrees.scala index 122de7d43..2e9944df3 100644 --- a/src/dotty/tools/dotc/ast/TypedTrees.scala +++ b/src/dotty/tools/dotc/ast/TypedTrees.scala @@ -134,11 +134,12 @@ object tpd extends Trees.Instance[Type] { def Throw(expr: Tree)(implicit ctx: Context): Throw = Trees.Throw(expr).withType(defn.NothingType).checked - def SeqLiteral(elemtpt: Tree, elems: List[Tree])(implicit ctx: Context): SeqLiteral = - Trees.SeqLiteral(elemtpt, elems).withType(defn.RepeatedParamType.appliedTo(elemtpt.tpe)).checked + def SeqLiteral(tpe: Type, elems: List[Tree])(implicit ctx: Context): SeqLiteral = + Trees.SeqLiteral(elems).withType(tpe).checked def SeqLiteral(elems: List[Tree])(implicit ctx: Context): SeqLiteral = - SeqLiteral(TypeTree(ctx.lub(elems map (_.tpe))), elems) + SeqLiteral(defn.SeqClass.typeConstructor.appliedTo( + ctx.lub(elems map (_.tpe)) :: Nil), elems) def TypeTree(tp: Type, original: Tree = EmptyTree)(implicit ctx: Context): TypeTree = Trees.TypeTree(original).withType(tp).checked diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 26886ed1d..af2b694f5 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -648,6 +648,10 @@ object Types { Set((Set(), Set())) } + /** The element type of a sequence or array */ + def elemType(implicit ctx: Context): Type = + firstBaseTypeArg(defn.SeqClass) orElse firstBaseTypeArg(defn.ArrayClass) + // ----- Substitutions ----------------------------------------------------- /** Substitute all types that refer in their symbol attribute to @@ -742,6 +746,21 @@ object Types { else TypeAlias(this) } + /** The type arguments of the base type instance wrt `base` of this type */ + final def baseTypeArgs(base: Symbol)(implicit ctx: Context): List[Type] = + if (this <:< base.symRef) + base.typeParams map (param => member(param.name).info.argType(param)) + else + Nil + + /** The first type argument of the base type instance wrt `base` of this type */ + final def firstBaseTypeArg(base: Symbol)(implicit ctx: Context): Type = base.typeParams match { + case param :: _ if this <:< base.symRef => + member(param.name).info.argType(param) + case _ => + NoType + } + /** If this is an encoding of a (partially) applied type, return its arguments, * otherwise return Nil */ diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala index 3b9ca7ba5..70798ad8a 100644 --- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala +++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala @@ -780,7 +780,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: val end = readNat() + readIndex // array elements are trees representing instances of scala.annotation.Annotation SeqLiteral( - TypeTree(defn.AnnotationClass.typeConstructor), + defn.SeqType.appliedTo(defn.AnnotationClass.typeConstructor :: Nil), until(end, () => readClassfileAnnotArg(readNat()))) } @@ -983,7 +983,8 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: case ARRAYVALUEtree => val elemtpt = readTreeRef() val trees = until(end, readTreeRef) - SeqLiteral(elemtpt, trees) + SeqLiteral(defn.SeqType.appliedTo(elemtpt.tpe :: Nil), trees) + // note can't deal with trees passed to Java methods as arrays here case FUNCTIONtree => setSym() diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala index 01d267aec..bd16f97aa 100644 --- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -185,7 +185,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { changePrec(GlobalPrec) { "throw " ~ toText(expr) } - case SeqLiteral(elempt, elems) => + case SeqLiteral(elems) => "[" ~ toTextGlobal(elems, ",") ~ "]" case TypeTree(orig) => if (tree.hasType) toText(tree.typeOpt) else toText(orig) diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index 7cc35387e..663e24415 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -393,7 +393,8 @@ trait Applications extends Compatibility{ self: Typer => def makeVarArg(n: Int, elemFormal: Type): Unit = { val args = typedArgBuf.takeRight(n).toList typedArgBuf.trimEnd(n) - typedArgBuf += SeqLiteral(TypeTree(elemFormal), args) + val seqType = if (methodType.isJava) defn.ArrayType else defn.SeqType + typedArgBuf += tpd.SeqLiteral(seqType.appliedTo(elemFormal :: Nil), args) } def fail(msg: => String, arg: Tree[T]) = { diff --git a/test/test/DeSugarTest.scala b/test/test/DeSugarTest.scala index 0dbe7000d..b408d4b34 100644 --- a/test/test/DeSugarTest.scala +++ b/test/test/DeSugarTest.scala @@ -53,8 +53,8 @@ class DeSugarTest extends ParserTest { tree1.derivedTyped(transform(expr), transform(tpt, Type)) case CaseDef(pat, guard, body) => tree1.derivedCaseDef(transform(pat, Pattern), transform(guard), transform(body)) - case SeqLiteral(elempt, elems) => - tree1.derivedSeqLiteral(transform(elempt, Type), transform(elems)) + case SeqLiteral(elems) => + tree1.derivedSeqLiteral(transform(elems)) case UnApply(fun, args) => tree1.derivedUnApply(transform(fun, Expr), transform(args)) case ValDef(mods, name, tpt, rhs) => |