diff options
-rw-r--r-- | src/dotty/tools/dotc/ast/untpd.scala | 10 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/TreeChecker.scala | 9 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 4 | ||||
-rw-r--r-- | tests/run/i768.scala | 10 |
5 files changed, 33 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/ast/untpd.scala b/src/dotty/tools/dotc/ast/untpd.scala index f009d6a86..5db893ff2 100644 --- a/src/dotty/tools/dotc/ast/untpd.scala +++ b/src/dotty/tools/dotc/ast/untpd.scala @@ -228,7 +228,15 @@ 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 refOfDef(tree: NameTree)(implicit ctx: Context) = Ident(tree.name) + /** A reference to given definition. If definition is a repeated + * parameter, the reference will be a repeated argument. + */ + def refOfDef(tree: MemberDef)(implicit ctx: Context) = tree match { + case ValDef(_, PostfixOp(_, nme.raw.STAR), _) => + Typed(Ident(tree.name), Ident(tpnme.WILDCARD_STAR)) + case _ => + Ident(tree.name) + } // ------- Decorators ------------------------------------------------- diff --git a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala index 53e8478fa..a3c131427 100644 --- a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala +++ b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala @@ -501,7 +501,9 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas } ctx.newClassSymbol(owner, name.asTypeName, flags, completer, coord = start) } - case MODULEsym | VALsym => + case VALsym => + ctx.newSymbol(owner, name.asTermName, flags, localMemberUnpickler, coord = start) + case MODULEsym => if (isModuleRoot) { moduleRoot setFlag flags moduleRoot.symbol @@ -546,6 +548,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas if (tag == ALIASsym) TypeAlias(tp1) else if (denot.isType) checkNonCyclic(denot.symbol, tp1, reportErrors = false) // we need the checkNonCyclic call to insert LazyRefs for F-bounded cycles + else if (!denot.is(Param)) tp1.underlyingIfRepeated(isJava = false) else tp1 if (denot.isConstructor) addConstructorTypeParams(denot) if (atEnd) { diff --git a/src/dotty/tools/dotc/transform/TreeChecker.scala b/src/dotty/tools/dotc/transform/TreeChecker.scala index 6ae765480..f046226d1 100644 --- a/src/dotty/tools/dotc/transform/TreeChecker.scala +++ b/src/dotty/tools/dotc/transform/TreeChecker.scala @@ -228,16 +228,21 @@ class TreeChecker extends Phase with SymTransformer { } }.apply(tp) + def checkNotRepeated(tree: Tree)(implicit ctx: Context): tree.type = { + assert(!tree.tpe.widen.isRepeatedParam, i"repeated parameter type not allowed here: $tree") + tree + } + override def typedIdent(tree: untpd.Ident, pt: Type)(implicit ctx: Context): Tree = { assert(tree.isTerm || !ctx.isAfterTyper, tree.show + " at " + ctx.phase) assert(tree.isType || !needsSelect(tree.tpe), i"bad type ${tree.tpe} for $tree # ${tree.uniqueId}") assertDefined(tree) - super.typedIdent(tree, pt) + checkNotRepeated(super.typedIdent(tree, pt)) } override def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = { assert(tree.isTerm || !ctx.isAfterTyper, tree.show + " at " + ctx.phase) - super.typedSelect(tree, pt) + checkNotRepeated(super.typedSelect(tree, pt)) } override def typedThis(tree: untpd.This)(implicit ctx: Context) = { diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 33ec156a1..dcf4ccc6c 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -577,7 +577,9 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit val inferredParams: List[untpd.ValDef] = for ((param, i) <- params.zipWithIndex) yield if (!param.tpt.isEmpty) param - else cpy.ValDef(param)(tpt = untpd.TypeTree(inferredParamType(param, protoFormal(i)))) + else cpy.ValDef(param)( + tpt = untpd.TypeTree( + inferredParamType(param, protoFormal(i)).underlyingIfRepeated(isJava = false))) // Define result type of closure as the expected type, thereby pushing // down any implicit searches. We do this even if the expected type is not fully diff --git a/tests/run/i768.scala b/tests/run/i768.scala new file mode 100644 index 000000000..0697b476b --- /dev/null +++ b/tests/run/i768.scala @@ -0,0 +1,10 @@ +case class A(a: String*){ + val s = a.toString +} + +object Test { + def main(args: Array[String]) = + assert(A("a", "bc").s == "WrappedArray(a, bc)") +} + + |