Skip to content

Commit 103237e

Browse files
committed
Transparent methods don't need inline accessors
... since they are inlined themselves. Also, fleshed out tuple PoC.
1 parent 0aa2e00 commit 103237e

File tree

3 files changed

+96
-53
lines changed

3 files changed

+96
-53
lines changed

compiler/src/dotty/tools/dotc/typer/PrepareTransparent.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,14 @@ object PrepareTransparent {
7676
* by excluding all symbols properly contained in the inlined method.
7777
*
7878
* Constant vals don't need accessors since they are inlined in FirstTransform.
79+
* Transparent methods don't need accessors since they are inlined in Typer.
7980
*/
8081
def needsAccessor(sym: Symbol)(implicit ctx: Context) =
8182
sym.isTerm &&
8283
(sym.is(AccessFlags) || sym.privateWithin.exists) &&
8384
!sym.isContainedIn(inlineSym) &&
84-
!(sym.isStable && sym.info.widenTermRefExpr.isInstanceOf[ConstantType])
85+
!(sym.isStable && sym.info.widenTermRefExpr.isInstanceOf[ConstantType]) &&
86+
!sym.is(TransparentMethod)
8587

8688
def preTransform(tree: Tree)(implicit ctx: Context): Tree
8789

tests/run/TupleAbstract.check

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
()
2+
(1)
3+
(A,1)
4+
(2,A,1)
5+
(B,2,A,1)
6+
(3,B,2,A,1)
7+
(C,3,B,2,A,1)
8+
(4,C,3,B,2,A,1)
9+
(D,4,C,3,B,2,A,1)
10+
h1 = 1
11+
h2 = A
12+
h7 = 4
13+
h8 = D
14+
t1 = ()
15+
t2 = (1)
16+
t7 = (C,3,B,2,A,1)
17+
t8 = (4,C,3,B,2,A,1)
18+
a1_0 = 1
19+
a2_0 = A
20+
a3_1 = A
21+
a4_3 = 1
22+
a6_4 = A
23+
a8_0 = D
24+
c0_0 = ()
25+
c0_1 = (1)
26+
c1_0 = (1)
27+
c0_4 = (B,2,A,1)
28+
c4_0 = (B,2,A,1)
29+
c1_1 = (1,1)
30+
c1_8 = (1,D,4,C,3,B,2,A,1)
31+
c2_1 = (A,1,1)
32+
c2_2 = (A,1,A,1)
33+
c2_3 = (A,1,2,A,1)
34+
c3_3 = (2,A,1,2,A,1)

tests/run/TupleAbstract.scala

Lines changed: 59 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4,56 +4,63 @@ import annotation.showAsInfix
44

55
class TypeLevel {
66
type Tuple
7+
78
type Empty <: Tuple
9+
// in the actual implementation, pick scala.Unit, and have it extend `Tuple`.
810

911
@showAsInfix type *:[+H, +T <: Tuple] <: Tuple
12+
1013
erased def erasedValue[T]: T = ???
1114
case class Typed[T](val value: T) { type Type = T }
1215
}
1316

14-
class TupleXXL(val elems: Array[Object])
17+
class TupleXXL private (es: Array[Object]) {
18+
override def toString = elems.mkString("(", ",", ")")
19+
override def hashCode = getClass.hashCode * 41 + elems.deep.hashCode
20+
override def equals(that: Any) = that match {
21+
case that: TupleXXL => this.elems.deep.equals(that.elems.deep)
22+
case _ => false
23+
}
24+
def elems: Array[Object] = es
25+
}
26+
object TupleXXL {
27+
def apply(elems: Array[Object]) = new TupleXXL(elems.clone)
28+
}
1529

1630
object Tuples {
1731
val typelevel = new TypeLevel
1832
import typelevel._
1933

20-
final val MaxSpecialized = 7 // 22 in real life
34+
def unit = ().asInstanceOf[Empty]
2135

22-
transparent def _empty: Tuple = erasedValue[Empty]
23-
transparent def _pair[H, T <: Tuple] (x: H, xs: T): Tuple = erasedValue[H *: T]
36+
private final val MaxSpecialized = 7 // 22 in real life
2437

25-
def unit = ().asInstanceOf[Empty]
38+
private transparent def _empty: Tuple = erasedValue[Empty]
39+
private transparent def _pair[H, T <: Tuple] (x: H, xs: T): Tuple = erasedValue[H *: T]
2640

27-
transparent def _size(xs: Tuple): Int = xs match {
41+
private transparent def _size(xs: Tuple): Int = xs match {
2842
case _: Empty => 0
2943
case _: (_ *: xs1) => _size(erasedValue[xs1]) + 1
3044
}
3145

32-
erased val xs2 = erasedValue[Int *: String *: Empty]
33-
34-
erased val s = _size(xs2)
35-
36-
transparent def _index(xs: Tuple, n: Int): Any = xs match {
46+
private transparent def _index(xs: Tuple, n: Int): Any = xs match {
3747
case _: (x *: _) if n == 0 => erasedValue[x]
3848
case _: (_ *: xs1) if n > 0 => _index(erasedValue[xs1], n - 1)
3949
}
4050

41-
transparent def _head(xs: Tuple): Any = xs match {
51+
private transparent def _head(xs: Tuple): Any = xs match {
4252
case _: (x *: _) => erasedValue[x]
4353
}
4454

45-
transparent def _tail(xs: Tuple): Tuple = xs match {
55+
private transparent def _tail(xs: Tuple): Tuple = xs match {
4656
case _: (_ *: xs1) => erasedValue[xs1]
4757
}
4858

49-
transparent def _concat(xs: Tuple, ys: Tuple): Tuple = xs match {
59+
private transparent def _concat(xs: Tuple, ys: Tuple): Tuple = xs match {
5060
case _: Empty => ys
5161
case _: (x1 *: xs1) => _pair(erasedValue[x1], _concat(erasedValue[xs1], ys))
5262
}
5363

54-
erased val e0 = _index(xs2, 0)
55-
erased val e1 = _index(xs2, 1)
56-
5764
transparent def fromArray[T <: Tuple](xs: Array[Object]): T =
5865
_size(erasedValue[T]) match {
5966
case 0 => ().asInstanceOf[T]
@@ -64,7 +71,7 @@ object Tuples {
6471
case 5 => Tuple5(xs(0), xs(1), xs(2), xs(3), xs(4)).asInstanceOf[T]
6572
case 6 => Tuple6(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5)).asInstanceOf[T]
6673
case 7 => Tuple7(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6)).asInstanceOf[T]
67-
case _ => new TupleXXL(xs).asInstanceOf[T]
74+
case _ => TupleXXL(xs).asInstanceOf[T]
6875
}
6976

7077
val emptyArray = Array[Object]()
@@ -255,38 +262,38 @@ object Test extends App {
255262
import test._
256263
import Tuples._
257264
import typelevel._
258-
val x0 = unit
259-
val x1 = 1 *: x0
260-
val x2 = "A" *: x1
261-
val x3 = 2 *: x2
262-
val x4 = "B" *: x3
263-
val x5 = 3 *: x4
264-
val x6 = "C" *: x5
265-
val x7 = 4 *: x6
266-
val x8 = "D" *: x7
267-
val h1 = x1.head; val h1c: Int = h1
268-
val h2 = x2.head; val h2c: String = h2
269-
val h7 = x7.head; val h7c: Int = h7
270-
val h8 = x8.head; val h8c: String = h8
271-
val t1 = x1.tail; val t1c: Empty = t1
272-
val t2 = x2.tail; val t2c: Int *: Empty = t2
273-
val t7 = x7.tail; val t7c: String *: Int *: Empty = t7.tail.tail.tail.tail
274-
val t8 = x8.tail; val t8c: Int = t8(6)
275-
val a1_0 = x1(0); val a1_0c: Int = a1_0
276-
val a2_0 = x2(0); val a2_0c: String = a2_0
277-
val a3_1 = x3(1); val a3_1c: String = a3_1
278-
val a4_3 = x4(3); val a4_3c: Int = a4_3
279-
val a6_4 = x6(4); val a6_4c: String = a6_4
280-
val a8_0 = x8(0); val a8_0c: String = a8_0
281-
val c0_0 = x0 ++ x0; val c0_0c: Empty = c0_0
282-
val c0_1 = x0 ++ x1; val c0_1c: Int *: Empty = c0_1c
283-
val c1_0 = x1 ++ x0; val c1_0c: Int *: Empty = c1_0c
284-
val c0_4 = x0 ++ x4; val c0_4c: String *: Int *: String *: Int *: Empty = c0_4
285-
val c4_0 = x4 ++ x0; val c4_0c: String *: Int *: String *: Int *: Empty = c4_0
286-
val c1_1 = x1 ++ x1; val c1_1c: Int *: Int *: Empty = c1_1
287-
val c1_8 = x1 ++ x8; val c1_8c: Int *: String *: Int *: String *: Int *: String *: Int *: String *: Int *: Empty = c1_8
288-
val c2_1 = x2 ++ x1; val c2_1c: String *: Int *: Int *: Empty = c2_1
289-
val c2_2 = x2 ++ x2; val c2_2c: String *: Int *: String *: Int *: Empty = c2_2
290-
val c2_3 = x2 ++ x3; val c2_3c: String *: Int *: Int *: String *: Int *: Empty = c2_3
291-
val c3_3 = x3 ++ x3; val c3_3c: Int *: String *: Int *: Int *: String *: Int *: Empty = c3_3
265+
val x0 = unit; println(x0)
266+
val x1 = 1 *: x0; println(x1)
267+
val x2 = "A" *: x1; println(x2)
268+
val x3 = 2 *: x2; println(x3)
269+
val x4 = "B" *: x3; println(x4)
270+
val x5 = 3 *: x4; println(x5)
271+
val x6 = "C" *: x5; println(x6)
272+
val x7 = 4 *: x6; println(x7)
273+
val x8 = "D" *: x7; println(x8)
274+
val h1 = x1.head; val h1c: Int = h1; println(s"h1 = $h1")
275+
val h2 = x2.head; val h2c: String = h2; println(s"h2 = $h2")
276+
val h7 = x7.head; val h7c: Int = h7; println(s"h7 = $h7")
277+
val h8 = x8.head; val h8c: String = h8; println(s"h8 = $h8")
278+
val t1 = x1.tail; val t1c: Empty = t1; println(s"t1 = $t1")
279+
val t2 = x2.tail; val t2c: Int *: Empty = t2; println(s"t2 = $t2")
280+
val t7 = x7.tail; val t7c: String *: Int *: Empty = t7.tail.tail.tail.tail; println(s"t7 = $t7")
281+
val t8 = x8.tail; val t8c: Int = t8(6); println(s"t8 = $t8")
282+
val a1_0 = x1(0); val a1_0c: Int = a1_0; println(s"a1_0 = $a1_0")
283+
val a2_0 = x2(0); val a2_0c: String = a2_0; println(s"a2_0 = $a2_0")
284+
val a3_1 = x3(1); val a3_1c: String = a3_1; println(s"a3_1 = $a3_1")
285+
val a4_3 = x4(3); val a4_3c: Int = a4_3; println(s"a4_3 = $a4_3")
286+
val a6_4 = x6(4); val a6_4c: String = a6_4; println(s"a6_4 = $a6_4")
287+
val a8_0 = x8(0); val a8_0c: String = a8_0; println(s"a8_0 = $a8_0")
288+
val c0_0 = x0 ++ x0; val c0_0c: Empty = c0_0; println(s"c0_0 = $c0_0")
289+
val c0_1 = x0 ++ x1; val c0_1c: Int *: Empty = c0_1c; println(s"c0_1 = $c0_1")
290+
val c1_0 = x1 ++ x0; val c1_0c: Int *: Empty = c1_0c; println(s"c1_0 = $c1_0")
291+
val c0_4 = x0 ++ x4; val c0_4c: String *: Int *: String *: Int *: Empty = c0_4; println(s"c0_4 = $c0_4")
292+
val c4_0 = x4 ++ x0; val c4_0c: String *: Int *: String *: Int *: Empty = c4_0; println(s"c4_0 = $c4_0")
293+
val c1_1 = x1 ++ x1; val c1_1c: Int *: Int *: Empty = c1_1; println(s"c1_1 = $c1_1")
294+
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")
295+
val c2_1 = x2 ++ x1; val c2_1c: String *: Int *: Int *: Empty = c2_1; println(s"c2_1 = $c2_1")
296+
val c2_2 = x2 ++ x2; val c2_2c: String *: Int *: String *: Int *: Empty = c2_2; println(s"c2_2 = $c2_2")
297+
val c2_3 = x2 ++ x3; val c2_3c: String *: Int *: Int *: String *: Int *: Empty = c2_3; println(s"c2_3 = $c2_3")
298+
val c3_3 = x3 ++ x3; val c3_3c: Int *: String *: Int *: Int *: String *: Int *: Empty = c3_3; println(s"c3_3 = $c3_3")
292299
}

0 commit comments

Comments
 (0)