Skip to content

Commit 25d7675

Browse files
committed
Added tests for AppliedTermRefs.
1 parent 51b01ff commit 25d7675

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

tests/neg/appliedTerm.scala

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
object SimpleEqs {
2+
val x = 1
3+
val y: {x} = x
4+
implicitly[{x + 1} =:= {y}] // error
5+
implicitly[{x + 1} =:= {y + 2}] // error
6+
implicitly[{x + 1} =:= {1 + y}] // error: TypeComparer doesn't know about commutativity
7+
8+
val b = true
9+
implicitly[{b} =:= {b}]
10+
implicitly[{!b} =:= {!b}]
11+
implicitly[{!b} =:= {b}] // error
12+
}
13+
14+
15+
object Stability {
16+
def f1(x: Int): Int = x
17+
def f2(x: Int): {x} = x
18+
19+
val x = 1
20+
implicitly[{f1(x)} =:= {x}] // error: f1 is not considered stable // error: f1's result type is not precise enough
21+
implicitly[{f1(x)} =:= {f1(x)}] // error: f1 is not considered stable // error: f1 is not considered stable
22+
implicitly[{f2(x)} =:= {x}]
23+
implicitly[{f2(x)} =:= {f2(x)}]
24+
implicitly[{f1(x)} =:= {f2(x)}] // error: f1 is not considered stable // error: f1's result type is not precise enough
25+
}

tests/pos/appliedTerm.scala

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
object SimpleEqs {
2+
val x = 1
3+
val y: {x} = x
4+
implicitly[{x + 1} =:= {y + 1}]
5+
}
6+
7+
8+
object AvoidLocalRefs {
9+
type Id[T] = T
10+
11+
val x = 1
12+
def y = { val a: {x} = x; val t: Id[{a + 1}] = a + 1; t }
13+
def z: {x + 1} = { val a: {x} = x; val t: Id[{a + 1}] = a + 1; t }
14+
15+
{ val a = 0; a + 1 }
16+
{ val a = 0; 1 + a }
17+
}
18+
19+
20+
object Bounds {
21+
@annotation.implicitNotFound(msg = "Cannot prove that ${B} holds.")
22+
sealed abstract class P[B <: Boolean](val b: B)
23+
private[this] val prop_singleton = new P[true](true) {}
24+
object P {
25+
def assume(b: Boolean): P[b.type] = prop_singleton.asInstanceOf[P[b.type]]
26+
}
27+
28+
def if_(cond: Boolean): (implicit (ev: P[cond.type]) => Unit) => Unit =
29+
thn => if (cond) thn(P.assume(cond))
30+
31+
32+
// Bounds-checked
33+
34+
def index(k: Int)(implicit ev: P[{k >= 0}]): Int = k
35+
36+
def run(i: Int) =
37+
if_(i >= 0) {
38+
index(i)
39+
}
40+
41+
42+
// Boxed value with a predicate
43+
44+
class PredBox[T, B <: Boolean](val v: T)(val p: P[B])
45+
object PredBox {
46+
def apply[T, B <: Boolean](v: T)(implicit ev: P[B]) = new PredBox[T, B](v)(ev)
47+
}
48+
49+
def run2(i: Int) =
50+
if_(i != 0) {
51+
PredBox[Int, {i != 0}](i)
52+
}
53+
}
54+
55+
56+
object ArithmeticIdentities {
57+
type SInt = Int & Singleton
58+
59+
class DecomposeHelper[V <: SInt](val v: V) {
60+
import DecomposeHelper._
61+
def asSumOf[X <: SInt, Y <: SInt](x: X, y: Y)(implicit ev: {v} =:= {x + y}): SumOf[{x}, {y}] = SumOf(x, y)(ev(v))
62+
}
63+
64+
object DecomposeHelper {
65+
/* Axioms */
66+
sealed trait Decomposition[V <: SInt]
67+
case class SumOf[X <: SInt, Y <: SInt](x: X, y: Y)(val v: {x + y}) extends Decomposition[{v}] {
68+
def commuted: SumOf[Y, X] = SumOf(y, x)(v.asInstanceOf[{y + x}])
69+
}
70+
}
71+
72+
implicit def toDecomposeHelper[V <: Int](v: V): DecomposeHelper[v.type] = new DecomposeHelper(v)
73+
74+
75+
// Let's "show" that x + 1 == 1 + x
76+
77+
val x = 123
78+
(x + 1).asSumOf(x, 1).v: {x + 1}
79+
(x + 1).asSumOf(x, 1).commuted.v: {1 + x}
80+
}
81+
82+
83+
//object ArithmeticIdentities2 {
84+
// // FIXME: Crashes during the computation of `add`'s signature (when typing the ident `add`):
85+
// def add[X<:Int, Y<:Int, Z<:Int](x: X, y: Y, z: {x + y}): z.type = z
86+
// val x = 1
87+
// add(x, x, x + x)
88+
//}

0 commit comments

Comments
 (0)