Skip to content

Commit 093e403

Browse files
committed
add tests
1 parent 4422101 commit 093e403

File tree

1 file changed

+127
-0
lines changed

1 file changed

+127
-0
lines changed

ocaml/testsuite/tests/typing-layouts/error_message_attr.ml

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,130 @@ Error: Bad layout annotation:
116116
(* CR layouts: Bug in Jane_syntax is duplicating the attrs here *)
117117

118118
(* Currently it's not possible to attach attributes to Ltyp_poly *)
119+
120+
(* *************************************************************** *)
121+
(* Tests for [@error_message] applied to [Pexp_constraint].
122+
Seperate implementation from when it's applied to layout annotations. *)
123+
124+
(* Needs a string body *)
125+
let f (x : bool) = (x : int)[@error_message]
126+
[%%expect{|
127+
Line 1, characters 28-44:
128+
1 | let f (x : bool) = (x : int)[@error_message]
129+
^^^^^^^^^^^^^^^^
130+
Warning 47 [attribute-payload]: illegal payload for attribute 'error_message'.
131+
Error_message attribute expects a string argument
132+
Line 1, characters 20-21:
133+
1 | let f (x : bool) = (x : int)[@error_message]
134+
^
135+
Error: This expression has type bool but an expression was expected of type
136+
int
137+
|}]
138+
139+
(* Can only be applied once *)
140+
let f (x : bool) = (x : int)[@error_message "A"][@error_message "B"]
141+
[%%expect{|
142+
Line 1, characters 48-68:
143+
1 | let f (x : bool) = (x : int)[@error_message "A"][@error_message "B"]
144+
^^^^^^^^^^^^^^^^^^^^
145+
Warning 47 [attribute-payload]: illegal payload for attribute 'error_message'.
146+
More than one error_message attribute present. All of them will be ignored.
147+
Line 1, characters 20-21:
148+
1 | let f (x : bool) = (x : int)[@error_message "A"][@error_message "B"]
149+
^
150+
Error: This expression has type bool but an expression was expected of type
151+
int
152+
|}]
153+
154+
(* Simple test case *)
155+
let f (x : bool) = (x : int)[@error_message "custom message"]
156+
[%%expect{|
157+
Line 1, characters 20-21:
158+
1 | let f (x : bool) = (x : int)[@error_message "custom message"]
159+
^
160+
Error: This expression has type bool but an expression was expected of type
161+
int
162+
because [@error_message]: custom message
163+
|}]
164+
165+
(* Doesn't work when the type mismatch happens later. This differ from
166+
the layout annotation case. *)
167+
let f x: bool = (x : int)[@error_message "custom message"]
168+
[%%expect{|
169+
Line 1, characters 16-25:
170+
1 | let f x: bool = (x : int)[@error_message "custom message"]
171+
^^^^^^^^^
172+
Error: This expression has type int but an expression was expected of type
173+
bool
174+
|}]
175+
176+
(* Doesn't apply when the type error is from elsewhere within the expression *)
177+
let g (x : int) = x
178+
let f (x : bool) = (let y = false in g y : int)[@error_message "custom message"]
179+
[%%expect{|
180+
val g : int -> int = <fun>
181+
Line 2, characters 39-40:
182+
2 | let f (x : bool) = (let y = false in g y : int)[@error_message "custom message"]
183+
^
184+
Error: This expression has type bool but an expression was expected of type
185+
int
186+
|}]
187+
188+
(* Can be used to enforce layouts but not great *)
189+
let f (x : string) = (x : (_ : immediate))[@error_message "custom message"]
190+
[%%expect{|
191+
Line 1, characters 22-23:
192+
1 | let f (x : string) = (x : (_ : immediate))[@error_message "custom message"]
193+
^
194+
Error: This expression has type string but an expression was expected of type
195+
('a : immediate)
196+
because [@error_message]: custom message
197+
The layout of string is value, because
198+
it is the primitive value type string.
199+
But the layout of string must be a sublayout of immediate, because
200+
of the annotation on the wildcard _ at line 1, characters 26-41.
201+
|}]
202+
203+
(* Doesn't apply when the mismatch is deep *)
204+
let f () = (fun (x: int) -> x : string -> string)[@error_message "custom message"]
205+
[%%expect{|
206+
Line 1, characters 16-24:
207+
1 | let f () = (fun (x: int) -> x : string -> string)[@error_message "custom message"]
208+
^^^^^^^^
209+
Error: This pattern matches values of type int
210+
but a pattern was expected which matches values of type string
211+
|}]
212+
213+
let f () = (fun (x: int) -> x : string)[@error_message "custom message"]
214+
[%%expect{|
215+
Line 1, characters 12-29:
216+
1 | let f () = (fun (x: int) -> x : string)[@error_message "custom message"]
217+
^^^^^^^^^^^^^^^^^
218+
Error: This expression should not be a function, the expected type is
219+
string because [@error_message]: custom message
220+
|}]
221+
222+
(* Same when the function is not declared inline *)
223+
let g (x: int) = x
224+
let f () = (g : (string -> string))[@error_message "custom message"]
225+
[%%expect{|
226+
val g : int -> int = <fun>
227+
Line 2, characters 12-13:
228+
2 | let f () = (g : (string -> string))[@error_message "custom message"]
229+
^
230+
Error: This expression has type int -> int
231+
but an expression was expected of type string -> string
232+
Type int is not compatible with type string
233+
|}]
234+
235+
let g (x: int) = x
236+
let f () = (g : string)[@error_message "custom message"]
237+
[%%expect{|
238+
val g : int -> int = <fun>
239+
Line 2, characters 12-13:
240+
2 | let f () = (g : string)[@error_message "custom message"]
241+
^
242+
Error: This expression has type int -> int
243+
but an expression was expected of type string
244+
because [@error_message]: custom message
245+
|}]

0 commit comments

Comments
 (0)