Skip to content

Commit ab41151

Browse files
hajduakosmeta-codesync[bot]
authored andcommitted
[erl-frontend] Add support for OTP 28 strict map generator
Summary: Add support for the <:- strict generator which fails if any RHS element doesn't match the LHS pattern, see https://www.erlang.org/eeps/eep-0070. Reviewed By: rgrig Differential Revision: D91221323 fbshipit-source-id: 06a65ce779f6e386b1c45509f12135092f572ee2
1 parent 6f78c98 commit ab41151

File tree

6 files changed

+38
-5
lines changed

6 files changed

+38
-5
lines changed

infer/src/erlang/ErlangAst.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ and qualifier =
114114
| BitsGenerator of {pattern: expression; expression: expression}
115115
| Filter of expression
116116
| Generator of {pattern: expression; expression: expression; strict: bool}
117-
| MapGenerator of {pattern: association; expression: expression}
117+
| MapGenerator of {pattern: association; expression: expression; strict: bool}
118118

119119
and timeout = {time: expression; handler: body}
120120

infer/src/erlang/ErlangJsonParser.ml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,11 @@ and to_qualifier gen_uniq json : Ast.qualifier option =
520520
| `List [`String "m_generate"; _anno; pattern; expression] ->
521521
let* pattern = to_association gen_uniq pattern in
522522
let* expression = to_expression gen_uniq expression in
523-
Some (Ast.MapGenerator {pattern; expression})
523+
Some (Ast.MapGenerator {pattern; expression; strict= false})
524+
| `List [`String "m_generate_strict"; _anno; pattern; expression] ->
525+
let* pattern = to_association gen_uniq pattern in
526+
let* expression = to_expression gen_uniq expression in
527+
Some (Ast.MapGenerator {pattern; expression; strict= true})
524528
| filter ->
525529
let* filter = to_expression gen_uniq filter in
526530
Some (Ast.Filter filter)

infer/src/erlang/ErlangTranslator.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,7 +1042,7 @@ and translate_comprehension_loop (env : (_, _) Env.t) loop_body qualifiers : Blo
10421042
let init_block = Block.all env [init_block; check_block] in
10431043
let mk_matcher head_var = translate_pattern env head_var pattern in
10441044
make_gen gen_var init_block mk_matcher strict
1045-
| MapGenerator {pattern; expression} ->
1045+
| MapGenerator {pattern; expression; strict} ->
10461046
let gen_var = mk_fresh_id () in
10471047
let init_block =
10481048
(* Turn the generator map into a list of {key, val} pairs *)
@@ -1070,7 +1070,7 @@ and translate_comprehension_loop (env : (_, _) Env.t) loop_body qualifiers : Blo
10701070
key_val_load |~~> [matcher.start] ;
10711071
{matcher with start= key_val_load}
10721072
in
1073-
make_gen gen_var init_block mk_matcher false (* Strict mode not yet parsed for maps *)
1073+
make_gen gen_var init_block mk_matcher strict
10741074
| BitsGenerator _ ->
10751075
let unsupported = call_unsupported "bits_generator" 0 in
10761076
let call_instr = builtin_call env (mk_fresh_id ()) unsupported [] in

infer/tests/codetoanalyze/erlang/compiler/issues.exp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,10 @@ features_mc:test_mapgen_empty_Bad/0: expected_crash
453453
features_mc:test_mapgen_empty_Ok/0: ok
454454
features_mc:test_mapgen_nonempty_Bad/0: expected_crash
455455
features_mc:test_mapgen_nonempty_Ok/0: ok
456+
features_mc:test_mapgen_nonstrict_Bad/0: expected_crash
457+
features_mc:test_mapgen_nonstrict_Ok/0: ok
458+
features_mc:test_mapgen_strict_Bad/0: badmatch
459+
features_mc:test_mapgen_strict_Ok/0: ok
456460

457461
----- features_receive -----
458462
features_receive:test_receive1_Ok/0: ok

infer/tests/codetoanalyze/erlang/pulse/features/features_mc.erl

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@
2020
test_mapgen_badmap_Bad/0,
2121
test_mapgen_badmap2_Bad/0,
2222
test_mapcomp_with_mapgen_Ok/0,
23-
test_mapcomp_with_mapgen_Bad/0
23+
test_mapcomp_with_mapgen_Bad/0,
24+
test_mapgen_nonstrict_Ok/0,
25+
test_mapgen_nonstrict_Bad/0,
26+
test_mapgen_strict_Ok/0,
27+
test_mapgen_strict_Bad/0
2428
]).
2529

2630
test_mapcomp_Ok() ->
@@ -91,3 +95,22 @@ test_mapcomp_with_mapgen_Bad() ->
9195
M = #{1 => 2},
9296
M2 = #{V => K || K := V <- M},
9397
?CRASH_IF_EQUAL(1, maps:get(2, M2)).
98+
99+
test_mapgen_nonstrict_Ok() ->
100+
M = #{1 => 2},
101+
L = [K || K := 2 <- M],
102+
?ASSERT_EQUAL([1], L).
103+
104+
test_mapgen_nonstrict_Bad() ->
105+
M = #{1 => 2},
106+
L = [K || K := 2 <- M],
107+
?CRASH_IF_EQUAL([1], L).
108+
109+
test_mapgen_strict_Ok() ->
110+
M = #{1 => 2},
111+
L = [K || K := 2 <:- M],
112+
?ASSERT_EQUAL([1], L).
113+
114+
test_mapgen_strict_Bad() ->
115+
M = #{1 => 2},
116+
L = [K || K := 3 <:- M].

infer/tests/codetoanalyze/erlang/pulse/issues.exp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,8 @@ codetoanalyze/erlang/pulse/features/features_mc.erl, fp_test_mapgen_nonempty2_Ok
237237
codetoanalyze/erlang/pulse/features/features_mc.erl, test_mapgen_badmap_Bad/0, 2, BAD_GENERATOR, no_bucket, ERROR, [bad generator here]
238238
codetoanalyze/erlang/pulse/features/features_mc.erl, test_mapgen_badmap2_Bad/0, 2, BAD_GENERATOR, no_bucket, ERROR, [bad generator here]
239239
codetoanalyze/erlang/pulse/features/features_mc.erl, test_mapcomp_with_mapgen_Bad/0, 3, NO_MATCH_OF_RHS, no_bucket, ERROR, [no match of RHS here]
240+
codetoanalyze/erlang/pulse/features/features_mc.erl, test_mapgen_nonstrict_Bad/0, 3, NO_MATCH_OF_RHS, no_bucket, ERROR, [no match of RHS here]
241+
codetoanalyze/erlang/pulse/features/features_mc.erl, test_mapgen_strict_Bad/0, 2, NO_MATCH_OF_RHS, no_bucket, ERROR, [no match of RHS here]
240242
codetoanalyze/erlang/pulse/features/features_receive.erl, test_receive2_Bad/0, 7, NO_MATCH_OF_RHS, no_bucket, ERROR, [no match of RHS here]
241243
codetoanalyze/erlang/pulse/features/features_receive.erl, test_receive4_Bad/0, 6, NO_MATCH_OF_RHS, no_bucket, ERROR, [no match of RHS here]
242244
codetoanalyze/erlang/pulse/features/features_receive.erl, test_receive5_Bad/0, 6, NO_MATCH_OF_RHS, no_bucket, ERROR, [no match of RHS here]

0 commit comments

Comments
 (0)