From 39719aadb4076ecf22ca348f607367817638853d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 10 Mar 2016 16:46:14 +0100 Subject: [PATCH 1/4] More info when resolveOverloading fails --- src/dotty/tools/dotc/ast/tpd.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala index bf6084d7a75c..9a6f74331a9e 100644 --- a/src/dotty/tools/dotc/ast/tpd.scala +++ b/src/dotty/tools/dotc/ast/tpd.scala @@ -852,7 +852,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { ctx.typer.resolveOverloaded(allAlts, proto, Nil) assert(alternatives.size == 1, i"${if (alternatives.isEmpty) "no" else "multiple"} overloads available for " + - i"$method on ${receiver.tpe.widenDealias} with targs: $targs, args: $args and expectedType: $expectedType." + + i"$method on ${receiver.tpe.widenDealias} with targs: $targs%, %; args: $args%, % of types ${args.tpes}%, %; expectedType: $expectedType." + i" isAnnotConstructor = $isAnnotConstructor.\n" + i"all alternatives: ${allAlts.map(_.symbol.showDcl).mkString(", ")}\n" + i"matching alternatives: ${alternatives.map(_.symbol.showDcl).mkString(", ")}.") // this is parsed from bytecode tree. there's nothing user can do about it From 9a624b9249024eec4e165b47e22fe3f029a9ae81 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 10 Mar 2016 18:50:43 +0100 Subject: [PATCH 2/4] Nothing is not nullable --- src/dotty/tools/dotc/core/SymDenotations.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index bde8cc10a1f5..a83e7726af0d 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -616,7 +616,7 @@ object SymDenotations { /** Is this symbol a class references to which that are supertypes of null? */ final def isNullableClass(implicit ctx: Context): Boolean = - isClass && !isValueClass && !(this is ModuleClass) + isClass && !isValueClass && !(this is ModuleClass) && symbol != defn.NothingClass /** Is this definition accessible as a member of tree with type `pre`? * @param pre The type of the tree from which the selection is made From 65639176ce59fd64cbecd90bf5680e64e471938f Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 10 Mar 2016 17:15:20 +0100 Subject: [PATCH 3/4] Add second field to SeqLiteral The field keeps track of the element type. This is necessary because JavaSeqLiteral is nonvariant and the elements might be empty, so we cannot always compute the type from the element types. --- src/dotty/tools/dotc/ast/Desugar.scala | 2 +- src/dotty/tools/dotc/ast/Trees.scala | 30 ++++++++++--------- src/dotty/tools/dotc/ast/tpd.scala | 22 +++++++------- src/dotty/tools/dotc/ast/untpd.scala | 4 +-- .../dotc/core/classfile/ClassfileParser.scala | 9 +++++- .../tools/dotc/core/tasty/TreePickler.scala | 4 +-- .../tools/dotc/core/tasty/TreeUnpickler.scala | 5 ++-- .../core/unpickleScala2/Scala2Unpickler.scala | 6 ++-- .../tools/dotc/printing/RefinedPrinter.scala | 4 +-- .../tools/dotc/transform/ElimRepeated.scala | 4 +-- .../tools/dotc/transform/SeqLiterals.scala | 4 +-- .../tools/dotc/transform/TreeTransform.scala | 3 +- src/dotty/tools/dotc/typer/Applications.scala | 7 +++-- src/dotty/tools/dotc/typer/ReTyper.scala | 2 +- src/dotty/tools/dotc/typer/TypeAssigner.scala | 14 ++++----- src/dotty/tools/dotc/typer/Typer.scala | 9 +++++- test/test/DeSugarTest.scala | 4 +-- 17 files changed, 76 insertions(+), 57 deletions(-) diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala index 8ba155097a11..1eafea049f02 100644 --- a/src/dotty/tools/dotc/ast/Desugar.scala +++ b/src/dotty/tools/dotc/ast/Desugar.scala @@ -1000,7 +1000,7 @@ object desugar { collect(expr) case NamedArg(_, arg) => collect(arg) - case SeqLiteral(elems) => + case SeqLiteral(elems, _) => elems foreach collect case Alternative(trees) => for (tree <- trees; (vble, _) <- getVariables(tree)) diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala index 54ace3be4c9d..5fbbad9a1d3e 100644 --- a/src/dotty/tools/dotc/ast/Trees.scala +++ b/src/dotty/tools/dotc/ast/Trees.scala @@ -515,16 +515,18 @@ object Trees { type ThisTree[-T >: Untyped] = Try[T] } - /** Seq(elems) */ - case class SeqLiteral[-T >: Untyped] private[ast] (elems: List[Tree[T]]) + /** Seq(elems) + * @param tpt The element type of the sequence. + */ + case class SeqLiteral[-T >: Untyped] private[ast] (elems: List[Tree[T]], elemtpt: Tree[T]) extends Tree[T] { type ThisTree[-T >: Untyped] = SeqLiteral[T] } /** Array(elems) */ - class JavaSeqLiteral[T >: Untyped] private[ast] (elems: List[Tree[T]]) - extends SeqLiteral(elems) { - override def toString = s"JavaSeqLiteral($elems)" + class JavaSeqLiteral[T >: Untyped] private[ast] (elems: List[Tree[T]], elemtpt: Tree[T]) + extends SeqLiteral(elems, elemtpt) { + override def toString = s"JavaSeqLiteral($elems, $elemtpt)" } /** A type tree that represents an existing or inferred type */ @@ -974,12 +976,12 @@ object Trees { case tree: Try if (expr eq tree.expr) && (cases eq tree.cases) && (finalizer eq tree.finalizer) => tree case _ => finalize(tree, untpd.Try(expr, cases, finalizer)) } - def SeqLiteral(tree: Tree)(elems: List[Tree])(implicit ctx: Context): SeqLiteral = tree match { + def SeqLiteral(tree: Tree)(elems: List[Tree], elemtpt: Tree)(implicit ctx: Context): SeqLiteral = tree match { case tree: JavaSeqLiteral => - if (elems eq tree.elems) tree - else finalize(tree, new JavaSeqLiteral(elems)) - case tree: SeqLiteral if elems eq tree.elems => tree - case _ => finalize(tree, untpd.SeqLiteral(elems)) + if ((elems eq tree.elems) && (elemtpt eq tree.elemtpt)) tree + else finalize(tree, new JavaSeqLiteral(elems, elemtpt)) + case tree: SeqLiteral if (elems eq tree.elems) && (elemtpt eq tree.elemtpt) => tree + case _ => finalize(tree, untpd.SeqLiteral(elems, elemtpt)) } def TypeTree(tree: Tree)(original: Tree): TypeTree = tree match { case tree: TypeTree if original eq tree.original => tree @@ -1125,8 +1127,8 @@ object Trees { cpy.Return(tree)(transform(expr), transformSub(from)) case Try(block, cases, finalizer) => cpy.Try(tree)(transform(block), transformSub(cases), transform(finalizer)) - case SeqLiteral(elems) => - cpy.SeqLiteral(tree)(transform(elems)) + case SeqLiteral(elems, elemtpt) => + cpy.SeqLiteral(tree)(transform(elems), transform(elemtpt)) case TypeTree(original) => tree case SingletonTypeTree(ref) => @@ -1229,8 +1231,8 @@ object Trees { this(this(x, expr), from) case Try(block, handler, finalizer) => this(this(this(x, block), handler), finalizer) - case SeqLiteral(elems) => - this(x, elems) + case SeqLiteral(elems, elemtpt) => + this(this(x, elems), elemtpt) case TypeTree(original) => x case SingletonTypeTree(ref) => diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala index 9a6f74331a9e..a6d97478b027 100644 --- a/src/dotty/tools/dotc/ast/tpd.scala +++ b/src/dotty/tools/dotc/ast/tpd.scala @@ -123,14 +123,11 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { def Try(block: Tree, cases: List[CaseDef], finalizer: Tree)(implicit ctx: Context): Try = ta.assignType(untpd.Try(block, cases, finalizer), block, cases) - def SeqLiteral(elems: List[Tree])(implicit ctx: Context): SeqLiteral = - ta.assignType(untpd.SeqLiteral(elems), elems) + def SeqLiteral(elems: List[Tree], elemtpt: Tree)(implicit ctx: Context): SeqLiteral = + ta.assignType(untpd.SeqLiteral(elems, elemtpt), elems, elemtpt) - def SeqLiteral(tpe: Type, elems: List[Tree])(implicit ctx: Context): SeqLiteral = - if (tpe derivesFrom defn.SeqClass) SeqLiteral(elems) else JavaSeqLiteral(elems) - - def JavaSeqLiteral(elems: List[Tree])(implicit ctx: Context): SeqLiteral = - ta.assignType(new untpd.JavaSeqLiteral(elems), elems) + def JavaSeqLiteral(elems: List[Tree], elemtpt: Tree)(implicit ctx: Context): SeqLiteral = + ta.assignType(new untpd.JavaSeqLiteral(elems, elemtpt), elems, elemtpt) def TypeTree(original: Tree)(implicit ctx: Context): TypeTree = TypeTree(original.tpe, original) @@ -564,11 +561,14 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { } } - override def SeqLiteral(tree: Tree)(elems: List[Tree])(implicit ctx: Context): SeqLiteral = { - val tree1 = untpd.cpy.SeqLiteral(tree)(elems) + override def SeqLiteral(tree: Tree)(elems: List[Tree], elemtpt: Tree)(implicit ctx: Context): SeqLiteral = { + val tree1 = untpd.cpy.SeqLiteral(tree)(elems, elemtpt) tree match { - case tree: SeqLiteral if sameTypes(elems, tree.elems) => tree1.withTypeUnchecked(tree.tpe) - case _ => ta.assignType(tree1, elems) + case tree: SeqLiteral + if sameTypes(elems, tree.elems) && (elemtpt.tpe eq tree.elemtpt.tpe) => + tree1.withTypeUnchecked(tree.tpe) + case _ => + ta.assignType(tree1, elems, elemtpt) } } diff --git a/src/dotty/tools/dotc/ast/untpd.scala b/src/dotty/tools/dotc/ast/untpd.scala index 85052a4da950..c7a7036c3836 100644 --- a/src/dotty/tools/dotc/ast/untpd.scala +++ b/src/dotty/tools/dotc/ast/untpd.scala @@ -127,8 +127,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { def CaseDef(pat: Tree, guard: Tree, body: Tree): CaseDef = new CaseDef(pat, guard, body) def Return(expr: Tree, from: Tree): Return = new Return(expr, from) def Try(expr: Tree, cases: List[CaseDef], finalizer: Tree): Try = new Try(expr, cases, finalizer) - def SeqLiteral(elems: List[Tree]): SeqLiteral = new SeqLiteral(elems) - def JavaSeqLiteral(elems: List[Tree]): JavaSeqLiteral = new JavaSeqLiteral(elems) + def SeqLiteral(elems: List[Tree], elemtpt: Tree): SeqLiteral = new SeqLiteral(elems, elemtpt) + def JavaSeqLiteral(elems: List[Tree], elemtpt: Tree): JavaSeqLiteral = new JavaSeqLiteral(elems, elemtpt) def TypeTree(original: Tree): TypeTree = new TypeTree(original) def TypeTree() = new TypeTree(EmptyTree) def SingletonTypeTree(ref: Tree): SingletonTypeTree = new SingletonTypeTree(ref) diff --git a/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala b/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala index 9ea24324bc0d..25558a79a690 100644 --- a/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala +++ b/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala @@ -438,7 +438,14 @@ class ClassfileParser( case None => hasError = true } if (hasError) None - else if (skip) None else Some(JavaSeqLiteral(arr.toList)) + else if (skip) None + else { + val elems = arr.toList + val elemType = + if (elems.isEmpty) defn.ObjectType + else ctx.typeComparer.lub(elems.tpes).widen + Some(JavaSeqLiteral(elems, TypeTree(elemType))) + } case ANNOTATION_TAG => parseAnnotation(index, skip) map (_.tree) } diff --git a/src/dotty/tools/dotc/core/tasty/TreePickler.scala b/src/dotty/tools/dotc/core/tasty/TreePickler.scala index bb6c3cd2e8ec..d7fc62a16329 100644 --- a/src/dotty/tools/dotc/core/tasty/TreePickler.scala +++ b/src/dotty/tools/dotc/core/tasty/TreePickler.scala @@ -407,9 +407,9 @@ class TreePickler(pickler: TastyPickler) { case Try(block, cases, finalizer) => writeByte(TRY) withLength { pickleTree(block); cases.foreach(pickleTree); pickleTreeUnlessEmpty(finalizer) } - case SeqLiteral(elems) => + case SeqLiteral(elems, elemtpt) => writeByte(REPEATED) - withLength { elems.foreach(pickleTree) } + withLength { pickleTree(elemtpt); elems.foreach(pickleTree) } case TypeTree(original) => pickleTpt(tree) case Bind(name, body) => diff --git a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index 16caac02e20b..9d692cc93375 100644 --- a/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -801,7 +801,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) { val fn = readTerm() val isJava = fn.tpe.isInstanceOf[JavaMethodType] def readArg() = readTerm() match { - case SeqLiteral(elems) if isJava => JavaSeqLiteral(elems) + case SeqLiteral(elems, elemtpt) if isJava => JavaSeqLiteral(elems, elemtpt) case arg => arg } tpd.Apply(fn, until(end)(readArg())) @@ -837,7 +837,8 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) { case TRY => Try(readTerm(), readCases(end), ifBefore(end)(readTerm(), EmptyTree)) case REPEATED => - SeqLiteral(until(end)(readTerm())) + val elemtpt = readTpt() + SeqLiteral(until(end)(readTerm()), elemtpt) case BIND => val name = readName() val info = readType() diff --git a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala index 7a13388aebcf..2831de3e01b3 100644 --- a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala +++ b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala @@ -850,8 +850,8 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas val end = readNat() + readIndex // array elements are trees representing instances of scala.annotation.Annotation SeqLiteral( - defn.SeqType.appliedTo(defn.AnnotationType :: Nil), - until(end, () => readClassfileAnnotArg(readNat()))) + until(end, () => readClassfileAnnotArg(readNat())), + TypeTree(defn.AnnotationType)) } private def readAnnotInfoArg()(implicit ctx: Context): Tree = { @@ -1063,7 +1063,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas case ARRAYVALUEtree => val elemtpt = readTreeRef() val trees = until(end, readTreeRef) - SeqLiteral(defn.SeqType.appliedTo(elemtpt.tpe :: Nil), trees) + SeqLiteral(trees, elemtpt) // note can't deal with trees passed to Java methods as arrays here case FUNCTIONtree => diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala index a03a01e8d3ee..e21f12410928 100644 --- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -380,8 +380,8 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { changePrec(GlobalPrec) { "throw " ~ toText(expr) } - case SeqLiteral(elems) => - "[" ~ toTextGlobal(elems, ",") ~ "]" + case SeqLiteral(elems, elemtpt) => + "[" ~ toTextGlobal(elems, ",") ~ " : " ~ toText(elemtpt) ~ "]" case tpt: untpd.DerivedTypeTree => "" case TypeTree(orig) => diff --git a/src/dotty/tools/dotc/transform/ElimRepeated.scala b/src/dotty/tools/dotc/transform/ElimRepeated.scala index 98abbb26d144..30778267d68d 100644 --- a/src/dotty/tools/dotc/transform/ElimRepeated.scala +++ b/src/dotty/tools/dotc/transform/ElimRepeated.scala @@ -71,8 +71,8 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer with Annotati /** Convert sequence argument to Java array */ private def seqToArray(tree: Tree)(implicit ctx: Context): Tree = tree match { - case SeqLiteral(elems) => - JavaSeqLiteral(elems) + case SeqLiteral(elems, elemtpt) => + JavaSeqLiteral(elems, elemtpt) case _ => val elemType = tree.tpe.firstBaseArgInfo(defn.SeqClass) var elemClass = elemType.classSymbol diff --git a/src/dotty/tools/dotc/transform/SeqLiterals.scala b/src/dotty/tools/dotc/transform/SeqLiterals.scala index 6e29d7e092df..49ea695300bb 100644 --- a/src/dotty/tools/dotc/transform/SeqLiterals.scala +++ b/src/dotty/tools/dotc/transform/SeqLiterals.scala @@ -32,9 +32,9 @@ class SeqLiterals extends MiniPhaseTransform { override def transformSeqLiteral(tree: SeqLiteral)(implicit ctx: Context, info: TransformerInfo): Tree = tree match { case tree: JavaSeqLiteral => tree case _ => - val arr = JavaSeqLiteral(tree.elems) + val arr = JavaSeqLiteral(tree.elems, tree.elemtpt) //println(i"trans seq $tree, arr = $arr: ${arr.tpe} ${arr.tpe.elemType}") - val elemtp = arr.tpe.elemType.bounds.hi + val elemtp = tree.elemtpt.tpe val elemCls = elemtp.classSymbol val (wrapMethStr, targs) = if (elemCls.isPrimitiveValueClass) (s"wrap${elemCls.name}Array", Nil) diff --git a/src/dotty/tools/dotc/transform/TreeTransform.scala b/src/dotty/tools/dotc/transform/TreeTransform.scala index 7a2280baa34e..7fe00338832b 100644 --- a/src/dotty/tools/dotc/transform/TreeTransform.scala +++ b/src/dotty/tools/dotc/transform/TreeTransform.scala @@ -1148,7 +1148,8 @@ object TreeTransforms { if (mutatedInfo eq null) tree else { val elems = transformTrees(tree.elems, mutatedInfo, cur) - goSeqLiteral(cpy.SeqLiteral(tree)(elems), mutatedInfo.nx.nxTransSeqLiteral(cur)) + val elemtpt = transform(tree.elemtpt, mutatedInfo, cur) + goSeqLiteral(cpy.SeqLiteral(tree)(elems, elemtpt), mutatedInfo.nx.nxTransSeqLiteral(cur)) } case tree: TypeTree => implicit val mutatedInfo: TransformerInfo = mutateTransformers(info, prepForTypeTree, info.nx.nxPrepTypeTree, tree, cur) diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index 3b8c56ea6eb8..3ad9902a4c4a 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -442,7 +442,10 @@ trait Applications extends Compatibility { self: Typer => def makeVarArg(n: Int, elemFormal: Type): Unit = { val args = typedArgBuf.takeRight(n).toList typedArgBuf.trimEnd(n) - val seqLit = if (methodType.isJava) JavaSeqLiteral(args) else SeqLiteral(args) + val elemtpt = TypeTree(elemFormal) + val seqLit = + if (methodType.isJava) JavaSeqLiteral(args, elemtpt) + else SeqLiteral(args, elemtpt) typedArgBuf += seqToRepeated(seqLit) } @@ -771,7 +774,7 @@ trait Applications extends Compatibility { self: Typer => for (argType <- argTypes) assert(!argType.isInstanceOf[TypeBounds], unapplyApp.tpe.show) val bunchedArgs = argTypes match { case argType :: Nil => - if (argType.isRepeatedParam) untpd.SeqLiteral(args) :: Nil + if (argType.isRepeatedParam) untpd.SeqLiteral(args, untpd.TypeTree()) :: Nil else if (args.lengthCompare(1) > 0 && ctx.canAutoTuple) untpd.Tuple(args) :: Nil else args case _ => args diff --git a/src/dotty/tools/dotc/typer/ReTyper.scala b/src/dotty/tools/dotc/typer/ReTyper.scala index 49718fd008d6..225451886e74 100644 --- a/src/dotty/tools/dotc/typer/ReTyper.scala +++ b/src/dotty/tools/dotc/typer/ReTyper.scala @@ -92,7 +92,7 @@ class ReTyper extends Typer { try super.typedUnadapted(tree, pt) catch { case NonFatal(ex) => - Printers.transforms.println(i"exception while typing $tree of class ${tree.getClass} # ${tree.uniqueId}") + println(i"exception while typing $tree of class ${tree.getClass} # ${tree.uniqueId}") throw ex } diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala index 476839ab34a5..84951fd2b3e9 100644 --- a/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -392,14 +392,12 @@ trait TypeAssigner { if (cases.isEmpty) tree.withType(expr.tpe) else tree.withType(ctx.typeComparer.lub(expr.tpe :: cases.tpes)) - def assignType(tree: untpd.SeqLiteral, elems: List[Tree])(implicit ctx: Context) = tree match { - case tree: JavaSeqLiteral => - tree.withType(defn.ArrayOf(ctx.typeComparer.lub(elems.tpes).widen)) - case _ => - val ownType = - if (ctx.erasedTypes) defn.SeqType - else defn.SeqType.appliedTo(ctx.typeComparer.lub(elems.tpes).widen) - tree.withType(ownType) + def assignType(tree: untpd.SeqLiteral, elems: List[Tree], elemtpt: Tree)(implicit ctx: Context) = { + val ownType = tree match { + case tree: JavaSeqLiteral => defn.ArrayOf(elemtpt.tpe) + case _ => if (ctx.erasedTypes) defn.SeqType else defn.SeqType.appliedTo(elemtpt.tpe) + } + tree.withType(ownType) } def assignType(tree: untpd.SingletonTypeTree, ref: Tree)(implicit ctx: Context) = diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index fdb92a40b1d1..2683b2364471 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -836,7 +836,14 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit def typedSeqLiteral(tree: untpd.SeqLiteral, pt: Type)(implicit ctx: Context): SeqLiteral = track("typedSeqLiteral") { val proto1 = pt.elemType orElse WildcardType val elems1 = tree.elems mapconserve (typed(_, proto1)) - assignType(cpy.SeqLiteral(tree)(elems1), elems1) + val proto2 = // the computed type of the `elemtpt` field + if (!tree.elemtpt.isEmpty) WildcardType + else if (isFullyDefined(proto1, ForceDegree.none)) proto1 + else if (tree.elems.isEmpty && tree.isInstanceOf[Trees.JavaSeqLiteral[_]]) + defn.ObjectType // generic empty Java varargs are of type Object[] + else ctx.typeComparer.lub(elems1.tpes) + val elemtpt1 = typed(tree.elemtpt, proto2) + assignType(cpy.SeqLiteral(tree)(elems1, elemtpt1), elems1, elemtpt1) } def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): TypeTree = track("typedTypeTree") { diff --git a/test/test/DeSugarTest.scala b/test/test/DeSugarTest.scala index 44360d657cdc..77aa293d53a3 100644 --- a/test/test/DeSugarTest.scala +++ b/test/test/DeSugarTest.scala @@ -53,8 +53,8 @@ class DeSugarTest extends ParserTest { cpy.Typed(tree1)(transform(expr), transform(tpt, Type)) case CaseDef(pat, guard, body) => cpy.CaseDef(tree1)(transform(pat, Pattern), transform(guard), transform(body)) - case SeqLiteral(elems) => - cpy.SeqLiteral(tree1)(transform(elems)) + case SeqLiteral(elems, elemtpt) => + cpy.SeqLiteral(tree1)(transform(elems), transform(elemtpt)) case UnApply(fun, implicits, patterns) => cpy.UnApply(tree1)(transform(fun, Expr), transform(implicits), transform(patterns)) case tree1 @ ValDef(name, tpt, _) => From 208c91a3749910ff23ae65f7ff36d7b3cf8d62db Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 11 Mar 2016 11:09:31 +0100 Subject: [PATCH 4/4] Fix test cases The test contained an error that was unvovered by the "Nothing is not Nullable" fix. --- tests/pickling/hk.scala | 2 +- tests/pos/hk.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/pickling/hk.scala b/tests/pickling/hk.scala index 9fdaf94f6ca8..a8f2aa5971cc 100644 --- a/tests/pickling/hk.scala +++ b/tests/pickling/hk.scala @@ -31,7 +31,7 @@ object higherKinded { } class Ident[-T >: Untyped] extends Tree[T] { - type ThisType[-U] = Ident[U] + type ThisType[-U >: Untyped] = Ident[U] } val id = new Ident[Integer] diff --git a/tests/pos/hk.scala b/tests/pos/hk.scala index 9fdaf94f6ca8..a8f2aa5971cc 100644 --- a/tests/pos/hk.scala +++ b/tests/pos/hk.scala @@ -31,7 +31,7 @@ object higherKinded { } class Ident[-T >: Untyped] extends Tree[T] { - type ThisType[-U] = Ident[U] + type ThisType[-U >: Untyped] = Ident[U] } val id = new Ident[Integer]