Skip to content

Commit e73ef77

Browse files
committed
Merge pull request #1166 from dotty-staging/fix-#1136
Fix typing of SeqLiterals
2 parents bd8a6dc + 208c91a commit e73ef77

20 files changed

+80
-61
lines changed

src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1006,7 +1006,7 @@ object desugar {
10061006
collect(expr)
10071007
case NamedArg(_, arg) =>
10081008
collect(arg)
1009-
case SeqLiteral(elems) =>
1009+
case SeqLiteral(elems, _) =>
10101010
elems foreach collect
10111011
case Alternative(trees) =>
10121012
for (tree <- trees; (vble, _) <- getVariables(tree))

src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -519,16 +519,18 @@ object Trees {
519519
type ThisTree[-T >: Untyped] = Try[T]
520520
}
521521

522-
/** Seq(elems) */
523-
case class SeqLiteral[-T >: Untyped] private[ast] (elems: List[Tree[T]])
522+
/** Seq(elems)
523+
* @param tpt The element type of the sequence.
524+
*/
525+
case class SeqLiteral[-T >: Untyped] private[ast] (elems: List[Tree[T]], elemtpt: Tree[T])
524526
extends Tree[T] {
525527
type ThisTree[-T >: Untyped] = SeqLiteral[T]
526528
}
527529

528530
/** Array(elems) */
529-
class JavaSeqLiteral[T >: Untyped] private[ast] (elems: List[Tree[T]])
530-
extends SeqLiteral(elems) {
531-
override def toString = s"JavaSeqLiteral($elems)"
531+
class JavaSeqLiteral[T >: Untyped] private[ast] (elems: List[Tree[T]], elemtpt: Tree[T])
532+
extends SeqLiteral(elems, elemtpt) {
533+
override def toString = s"JavaSeqLiteral($elems, $elemtpt)"
532534
}
533535

534536
/** A type tree that represents an existing or inferred type */
@@ -978,12 +980,12 @@ object Trees {
978980
case tree: Try if (expr eq tree.expr) && (cases eq tree.cases) && (finalizer eq tree.finalizer) => tree
979981
case _ => finalize(tree, untpd.Try(expr, cases, finalizer))
980982
}
981-
def SeqLiteral(tree: Tree)(elems: List[Tree])(implicit ctx: Context): SeqLiteral = tree match {
983+
def SeqLiteral(tree: Tree)(elems: List[Tree], elemtpt: Tree)(implicit ctx: Context): SeqLiteral = tree match {
982984
case tree: JavaSeqLiteral =>
983-
if (elems eq tree.elems) tree
984-
else finalize(tree, new JavaSeqLiteral(elems))
985-
case tree: SeqLiteral if elems eq tree.elems => tree
986-
case _ => finalize(tree, untpd.SeqLiteral(elems))
985+
if ((elems eq tree.elems) && (elemtpt eq tree.elemtpt)) tree
986+
else finalize(tree, new JavaSeqLiteral(elems, elemtpt))
987+
case tree: SeqLiteral if (elems eq tree.elems) && (elemtpt eq tree.elemtpt) => tree
988+
case _ => finalize(tree, untpd.SeqLiteral(elems, elemtpt))
987989
}
988990
def TypeTree(tree: Tree)(original: Tree): TypeTree = tree match {
989991
case tree: TypeTree if original eq tree.original => tree
@@ -1129,8 +1131,8 @@ object Trees {
11291131
cpy.Return(tree)(transform(expr), transformSub(from))
11301132
case Try(block, cases, finalizer) =>
11311133
cpy.Try(tree)(transform(block), transformSub(cases), transform(finalizer))
1132-
case SeqLiteral(elems) =>
1133-
cpy.SeqLiteral(tree)(transform(elems))
1134+
case SeqLiteral(elems, elemtpt) =>
1135+
cpy.SeqLiteral(tree)(transform(elems), transform(elemtpt))
11341136
case TypeTree(original) =>
11351137
tree
11361138
case SingletonTypeTree(ref) =>
@@ -1233,8 +1235,8 @@ object Trees {
12331235
this(this(x, expr), from)
12341236
case Try(block, handler, finalizer) =>
12351237
this(this(this(x, block), handler), finalizer)
1236-
case SeqLiteral(elems) =>
1237-
this(x, elems)
1238+
case SeqLiteral(elems, elemtpt) =>
1239+
this(this(x, elems), elemtpt)
12381240
case TypeTree(original) =>
12391241
x
12401242
case SingletonTypeTree(ref) =>

src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,11 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
123123
def Try(block: Tree, cases: List[CaseDef], finalizer: Tree)(implicit ctx: Context): Try =
124124
ta.assignType(untpd.Try(block, cases, finalizer), block, cases)
125125

126-
def SeqLiteral(elems: List[Tree])(implicit ctx: Context): SeqLiteral =
127-
ta.assignType(untpd.SeqLiteral(elems), elems)
126+
def SeqLiteral(elems: List[Tree], elemtpt: Tree)(implicit ctx: Context): SeqLiteral =
127+
ta.assignType(untpd.SeqLiteral(elems, elemtpt), elems, elemtpt)
128128

129-
def SeqLiteral(tpe: Type, elems: List[Tree])(implicit ctx: Context): SeqLiteral =
130-
if (tpe derivesFrom defn.SeqClass) SeqLiteral(elems) else JavaSeqLiteral(elems)
131-
132-
def JavaSeqLiteral(elems: List[Tree])(implicit ctx: Context): SeqLiteral =
133-
ta.assignType(new untpd.JavaSeqLiteral(elems), elems)
129+
def JavaSeqLiteral(elems: List[Tree], elemtpt: Tree)(implicit ctx: Context): SeqLiteral =
130+
ta.assignType(new untpd.JavaSeqLiteral(elems, elemtpt), elems, elemtpt)
134131

135132
def TypeTree(original: Tree)(implicit ctx: Context): TypeTree =
136133
TypeTree(original.tpe, original)
@@ -564,11 +561,14 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
564561
}
565562
}
566563

567-
override def SeqLiteral(tree: Tree)(elems: List[Tree])(implicit ctx: Context): SeqLiteral = {
568-
val tree1 = untpd.cpy.SeqLiteral(tree)(elems)
564+
override def SeqLiteral(tree: Tree)(elems: List[Tree], elemtpt: Tree)(implicit ctx: Context): SeqLiteral = {
565+
val tree1 = untpd.cpy.SeqLiteral(tree)(elems, elemtpt)
569566
tree match {
570-
case tree: SeqLiteral if sameTypes(elems, tree.elems) => tree1.withTypeUnchecked(tree.tpe)
571-
case _ => ta.assignType(tree1, elems)
567+
case tree: SeqLiteral
568+
if sameTypes(elems, tree.elems) && (elemtpt.tpe eq tree.elemtpt.tpe) =>
569+
tree1.withTypeUnchecked(tree.tpe)
570+
case _ =>
571+
ta.assignType(tree1, elems, elemtpt)
572572
}
573573
}
574574

@@ -852,7 +852,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
852852
ctx.typer.resolveOverloaded(allAlts, proto, Nil)
853853
assert(alternatives.size == 1,
854854
i"${if (alternatives.isEmpty) "no" else "multiple"} overloads available for " +
855-
i"$method on ${receiver.tpe.widenDealias} with targs: $targs, args: $args and expectedType: $expectedType." +
855+
i"$method on ${receiver.tpe.widenDealias} with targs: $targs%, %; args: $args%, % of types ${args.tpes}%, %; expectedType: $expectedType." +
856856
i" isAnnotConstructor = $isAnnotConstructor.\n" +
857857
i"all alternatives: ${allAlts.map(_.symbol.showDcl).mkString(", ")}\n" +
858858
i"matching alternatives: ${alternatives.map(_.symbol.showDcl).mkString(", ")}.") // this is parsed from bytecode tree. there's nothing user can do about it

src/dotty/tools/dotc/ast/untpd.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
127127
def CaseDef(pat: Tree, guard: Tree, body: Tree): CaseDef = new CaseDef(pat, guard, body)
128128
def Return(expr: Tree, from: Tree): Return = new Return(expr, from)
129129
def Try(expr: Tree, cases: List[CaseDef], finalizer: Tree): Try = new Try(expr, cases, finalizer)
130-
def SeqLiteral(elems: List[Tree]): SeqLiteral = new SeqLiteral(elems)
131-
def JavaSeqLiteral(elems: List[Tree]): JavaSeqLiteral = new JavaSeqLiteral(elems)
130+
def SeqLiteral(elems: List[Tree], elemtpt: Tree): SeqLiteral = new SeqLiteral(elems, elemtpt)
131+
def JavaSeqLiteral(elems: List[Tree], elemtpt: Tree): JavaSeqLiteral = new JavaSeqLiteral(elems, elemtpt)
132132
def TypeTree(original: Tree): TypeTree = new TypeTree(original)
133133
def TypeTree() = new TypeTree(EmptyTree)
134134
def SingletonTypeTree(ref: Tree): SingletonTypeTree = new SingletonTypeTree(ref)

src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ object SymDenotations {
616616

617617
/** Is this symbol a class references to which that are supertypes of null? */
618618
final def isNullableClass(implicit ctx: Context): Boolean =
619-
isClass && !isValueClass && !(this is ModuleClass)
619+
isClass && !isValueClass && !(this is ModuleClass) && symbol != defn.NothingClass
620620

621621
/** Is this definition accessible as a member of tree with type `pre`?
622622
* @param pre The type of the tree from which the selection is made

src/dotty/tools/dotc/core/classfile/ClassfileParser.scala

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,14 @@ class ClassfileParser(
438438
case None => hasError = true
439439
}
440440
if (hasError) None
441-
else if (skip) None else Some(JavaSeqLiteral(arr.toList))
441+
else if (skip) None
442+
else {
443+
val elems = arr.toList
444+
val elemType =
445+
if (elems.isEmpty) defn.ObjectType
446+
else ctx.typeComparer.lub(elems.tpes).widen
447+
Some(JavaSeqLiteral(elems, TypeTree(elemType)))
448+
}
442449
case ANNOTATION_TAG =>
443450
parseAnnotation(index, skip) map (_.tree)
444451
}

src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,9 +418,9 @@ class TreePickler(pickler: TastyPickler) {
418418
case Try(block, cases, finalizer) =>
419419
writeByte(TRY)
420420
withLength { pickleTree(block); cases.foreach(pickleTree); pickleTreeUnlessEmpty(finalizer) }
421-
case SeqLiteral(elems) =>
421+
case SeqLiteral(elems, elemtpt) =>
422422
writeByte(REPEATED)
423-
withLength { elems.foreach(pickleTree) }
423+
withLength { pickleTree(elemtpt); elems.foreach(pickleTree) }
424424
case TypeTree(original) =>
425425
pickleTpt(tree)
426426
case Bind(name, body) =>

src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) {
805805
val fn = readTerm()
806806
val isJava = fn.tpe.isInstanceOf[JavaMethodType]
807807
def readArg() = readTerm() match {
808-
case SeqLiteral(elems) if isJava => JavaSeqLiteral(elems)
808+
case SeqLiteral(elems, elemtpt) if isJava => JavaSeqLiteral(elems, elemtpt)
809809
case arg => arg
810810
}
811811
tpd.Apply(fn, until(end)(readArg()))
@@ -841,7 +841,8 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) {
841841
case TRY =>
842842
Try(readTerm(), readCases(end), ifBefore(end)(readTerm(), EmptyTree))
843843
case REPEATED =>
844-
SeqLiteral(until(end)(readTerm()))
844+
val elemtpt = readTpt()
845+
SeqLiteral(until(end)(readTerm()), elemtpt)
845846
case BIND =>
846847
val name = readName()
847848
val info = readType()

src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -850,8 +850,8 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
850850
val end = readNat() + readIndex
851851
// array elements are trees representing instances of scala.annotation.Annotation
852852
SeqLiteral(
853-
defn.SeqType.appliedTo(defn.AnnotationType :: Nil),
854-
until(end, () => readClassfileAnnotArg(readNat())))
853+
until(end, () => readClassfileAnnotArg(readNat())),
854+
TypeTree(defn.AnnotationType))
855855
}
856856

857857
private def readAnnotInfoArg()(implicit ctx: Context): Tree = {
@@ -1063,7 +1063,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
10631063
case ARRAYVALUEtree =>
10641064
val elemtpt = readTreeRef()
10651065
val trees = until(end, readTreeRef)
1066-
SeqLiteral(defn.SeqType.appliedTo(elemtpt.tpe :: Nil), trees)
1066+
SeqLiteral(trees, elemtpt)
10671067
// note can't deal with trees passed to Java methods as arrays here
10681068

10691069
case FUNCTIONtree =>

src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,8 +380,8 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
380380
changePrec(GlobalPrec) {
381381
"throw " ~ toText(expr)
382382
}
383-
case SeqLiteral(elems) =>
384-
"[" ~ toTextGlobal(elems, ",") ~ "]"
383+
case SeqLiteral(elems, elemtpt) =>
384+
"[" ~ toTextGlobal(elems, ",") ~ " : " ~ toText(elemtpt) ~ "]"
385385
case tpt: untpd.DerivedTypeTree =>
386386
"<derived typetree watching " ~ summarized(toText(tpt.watched)) ~ ">"
387387
case TypeTree(orig) =>

src/dotty/tools/dotc/transform/ElimRepeated.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer with Annotati
7171

7272
/** Convert sequence argument to Java array */
7373
private def seqToArray(tree: Tree)(implicit ctx: Context): Tree = tree match {
74-
case SeqLiteral(elems) =>
75-
JavaSeqLiteral(elems)
74+
case SeqLiteral(elems, elemtpt) =>
75+
JavaSeqLiteral(elems, elemtpt)
7676
case _ =>
7777
val elemType = tree.tpe.firstBaseArgInfo(defn.SeqClass)
7878
var elemClass = elemType.classSymbol

src/dotty/tools/dotc/transform/SeqLiterals.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ class SeqLiterals extends MiniPhaseTransform {
3232
override def transformSeqLiteral(tree: SeqLiteral)(implicit ctx: Context, info: TransformerInfo): Tree = tree match {
3333
case tree: JavaSeqLiteral => tree
3434
case _ =>
35-
val arr = JavaSeqLiteral(tree.elems)
35+
val arr = JavaSeqLiteral(tree.elems, tree.elemtpt)
3636
//println(i"trans seq $tree, arr = $arr: ${arr.tpe} ${arr.tpe.elemType}")
37-
val elemtp = arr.tpe.elemType.bounds.hi
37+
val elemtp = tree.elemtpt.tpe
3838
val elemCls = elemtp.classSymbol
3939
val (wrapMethStr, targs) =
4040
if (elemCls.isPrimitiveValueClass) (s"wrap${elemCls.name}Array", Nil)

src/dotty/tools/dotc/transform/TreeTransform.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1148,7 +1148,8 @@ object TreeTransforms {
11481148
if (mutatedInfo eq null) tree
11491149
else {
11501150
val elems = transformTrees(tree.elems, mutatedInfo, cur)
1151-
goSeqLiteral(cpy.SeqLiteral(tree)(elems), mutatedInfo.nx.nxTransSeqLiteral(cur))
1151+
val elemtpt = transform(tree.elemtpt, mutatedInfo, cur)
1152+
goSeqLiteral(cpy.SeqLiteral(tree)(elems, elemtpt), mutatedInfo.nx.nxTransSeqLiteral(cur))
11521153
}
11531154
case tree: TypeTree =>
11541155
implicit val mutatedInfo: TransformerInfo = mutateTransformers(info, prepForTypeTree, info.nx.nxPrepTypeTree, tree, cur)

src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,10 @@ trait Applications extends Compatibility { self: Typer =>
442442
def makeVarArg(n: Int, elemFormal: Type): Unit = {
443443
val args = typedArgBuf.takeRight(n).toList
444444
typedArgBuf.trimEnd(n)
445-
val seqLit = if (methodType.isJava) JavaSeqLiteral(args) else SeqLiteral(args)
445+
val elemtpt = TypeTree(elemFormal)
446+
val seqLit =
447+
if (methodType.isJava) JavaSeqLiteral(args, elemtpt)
448+
else SeqLiteral(args, elemtpt)
446449
typedArgBuf += seqToRepeated(seqLit)
447450
}
448451

@@ -771,7 +774,7 @@ trait Applications extends Compatibility { self: Typer =>
771774
for (argType <- argTypes) assert(!argType.isInstanceOf[TypeBounds], unapplyApp.tpe.show)
772775
val bunchedArgs = argTypes match {
773776
case argType :: Nil =>
774-
if (argType.isRepeatedParam) untpd.SeqLiteral(args) :: Nil
777+
if (argType.isRepeatedParam) untpd.SeqLiteral(args, untpd.TypeTree()) :: Nil
775778
else if (args.lengthCompare(1) > 0 && ctx.canAutoTuple) untpd.Tuple(args) :: Nil
776779
else args
777780
case _ => args

src/dotty/tools/dotc/typer/ReTyper.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class ReTyper extends Typer {
9292
try super.typedUnadapted(tree, pt)
9393
catch {
9494
case NonFatal(ex) =>
95-
Printers.transforms.println(i"exception while typing $tree of class ${tree.getClass} # ${tree.uniqueId}")
95+
println(i"exception while typing $tree of class ${tree.getClass} # ${tree.uniqueId}")
9696
throw ex
9797
}
9898

src/dotty/tools/dotc/typer/TypeAssigner.scala

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -392,14 +392,12 @@ trait TypeAssigner {
392392
if (cases.isEmpty) tree.withType(expr.tpe)
393393
else tree.withType(ctx.typeComparer.lub(expr.tpe :: cases.tpes))
394394

395-
def assignType(tree: untpd.SeqLiteral, elems: List[Tree])(implicit ctx: Context) = tree match {
396-
case tree: JavaSeqLiteral =>
397-
tree.withType(defn.ArrayOf(ctx.typeComparer.lub(elems.tpes).widen))
398-
case _ =>
399-
val ownType =
400-
if (ctx.erasedTypes) defn.SeqType
401-
else defn.SeqType.appliedTo(ctx.typeComparer.lub(elems.tpes).widen)
402-
tree.withType(ownType)
395+
def assignType(tree: untpd.SeqLiteral, elems: List[Tree], elemtpt: Tree)(implicit ctx: Context) = {
396+
val ownType = tree match {
397+
case tree: JavaSeqLiteral => defn.ArrayOf(elemtpt.tpe)
398+
case _ => if (ctx.erasedTypes) defn.SeqType else defn.SeqType.appliedTo(elemtpt.tpe)
399+
}
400+
tree.withType(ownType)
403401
}
404402

405403
def assignType(tree: untpd.SingletonTypeTree, ref: Tree)(implicit ctx: Context) =

src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,14 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
839839
def typedSeqLiteral(tree: untpd.SeqLiteral, pt: Type)(implicit ctx: Context): SeqLiteral = track("typedSeqLiteral") {
840840
val proto1 = pt.elemType orElse WildcardType
841841
val elems1 = tree.elems mapconserve (typed(_, proto1))
842-
assignType(cpy.SeqLiteral(tree)(elems1), elems1)
842+
val proto2 = // the computed type of the `elemtpt` field
843+
if (!tree.elemtpt.isEmpty) WildcardType
844+
else if (isFullyDefined(proto1, ForceDegree.none)) proto1
845+
else if (tree.elems.isEmpty && tree.isInstanceOf[Trees.JavaSeqLiteral[_]])
846+
defn.ObjectType // generic empty Java varargs are of type Object[]
847+
else ctx.typeComparer.lub(elems1.tpes)
848+
val elemtpt1 = typed(tree.elemtpt, proto2)
849+
assignType(cpy.SeqLiteral(tree)(elems1, elemtpt1), elems1, elemtpt1)
843850
}
844851

845852
def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): TypeTree = track("typedTypeTree") {

test/test/DeSugarTest.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ class DeSugarTest extends ParserTest {
5353
cpy.Typed(tree1)(transform(expr), transform(tpt, Type))
5454
case CaseDef(pat, guard, body) =>
5555
cpy.CaseDef(tree1)(transform(pat, Pattern), transform(guard), transform(body))
56-
case SeqLiteral(elems) =>
57-
cpy.SeqLiteral(tree1)(transform(elems))
56+
case SeqLiteral(elems, elemtpt) =>
57+
cpy.SeqLiteral(tree1)(transform(elems), transform(elemtpt))
5858
case UnApply(fun, implicits, patterns) =>
5959
cpy.UnApply(tree1)(transform(fun, Expr), transform(implicits), transform(patterns))
6060
case tree1 @ ValDef(name, tpt, _) =>

tests/pickling/hk.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ object higherKinded {
3131
}
3232

3333
class Ident[-T >: Untyped] extends Tree[T] {
34-
type ThisType[-U] = Ident[U]
34+
type ThisType[-U >: Untyped] = Ident[U]
3535
}
3636

3737
val id = new Ident[Integer]

tests/pos/hk.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ object higherKinded {
3131
}
3232

3333
class Ident[-T >: Untyped] extends Tree[T] {
34-
type ThisType[-U] = Ident[U]
34+
type ThisType[-U >: Untyped] = Ident[U]
3535
}
3636

3737
val id = new Ident[Integer]

0 commit comments

Comments
 (0)