Skip to content

Commit be00179

Browse files
authored
flambda-backend: Honor [@error_message] attribute even when its location is ghost (#2750)
* Add regression test * Fix ghost location bug
1 parent 79d87be commit be00179

File tree

4 files changed

+98
-1
lines changed

4 files changed

+98
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
open Ast_mapper
2+
3+
(* Assert statically that a string that appears in the source text
4+
is alphabetically ordered. This is a bit contrived so that we
5+
can exercise [@ocaml.error_message].
6+
*)
7+
8+
let () =
9+
register "sorted" (fun _ ->
10+
{ default_mapper with expr = fun self expr ->
11+
match expr.pexp_desc with
12+
| Pexp_extension
13+
( { txt = "sorted" },
14+
PStr
15+
[ { pstr_desc =
16+
Pstr_eval
17+
( { pexp_desc = Pexp_constant (Pconst_string (str, loc, _)) }
18+
, _ ) } ] )
19+
->
20+
(* Use a ghost location, as is typical for ppxes *)
21+
let loc = { loc with loc_ghost = true } in
22+
let sorted =
23+
String.to_seq str
24+
|> List.of_seq
25+
|> List.sort Char.compare
26+
|> List.to_seq
27+
|> String.of_seq
28+
in
29+
Ast_helper.with_default_loc loc (fun () ->
30+
Ast_helper.Exp.apply
31+
(Ast_helper.Exp.ident { txt = Lident "ignore"; loc})
32+
[ Nolabel,
33+
Ast_helper.Exp.attr
34+
(Ast_helper.Exp.constraint_
35+
(Ast_helper.Exp.variant sorted None)
36+
(Ast_helper.Typ.variant
37+
[ Ast_helper.Rf.tag { txt = str; loc } true [] ]
38+
Closed
39+
None ))
40+
(Ast_helper.Attr.mk
41+
{ txt = "ocaml.error_message"; loc }
42+
(PStr
43+
[ Ast_helper.Exp.constant
44+
(Ast_helper.Const.string
45+
(Printf.sprintf
46+
"The %s string is not in alphabetical order."
47+
str))
48+
|> Ast_helper.Str.eval
49+
]))
50+
])
51+
| _ -> default_mapper.expr self expr
52+
}
53+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
File "test.ml", line 20, characters 21-46:
2+
20 | let () = [%sorted "not_in_alphabetical_order"]
3+
^^^^^^^^^^^^^^^^^^^^^^^^^
4+
Error: This expression has type [> `___aaabcdeehiillnnooprrtt ]
5+
but an expression was expected of type
6+
[ `not_in_alphabetical_order ]
7+
The not_in_alphabetical_order string is not in alphabetical order.
8+
The second variant type does not allow tag(s)
9+
`___aaabcdeehiillnnooprrtt
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
(* TEST
2+
readonly_files = "ppx_error_message.ml";
3+
include ocamlcommon;
4+
setup-ocamlc.byte-build-env;
5+
program = "${test_build_directory}/ppx_error_message.exe";
6+
all_modules = "ppx_error_message.ml";
7+
ocamlc.byte;
8+
module = "test.ml";
9+
flags = "-I ${test_build_directory} -ppx ${program}";
10+
ocamlc_byte_exit_status = "2";
11+
ocamlc.byte;
12+
check-ocamlc.byte-output;
13+
*)
14+
15+
module Good = struct
16+
let () = [%sorted "abcd"]
17+
end
18+
19+
module Bad = struct
20+
let () = [%sorted "not_in_alphabetical_order"]
21+
end
22+
23+

typing/typecore.ml

+13-1
Original file line numberDiff line numberDiff line change
@@ -4733,6 +4733,18 @@ let check_apply_prim_type prim typ =
47334733
end
47344734
| _ -> false
47354735

4736+
(* The explanation is suppressed if the location is ghost (e.g. the construct is
4737+
in ppx-generated code), unless the explanation originates from the
4738+
[@error_message] attribute, which a ppx may reasonably have inserted itself
4739+
to get a better error message.
4740+
*)
4741+
let should_show_explanation ~explanation ~loc =
4742+
if not loc.Location.loc_ghost then true
4743+
else
4744+
match explanation with
4745+
| Error_message_attr _ -> true
4746+
| _ -> false
4747+
47364748
(* Merge explanation to type clash error *)
47374749

47384750
let with_explanation explanation f =
@@ -4741,7 +4753,7 @@ let with_explanation explanation f =
47414753
| Some explanation ->
47424754
try f ()
47434755
with Error (loc', env', Expr_type_clash(err', None, exp'))
4744-
when not loc'.Location.loc_ghost ->
4756+
when should_show_explanation ~loc:loc' ~explanation ->
47454757
let err = Expr_type_clash(err', Some explanation, exp') in
47464758
raise (Error (loc', env', err))
47474759

0 commit comments

Comments
 (0)