diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index 10bf1c2032db..27e4afb65d6c 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -11,7 +11,7 @@ import Symbols._ import Types._ import Decorators._ import Constants._ -import StdNames.nme +import StdNames._ import Contexts.Context import Names.{Name, TermName, EmptyTermName} import NameOps._ @@ -602,7 +602,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { newOwners = ctx.owner :: Nil, substFrom = ddef.vparamss.head.map(_.symbol), substTo = argSyms) - Block(bindingsBuf.toList, expander.transform(ddef.rhs)) + seq(bindingsBuf.toList, expander.transform(ddef.rhs)) case _ => tree } case _ => tree @@ -629,7 +629,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { /** Try to match pattern `pat` against scrutinee reference `scrut`. If successful add * bindings for variables bound in this pattern to `bindingsBuf`. */ - def reducePattern(bindingsBuf: mutable.ListBuffer[MemberDef], scrut: TermRef, pat: Tree): Boolean = { + def reducePattern(bindingsBuf: mutable.ListBuffer[MemberDef], scrut: TermRef, pat: Tree)(implicit ctx: Context): Boolean = { val isImplicit = scrut.info == defn.ImplicitScrutineeTypeRef def newBinding(name: TermName, flags: FlagSet, rhs: Tree): Symbol = { @@ -655,8 +655,32 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { pat match { case Typed(pat1, tpt) => + val getBoundVars = new TreeAccumulator[List[TypeSymbol]] { + def apply(syms: List[TypeSymbol], t: Tree)(implicit ctx: Context) = { + val syms1 = t match { + case t: Bind if t.symbol.isType && t.name != tpnme.WILDCARD => + t.symbol.asType :: syms + case _ => + syms + } + foldOver(syms1, t) + } + } + val boundVars = getBoundVars(Nil, tpt) + for (bv <- boundVars) ctx.gadt.setBounds(bv, bv.info.bounds) if (isImplicit) searchImplicit(nme.WILDCARD, tpt) - else scrut <:< tpt.tpe && reducePattern(bindingsBuf, scrut, pat1) + else scrut <:< tpt.tpe && { + for (bv <- boundVars) { + bv.info = TypeAlias(ctx.gadt.bounds(bv).lo) + // FIXME: This is very crude. We should approximate with lower or higher bound depending + // on variance, and we should also take care of recursive bounds. Basically what + // ConstraintHandler#approximation does. However, this only works for constrained paramrefs + // not GADT-bound variables. Hopefully we will get some way to improve this when we + // re-implement GADTs in terms of constraints. + bindingsBuf += TypeDef(bv) + } + reducePattern(bindingsBuf, scrut, pat1) + } case pat @ Bind(name: TermName, Typed(_, tpt)) if isImplicit => searchImplicit(name, tpt) case pat @ Bind(name: TermName, body) => @@ -706,16 +730,19 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { val scrutineeBinding = normalizeBinding(ValDef(scrutineeSym, scrutinee)) def reduceCase(cdef: untpd.CaseDef): MatchRedux = { - def guardOK = cdef.guard.isEmpty || { - typer.typed(cdef.guard, defn.BooleanType) match { + val caseBindingsBuf = new mutable.ListBuffer[MemberDef]() + def guardOK(implicit ctx: Context) = cdef.guard.isEmpty || { + val guardCtx = ctx.fresh.setNewScope + caseBindingsBuf.foreach(binding => guardCtx.enter(binding.symbol)) + typer.typed(cdef.guard, defn.BooleanType)(guardCtx) match { case ConstantValue(true) => true case _ => false } } - val caseBindingsBuf = new mutable.ListBuffer[MemberDef]() if (scrutType != defn.ImplicitScrutineeTypeRef) caseBindingsBuf += scrutineeBinding - val pat1 = typer.typedPattern(cdef.pat, scrutType)(typer.gadtContext(gadtSyms)) - if (reducePattern(caseBindingsBuf, scrutineeSym.termRef, pat1) && guardOK) + val gadtCtx = typer.gadtContext(gadtSyms).addMode(Mode.GADTflexible) + val pat1 = typer.typedPattern(cdef.pat, scrutType)(gadtCtx) + if (reducePattern(caseBindingsBuf, scrutineeSym.termRef, pat1)(gadtCtx) && guardOK) Some((caseBindingsBuf.toList, cdef.body)) else None @@ -809,6 +836,8 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { def dropUnusedDefs(bindings: List[MemberDef], tree: Tree)(implicit ctx: Context): (List[MemberDef], Tree) = { val refCount = newMutableSymbolMap[Int] val bindingOfSym = newMutableSymbolMap[MemberDef] + val dealiased = new java.util.IdentityHashMap[Type, Type]() + def isInlineable(binding: MemberDef) = binding match { case DefDef(_, Nil, Nil, _, _) => true case vdef @ ValDef(_, _, _) => isPureExpr(vdef.rhs) @@ -818,6 +847,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { refCount(binding.symbol) = 0 bindingOfSym(binding.symbol) = binding } + val countRefs = new TreeTraverser { override def traverse(t: Tree)(implicit ctx: Context) = { def updateRefCount(sym: Symbol, inc: Int) = @@ -844,6 +874,45 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { } } && !boundSym.is(TransparentImplicitMethod) + val (termBindings, typeBindings) = bindings.partition(_.symbol.isTerm) + + /** drop any referenced type symbols from the given set of type symbols */ + val dealiasTypeBindings = new TreeMap { + val boundTypes = typeBindings.map(_.symbol).toSet + + val dealias = new TypeMap { + override def apply(tp: Type) = dealiased.get(tp) match { + case null => + val tp1 = mapOver { + tp match { + case tp: TypeRef if boundTypes.contains(tp.symbol) => + val TypeAlias(alias) = tp.info + alias + case _ => tp + } + } + dealiased.put(tp, tp1) + tp1 + case tp1 => tp1 + } + } + + override def transform(t: Tree)(implicit ctx: Context) = { + val dealiasedType = dealias(t.tpe) + val t1 = t match { + case t: RefTree => + if (boundTypes.contains(t.symbol)) TypeTree(dealiasedType).withPos(t.pos) + else t.withType(dealiasedType) + case t: DefTree => + t.symbol.info = dealias(t.symbol.info) + t + case _ => + t.withType(dealiasedType) + } + super.transform(t1) + } + } + val inlineBindings = new TreeMap { override def transform(t: Tree)(implicit ctx: Context) = t match { case t: RefTree => @@ -859,17 +928,23 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { case t: Apply => val t1 = super.transform(t) if (t1 `eq` t) t else reducer.betaReduce(t1) + case Block(Nil, expr) => + super.transform(expr) case _ => super.transform(t) } } - val retained = bindings.filterConserve(binding => retain(binding.symbol)) - if (retained `eq` bindings) { - (bindings, tree) + val dealiasedTermBindings = + termBindings.mapconserve(dealiasTypeBindings.transform).asInstanceOf[List[MemberDef]] + val dealiasedTree = dealiasTypeBindings.transform(tree) + + val retained = dealiasedTermBindings.filterConserve(binding => retain(binding.symbol)) + if (retained `eq` dealiasedTermBindings) { + (dealiasedTermBindings, dealiasedTree) } else { - val expanded = inlineBindings.transform(tree) + val expanded = inlineBindings.transform(dealiasedTree) dropUnusedDefs(retained, expanded) } } diff --git a/compiler/src/dotty/tools/dotc/typer/PrepareTransparent.scala b/compiler/src/dotty/tools/dotc/typer/PrepareTransparent.scala index 9219853fa309..44156f56e74f 100644 --- a/compiler/src/dotty/tools/dotc/typer/PrepareTransparent.scala +++ b/compiler/src/dotty/tools/dotc/typer/PrepareTransparent.scala @@ -49,7 +49,7 @@ object PrepareTransparent { def markTopLevelMatches(meth: Symbol, tree: untpd.Tree)(implicit ctx: Context): Unit = tree match { case tree: untpd.Match => tree.putAttachment(TopLevelMatch, ()) - tree.cases.foreach(markTopLevelMatches(meth, _)) + for (cdef <- tree.cases) markTopLevelMatches(meth, cdef.body) case tree: untpd.Block => markTopLevelMatches(meth, tree.expr) case _ => @@ -76,12 +76,14 @@ object PrepareTransparent { * by excluding all symbols properly contained in the inlined method. * * Constant vals don't need accessors since they are inlined in FirstTransform. + * Transparent methods don't need accessors since they are inlined in Typer. */ def needsAccessor(sym: Symbol)(implicit ctx: Context) = sym.isTerm && (sym.is(AccessFlags) || sym.privateWithin.exists) && !sym.isContainedIn(inlineSym) && - !(sym.isStable && sym.info.widenTermRefExpr.isInstanceOf[ConstantType]) + !(sym.isStable && sym.info.widenTermRefExpr.isInstanceOf[ConstantType]) && + !sym.is(TransparentMethod) def preTransform(tree: Tree)(implicit ctx: Context): Tree diff --git a/compiler/src/dotty/tools/dotc/util/Set.scala b/compiler/src/dotty/tools/dotc/util/Set.scala index bcaf272167ad..4ed1865ce60e 100644 --- a/compiler/src/dotty/tools/dotc/util/Set.scala +++ b/compiler/src/dotty/tools/dotc/util/Set.scala @@ -1,7 +1,3 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2012 LAMP/EPFL - * @author Martin Odersky - */ package dotty.tools.dotc.util /** A common class for lightweight sets. diff --git a/tests/run/TupleAbstract.check b/tests/run/TupleAbstract.check new file mode 100644 index 000000000000..6957f0548302 --- /dev/null +++ b/tests/run/TupleAbstract.check @@ -0,0 +1,34 @@ +() +(1) +(A,1) +(2,A,1) +(B,2,A,1) +(3,B,2,A,1) +(C,3,B,2,A,1) +(4,C,3,B,2,A,1) +(D,4,C,3,B,2,A,1) +h1 = 1 +h2 = A +h7 = 4 +h8 = D +t1 = () +t2 = (1) +t7 = (C,3,B,2,A,1) +t8 = (4,C,3,B,2,A,1) +a1_0 = 1 +a2_0 = A +a3_1 = A +a4_3 = 1 +a6_4 = A +a8_0 = D +c0_0 = () +c0_1 = (1) +c1_0 = (1) +c0_4 = (B,2,A,1) +c4_0 = (B,2,A,1) +c1_1 = (1,1) +c1_8 = (1,D,4,C,3,B,2,A,1) +c2_1 = (A,1,1) +c2_2 = (A,1,A,1) +c2_3 = (A,1,2,A,1) +c3_3 = (2,A,1,2,A,1) diff --git a/tests/run/TupleAbstract.scala b/tests/run/TupleAbstract.scala new file mode 100644 index 000000000000..1d7b01912f53 --- /dev/null +++ b/tests/run/TupleAbstract.scala @@ -0,0 +1,299 @@ +package test { + +import annotation.showAsInfix + +class TypeLevel { + type Tuple + + type Empty <: Tuple + // in the actual implementation, pick scala.Unit, and have it extend `Tuple`. + + @showAsInfix type *:[+H, +T <: Tuple] <: Tuple + + erased def erasedValue[T]: T = ??? + case class Typed[T](val value: T) { type Type = T } +} + +class TupleXXL private (es: Array[Object]) { + override def toString = elems.mkString("(", ",", ")") + override def hashCode = getClass.hashCode * 41 + elems.deep.hashCode + override def equals(that: Any) = that match { + case that: TupleXXL => this.elems.deep.equals(that.elems.deep) + case _ => false + } + def elems: Array[Object] = es +} +object TupleXXL { + def apply(elems: Array[Object]) = new TupleXXL(elems.clone) +} + +object Tuples { + val typelevel = new TypeLevel + import typelevel._ + + def unit = ().asInstanceOf[Empty] + + private final val MaxSpecialized = 7 // 22 in real life + + private transparent def _empty: Tuple = erasedValue[Empty] + private transparent def _pair[H, T <: Tuple] (x: H, xs: T): Tuple = erasedValue[H *: T] + + private transparent def _size(xs: Tuple): Int = xs match { + case _: Empty => 0 + case _: (_ *: xs1) => _size(erasedValue[xs1]) + 1 + } + + private transparent def _index(xs: Tuple, n: Int): Any = xs match { + case _: (x *: _) if n == 0 => erasedValue[x] + case _: (_ *: xs1) if n > 0 => _index(erasedValue[xs1], n - 1) + } + + private transparent def _head(xs: Tuple): Any = xs match { + case _: (x *: _) => erasedValue[x] + } + + private transparent def _tail(xs: Tuple): Tuple = xs match { + case _: (_ *: xs1) => erasedValue[xs1] + } + + private transparent def _concat(xs: Tuple, ys: Tuple): Tuple = xs match { + case _: Empty => ys + case _: (x1 *: xs1) => _pair(erasedValue[x1], _concat(erasedValue[xs1], ys)) + } + + transparent def fromArray[T <: Tuple](xs: Array[Object]): T = + _size(erasedValue[T]) match { + case 0 => ().asInstanceOf[T] + case 1 => Tuple1(xs(0)).asInstanceOf[T] + case 2 => Tuple2(xs(0), xs(1)).asInstanceOf[T] + case 3 => Tuple3(xs(0), xs(1), xs(2)).asInstanceOf[T] + case 4 => Tuple4(xs(0), xs(1), xs(2), xs(3)).asInstanceOf[T] + case 5 => Tuple5(xs(0), xs(1), xs(2), xs(3), xs(4)).asInstanceOf[T] + case 6 => Tuple6(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5)).asInstanceOf[T] + case 7 => Tuple7(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6)).asInstanceOf[T] + case _ => TupleXXL(xs).asInstanceOf[T] + } + + val emptyArray = Array[Object]() + + transparent implicit def tupleDeco(xs: Tuple): TupleOps = new TupleOps(xs) + + class TupleOps(val xs: Tuple) extends AnyVal { + + transparent def toArray: Array[Object] = _size(xs) match { + case 0 => + emptyArray + case 1 => + val t = xs.asInstanceOf[Tuple1[Object]] + Array(t._1) + case 2 => + val t = xs.asInstanceOf[Tuple2[Object, Object]] + Array(t._1, t._2) + case 3 => + val t = xs.asInstanceOf[Tuple3[Object, Object, Object]] + Array(t._1, t._2, t._3) + case 4 => + val t = xs.asInstanceOf[Tuple4[Object, Object, Object, Object]] + Array(t._1, t._2, t._3, t._4) + case 5 => + val t = xs.asInstanceOf[Tuple5[Object, Object, Object, Object, Object]] + Array(t._1, t._2, t._3, t._4, t._5) + case 6 => + val t = xs.asInstanceOf[Tuple6[Object, Object, Object, Object, Object, Object]] + Array(t._1, t._2, t._3, t._4, t._5, t._6) + case 7 => + val t = xs.asInstanceOf[Tuple7[Object, Object, Object, Object, Object, Object, Object]] + Array(t._1, t._2, t._3, t._4, t._5, t._6, t._7) + case _ => + xs.asInstanceOf[TupleXXL].elems + } + + transparent def *: [H] (x: H): Tuple = { + erased val resTpe = Typed(_pair(x, xs)) + _size(xs) match { + case 0 => + Tuple1(x).asInstanceOf[resTpe.Type] + case 1 => + Tuple2(x, xs.asInstanceOf[Tuple1[_]]._1).asInstanceOf[resTpe.Type] + case 2 => + val t = xs.asInstanceOf[Tuple2[_, _]] + Tuple3(x, t._1, t._2).asInstanceOf[resTpe.Type] + case 3 => + val t = xs.asInstanceOf[Tuple3[_, _, _]] + Tuple4(x, t._1, t._2, t._3).asInstanceOf[resTpe.Type] + case 4 => + val t = xs.asInstanceOf[Tuple4[_, _, _, _]] + Tuple5(x, t._1, t._2, t._3, t._4).asInstanceOf[resTpe.Type] + case n => + fromArray[resTpe.Type](prepend(x, toArray)) + } + } + + private def prepend[H](x: H, elems: Array[Object]): Array[Object] = { + val elems1 = new Array[Object](elems.length + 1) + elems1(0) = x.asInstanceOf[Object] + Array.copy(elems, 0, elems1, 1, elems.length) + elems1 + } + + transparent def head: Any = { + erased val resTpe = Typed(_head(xs)) + _size(xs) match { + case 1 => + val t = xs.asInstanceOf[Tuple1[_]] + t._1.asInstanceOf[resTpe.Type] + case 2 => + val t = xs.asInstanceOf[Tuple2[_, _]] + t._1.asInstanceOf[resTpe.Type] + case 3 => + val t = xs.asInstanceOf[Tuple3[_, _, _]] + t._1.asInstanceOf[resTpe.Type] + case 4 => + val t = xs.asInstanceOf[Tuple4[_, _, _, _]] + t._1.asInstanceOf[resTpe.Type] + case n if n > 4 && n <= MaxSpecialized => + xs.asInstanceOf[Product].productElement(0).asInstanceOf[resTpe.Type] + case n if n > MaxSpecialized => + val t = xs.asInstanceOf[TupleXXL] + t.elems(0).asInstanceOf[resTpe.Type] + } + } + + transparent def tail: Any = { + erased val resTpe = Typed(_tail(xs)) + _size(xs) match { + case 1 => + unit + case 2 => + val t = xs.asInstanceOf[Tuple2[_, _]] + Tuple1(t._2).asInstanceOf[resTpe.Type] + case 3 => + val t = xs.asInstanceOf[Tuple3[_, _, _]] + Tuple2(t._2, t._3).asInstanceOf[resTpe.Type] + case 4 => + val t = xs.asInstanceOf[Tuple4[_, _, _, _]] + Tuple3(t._2, t._3, t._4).asInstanceOf[resTpe.Type] + case 5 => + val t = xs.asInstanceOf[Tuple5[_, _, _, _, _]] + Tuple4(t._2, t._3, t._4, t._5).asInstanceOf[resTpe.Type] + case n if n > 5 => + fromArray[resTpe.Type](toArray.tail) + } + } + + transparent def apply(n: Int): Any = { + erased val resTpe = Typed(_index(xs, n)) + _size(xs) match { + case 1 => + val t = xs.asInstanceOf[Tuple1[_]] + n match { + case 0 => t._1.asInstanceOf[resTpe.Type] + } + case 2 => + val t = xs.asInstanceOf[Tuple2[_, _]] + n match { + case 0 => t._1.asInstanceOf[resTpe.Type] + case 1 => t._2.asInstanceOf[resTpe.Type] + } + case 3 => + val t = xs.asInstanceOf[Tuple3[_, _, _]] + n match { + case 0 => t._1.asInstanceOf[resTpe.Type] + case 1 => t._2.asInstanceOf[resTpe.Type] + case 2 => t._3.asInstanceOf[resTpe.Type] + } + case 4 => + val t = xs.asInstanceOf[Tuple4[_, _, _, _]] + n match { + case 0 => t._1.asInstanceOf[resTpe.Type] + case 1 => t._2.asInstanceOf[resTpe.Type] + case 2 => t._3.asInstanceOf[resTpe.Type] + case 3 => t._4.asInstanceOf[resTpe.Type] + } + case s if s > 4 && s <= MaxSpecialized && n >= 0 && n < s => + xs.asInstanceOf[Product].productElement(n).asInstanceOf[resTpe.Type] + case s if s > MaxSpecialized && n >= 0 && n < s => + xs.asInstanceOf[TupleXXL].elems(n).asInstanceOf[resTpe.Type] + } + } + + transparent def ++(ys: Tuple): Tuple = { + erased val resTpe = Typed(_concat(xs, ys)) + _size(xs) match { + case 0 => ys + case 1 => + if (_size(ys) == 0) xs + else xs.head *: ys + case 2 => + val t = xs.asInstanceOf[Tuple2[_, _]] + _size(ys) match { + case 0 => xs + case 1 => + val u = ys.asInstanceOf[Tuple1[_]] + Tuple3(t._1, t._2, u._1).asInstanceOf[resTpe.Type] + case 2 => + val u = ys.asInstanceOf[Tuple2[_, _]] + Tuple4(t._1, t._2, u._1, u._2).asInstanceOf[resTpe.Type] + case _ => + genericConcat[resTpe.Type](xs, ys) + } + case 3 => + val t = xs.asInstanceOf[Tuple3[_, _, _]] + _size(ys) match { + case 0 => xs + case 1 => + val u = ys.asInstanceOf[Tuple1[_]] + Tuple4(t._1, t._2, t._3, u._1).asInstanceOf[resTpe.Type] + case _ => + genericConcat[resTpe.Type](xs, ys) + } + case _ => + if (_size(ys) == 0) xs + else genericConcat[resTpe.Type](xs, ys) + } + } + + transparent def genericConcat[T <: Tuple](xs: Tuple, ys: Tuple): Tuple = + fromArray[T](xs.toArray ++ ys.toArray) + } +} +} +object Test extends App { + import test._ + import Tuples._ + import typelevel._ + val x0 = unit; println(x0) + val x1 = 1 *: x0; println(x1) + val x2 = "A" *: x1; println(x2) + val x3 = 2 *: x2; println(x3) + val x4 = "B" *: x3; println(x4) + val x5 = 3 *: x4; println(x5) + val x6 = "C" *: x5; println(x6) + val x7 = 4 *: x6; println(x7) + val x8 = "D" *: x7; println(x8) + val h1 = x1.head; val h1c: Int = h1; println(s"h1 = $h1") + val h2 = x2.head; val h2c: String = h2; println(s"h2 = $h2") + val h7 = x7.head; val h7c: Int = h7; println(s"h7 = $h7") + val h8 = x8.head; val h8c: String = h8; println(s"h8 = $h8") + val t1 = x1.tail; val t1c: Empty = t1; println(s"t1 = $t1") + val t2 = x2.tail; val t2c: Int *: Empty = t2; println(s"t2 = $t2") + val t7 = x7.tail; val t7c: String *: Int *: Empty = t7.tail.tail.tail.tail; println(s"t7 = $t7") + val t8 = x8.tail; val t8c: Int = t8(6); println(s"t8 = $t8") + val a1_0 = x1(0); val a1_0c: Int = a1_0; println(s"a1_0 = $a1_0") + val a2_0 = x2(0); val a2_0c: String = a2_0; println(s"a2_0 = $a2_0") + val a3_1 = x3(1); val a3_1c: String = a3_1; println(s"a3_1 = $a3_1") + val a4_3 = x4(3); val a4_3c: Int = a4_3; println(s"a4_3 = $a4_3") + val a6_4 = x6(4); val a6_4c: String = a6_4; println(s"a6_4 = $a6_4") + val a8_0 = x8(0); val a8_0c: String = a8_0; println(s"a8_0 = $a8_0") + val c0_0 = x0 ++ x0; val c0_0c: Empty = c0_0; println(s"c0_0 = $c0_0") + val c0_1 = x0 ++ x1; val c0_1c: Int *: Empty = c0_1c; println(s"c0_1 = $c0_1") + val c1_0 = x1 ++ x0; val c1_0c: Int *: Empty = c1_0c; println(s"c1_0 = $c1_0") + val c0_4 = x0 ++ x4; val c0_4c: String *: Int *: String *: Int *: Empty = c0_4; println(s"c0_4 = $c0_4") + val c4_0 = x4 ++ x0; val c4_0c: String *: Int *: String *: Int *: Empty = c4_0; println(s"c4_0 = $c4_0") + val c1_1 = x1 ++ x1; val c1_1c: Int *: Int *: Empty = c1_1; println(s"c1_1 = $c1_1") + val c1_8 = x1 ++ x8; val c1_8c: Int *: String *: Int *: String *: Int *: String *: Int *: String *: Int *: Empty = c1_8; println(s"c1_8 = $c1_8") + val c2_1 = x2 ++ x1; val c2_1c: String *: Int *: Int *: Empty = c2_1; println(s"c2_1 = $c2_1") + val c2_2 = x2 ++ x2; val c2_2c: String *: Int *: String *: Int *: Empty = c2_2; println(s"c2_2 = $c2_2") + val c2_3 = x2 ++ x3; val c2_3c: String *: Int *: Int *: String *: Int *: Empty = c2_3; println(s"c2_3 = $c2_3") + val c3_3 = x3 ++ x3; val c3_3c: Int *: String *: Int *: Int *: String *: Int *: Empty = c3_3; println(s"c3_3 = $c3_3") +} diff --git a/tests/run/tasty-extractors-1.check b/tests/run/tasty-extractors-1.check index 1d44a67395da..61b5cc647af5 100644 --- a/tests/run/tasty-extractors-1.check +++ b/tests/run/tasty-extractors-1.check @@ -37,40 +37,40 @@ Type.ConstantType(Constant.Int(3)) Term.Inlined(None, Nil, Term.If(Term.Typed(Term.Literal(Constant.Boolean(true)), TypeTree.TypeIdent("Boolean")), Term.Literal(Constant.Int(1)), Term.Literal(Constant.Int(2)))) Type.SymRef(ClassDef("Int", _, _, _, _), Type.ThisType(Type.SymRef(PackageDef("scala", _), NoPrefix()))) -Term.Inlined(None, Nil, Term.Match(Term.Literal(Constant.String("a")), List(CaseDef(Pattern.Value(Term.Literal(Constant.String("a"))), None, Term.Block(Nil, Term.Literal(Constant.Unit())))))) +Term.Inlined(None, Nil, Term.Match(Term.Literal(Constant.String("a")), List(CaseDef(Pattern.Value(Term.Literal(Constant.String("a"))), None, Term.Literal(Constant.Unit()))))) Type.SymRef(ClassDef("Unit", _, _, _, _), Type.ThisType(Type.SymRef(PackageDef("scala", _), NoPrefix()))) -Term.Inlined(None, Nil, Term.Match(Term.Literal(Constant.String("b")), List(CaseDef(Pattern.Bind("n", Pattern.Value(Term.Ident("_"))), None, Term.Block(Nil, Term.Literal(Constant.Unit())))))) +Term.Inlined(None, Nil, Term.Match(Term.Literal(Constant.String("b")), List(CaseDef(Pattern.Bind("n", Pattern.Value(Term.Ident("_"))), None, Term.Literal(Constant.Unit()))))) Type.SymRef(ClassDef("Unit", _, _, _, _), Type.ThisType(Type.SymRef(PackageDef("scala", _), NoPrefix()))) -Term.Inlined(None, Nil, Term.Match(Term.Literal(Constant.String("c")), List(CaseDef(Pattern.Bind("n", Pattern.TypeTest(TypeTree.TypeIdent("String"))), None, Term.Block(Nil, Term.Literal(Constant.Unit())))))) +Term.Inlined(None, Nil, Term.Match(Term.Literal(Constant.String("c")), List(CaseDef(Pattern.Bind("n", Pattern.TypeTest(TypeTree.TypeIdent("String"))), None, Term.Literal(Constant.Unit()))))) Type.SymRef(ClassDef("Unit", _, _, _, _), Type.ThisType(Type.SymRef(PackageDef("scala", _), NoPrefix()))) -Term.Inlined(None, Nil, Term.Match(Term.Literal(Constant.String("e")), List(CaseDef(Pattern.Value(Term.Ident("_")), None, Term.Block(Nil, Term.Literal(Constant.Unit())))))) +Term.Inlined(None, Nil, Term.Match(Term.Literal(Constant.String("e")), List(CaseDef(Pattern.Value(Term.Ident("_")), None, Term.Literal(Constant.Unit()))))) Type.SymRef(ClassDef("Unit", _, _, _, _), Type.ThisType(Type.SymRef(PackageDef("scala", _), NoPrefix()))) -Term.Inlined(None, Nil, Term.Match(Term.Literal(Constant.String("f")), List(CaseDef(Pattern.TypeTest(TypeTree.TypeIdent("String")), None, Term.Block(Nil, Term.Literal(Constant.Unit())))))) +Term.Inlined(None, Nil, Term.Match(Term.Literal(Constant.String("f")), List(CaseDef(Pattern.TypeTest(TypeTree.TypeIdent("String")), None, Term.Literal(Constant.Unit()))))) Type.SymRef(ClassDef("Unit", _, _, _, _), Type.ThisType(Type.SymRef(PackageDef("scala", _), NoPrefix()))) -Term.Inlined(None, Nil, Term.Match(Term.Typed(Term.Literal(Constant.String("g")), TypeTree.TypeIdent("Any")), List(CaseDef(Pattern.Alternative(List(Pattern.TypeTest(TypeTree.TypeIdent("String")), Pattern.TypeTest(TypeTree.TypeIdent("Int")))), None, Term.Block(Nil, Term.Literal(Constant.Unit())))))) +Term.Inlined(None, Nil, Term.Match(Term.Typed(Term.Literal(Constant.String("g")), TypeTree.TypeIdent("Any")), List(CaseDef(Pattern.Alternative(List(Pattern.TypeTest(TypeTree.TypeIdent("String")), Pattern.TypeTest(TypeTree.TypeIdent("Int")))), None, Term.Literal(Constant.Unit()))))) Type.SymRef(ClassDef("Unit", _, _, _, _), Type.ThisType(Type.SymRef(PackageDef("scala", _), NoPrefix()))) -Term.Inlined(None, Nil, Term.Match(Term.Literal(Constant.String("h")), List(CaseDef(Pattern.Value(Term.Ident("_")), Some(Term.Literal(Constant.Boolean(false))), Term.Block(Nil, Term.Literal(Constant.Unit())))))) +Term.Inlined(None, Nil, Term.Match(Term.Literal(Constant.String("h")), List(CaseDef(Pattern.Value(Term.Ident("_")), Some(Term.Literal(Constant.Boolean(false))), Term.Literal(Constant.Unit()))))) Type.SymRef(ClassDef("Unit", _, _, _, _), Type.ThisType(Type.SymRef(PackageDef("scala", _), NoPrefix()))) -Term.Inlined(None, Nil, Term.Block(List(ValDef("a", TypeTree.Synthetic(), Some(Term.Literal(Constant.String("o"))))), Term.Match(Term.Literal(Constant.String("i")), List(CaseDef(Pattern.Bind("a", Pattern.Value(Term.Ident("_"))), None, Term.Block(Nil, Term.Literal(Constant.Unit()))))))) +Term.Inlined(None, Nil, Term.Block(List(ValDef("a", TypeTree.Synthetic(), Some(Term.Literal(Constant.String("o"))))), Term.Match(Term.Literal(Constant.String("i")), List(CaseDef(Pattern.Bind("a", Pattern.Value(Term.Ident("_"))), None, Term.Literal(Constant.Unit())))))) Type.SymRef(ClassDef("Unit", _, _, _, _), Type.ThisType(Type.SymRef(PackageDef("scala", _), NoPrefix()))) -Term.Inlined(None, Nil, Term.Match(Term.Ident("Nil"), List(CaseDef(Pattern.Unapply(Term.TypeApply(Term.Select(Term.Ident("List"), "unapplySeq", Some(Signature(List(scala.collection.Seq), scala.Some))), List(TypeTree.Synthetic())), Nil, List(Pattern.Bind("a", Pattern.Value(Term.Ident("_"))), Pattern.Bind("b", Pattern.Value(Term.Ident("_"))), Pattern.Bind("c", Pattern.Value(Term.Ident("_"))))), None, Term.Block(Nil, Term.Literal(Constant.Unit())))))) +Term.Inlined(None, Nil, Term.Match(Term.Ident("Nil"), List(CaseDef(Pattern.Unapply(Term.TypeApply(Term.Select(Term.Ident("List"), "unapplySeq", Some(Signature(List(scala.collection.Seq), scala.Some))), List(TypeTree.Synthetic())), Nil, List(Pattern.Bind("a", Pattern.Value(Term.Ident("_"))), Pattern.Bind("b", Pattern.Value(Term.Ident("_"))), Pattern.Bind("c", Pattern.Value(Term.Ident("_"))))), None, Term.Literal(Constant.Unit()))))) Type.SymRef(ClassDef("Unit", _, _, _, _), Type.ThisType(Type.SymRef(PackageDef("scala", _), NoPrefix()))) -Term.Inlined(None, Nil, Term.Try(Term.Literal(Constant.Int(1)), List(CaseDef(Pattern.Value(Term.Ident("_")), None, Term.Block(Nil, Term.Literal(Constant.Unit())))), None)) +Term.Inlined(None, Nil, Term.Try(Term.Literal(Constant.Int(1)), List(CaseDef(Pattern.Value(Term.Ident("_")), None, Term.Literal(Constant.Unit()))), None)) Type.OrType(Type.SymRef(ClassDef("Int", _, _, _, _), Type.ThisType(Type.SymRef(PackageDef("scala", _), NoPrefix()))), Type.SymRef(ClassDef("Unit", _, _, _, _), Type.ThisType(Type.SymRef(PackageDef("scala", _), NoPrefix())))) Term.Inlined(None, Nil, Term.Try(Term.Literal(Constant.Int(2)), Nil, Some(Term.Literal(Constant.Unit())))) Type.ConstantType(Constant.Int(2)) -Term.Inlined(None, Nil, Term.Try(Term.Literal(Constant.Int(3)), List(CaseDef(Pattern.Value(Term.Ident("_")), None, Term.Block(Nil, Term.Literal(Constant.Unit())))), Some(Term.Literal(Constant.Unit())))) +Term.Inlined(None, Nil, Term.Try(Term.Literal(Constant.Int(3)), List(CaseDef(Pattern.Value(Term.Ident("_")), None, Term.Literal(Constant.Unit()))), Some(Term.Literal(Constant.Unit())))) Type.OrType(Type.SymRef(ClassDef("Int", _, _, _, _), Type.ThisType(Type.SymRef(PackageDef("scala", _), NoPrefix()))), Type.SymRef(ClassDef("Unit", _, _, _, _), Type.ThisType(Type.SymRef(PackageDef("scala", _), NoPrefix())))) Term.Inlined(None, Nil, Term.Apply(Term.Select(Term.Literal(Constant.String("a")), "==", Some(Signature(List(java.lang.Object), scala.Boolean))), List(Term.Literal(Constant.String("b")))))