blob: 670d6f49aa00ad67d569c3fd3aaeec42a20f712e (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
scala> class Annot(obj: Any) extends annotation.Annotation with annotation.TypeConstraint
defined class Annot
scala>
scala> class A {
val x = "hello"
val y: Int @Annot(x) = 10
override def toString = "an A"
}
defined class A
scala>
scala> val a = new A
a: A = an A
scala> val y = a.y // should rewrite "this.x" to "a.x"
y: Int @Annot(a.x) = 10
scala> var a2 = new A
a2: A = an A
scala> val y2 = a2.y // should drop the annotation
y2: Int = 10
scala>
scala> object Stuff {
val x = "hello"
val y : Int @Annot(x) = 10
}
defined object Stuff
scala>
scala> val y = Stuff.y // should rewrite the annotation
y: Int @Annot(Stuff.x) = 10
scala>
scala> class B {
val y: Int @Annot(Stuff.x) = 10
override def toString = "a B"
}
defined class B
scala>
scala> val b = new B
b: B = a B
scala> val y = b.y // should keep the annotation
y: Int @Annot(Stuff.x) = 10
scala> def m(x: String): String @Annot(x) = x
m: (x: String)String @Annot(x)
scala>
scala> val three = "three"
three: String = three
scala> val three2 = m(three:three.type) // should change x to three
three2: String @Annot(three) = three
scala> var four = "four"
four: String = four
scala> val four2 = m(four) // should have an existential bound
warning: there was one feature warning; re-run with -feature for details
four2: String @Annot(x) forSome { val x: String } = four
scala> val four3 = four2 // should have the same type as four2
warning: there was one feature warning; re-run with -feature for details
four3: String @Annot(x) forSome { val x: String } = four
scala> val stuff = m("stuff") // should not crash
stuff: String @Annot("stuff") = stuff
scala>
scala> class peer extends annotation.Annotation // should not crash
defined class peer
scala>
scala> class NPE[T <: NPE[T] @peer] // should not crash
defined class NPE
scala>
scala> def m = {
val x = "three"
val y : String @Annot(x) = x
y
} // x should not escape the local scope with a narrow type
warning: there was one feature warning; re-run with -feature for details
m: String @Annot(x) forSome { val x: String }
scala>
scala> def n(y: String) = {
def m(x: String) : String @Annot(x) = {
(if (x == "")
m("default")
else
x)
}
m("stuff".stripMargin)
} // x should be existentially bound
warning: there was one feature warning; re-run with -feature for details
n: (y: String)String @Annot(x) forSome { val x: String }
scala>
scala> class rep extends annotation.Annotation { }
defined class rep
scala>
scala> object A { val x = "hello" : String @ rep }
defined object A
warning: previously defined class A is not a companion to object A.
Companions must be defined together; you may wish to use :paste mode for this.
scala>
scala> val y = a.x // should drop the annotation
y: String = hello
scala>
scala> val x = 3 : Int @Annot(e+f+g+h) // should have a graceful error message
<console>:11: error: not found: value e
val x = 3 : Int @Annot(e+f+g+h) // should have a graceful error message
^
<console>:11: error: not found: value f
val x = 3 : Int @Annot(e+f+g+h) // should have a graceful error message
^
<console>:11: error: not found: value g
val x = 3 : Int @Annot(e+f+g+h) // should have a graceful error message
^
<console>:11: error: not found: value h
val x = 3 : Int @Annot(e+f+g+h) // should have a graceful error message
^
scala> :quit
|