Skip to content

Commit 8ecac17

Browse files
committed
khepri_tree: Use an intermediate parameterized type on top of #tree{}
[Why] Our `#tree{}` type has two versions which differ on the type of the `keep_while_conds_revidx` field. We also defined two type, `tree_v0()` and `tree_v1()` which finished to define the two versions. This was fine up to and including Erlang/OTP 27. However with Erlang/OTP 28, Dialyzer complained that `update_keep_while_conds/3` would never return. This was caused by the new "nominal type" property of opaque types: if I understand correclty, based on the type specs, we couldn't modify the `#tree{}` record in `update_keep_while_conds/3` because the returned `#tree{}` might not be a `tree_v0()` or a `tree_v1()`. [How] In the end, we couldn't use the #tree{} record directly to define the `tree_v0()` and `tree_v1()` types. We have to use an intermediate type that takes the type of the `keep_while_conds_revidx` field, then use this intermediate type in the definition of `tree_v0()` and `tree_v1()`. We remove the type of the `keep_while_conds_revidx` field in the record because it breaks the compilation with Erlang/OTP 27.
1 parent 621587d commit 8ecac17

File tree

1 file changed

+13
-7
lines changed

1 file changed

+13
-7
lines changed

src/khepri_tree.erl

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,16 @@
4040

4141
-record(tree, {root = #node{} :: khepri_tree:tree_node(),
4242
keep_while_conds = #{} :: khepri_tree:keep_while_conds_map(),
43-
keep_while_conds_revidx = #{} ::
44-
khepri_tree:keep_while_conds_revidx()}).
43+
keep_while_conds_revidx = #{}}).
4544

4645
-type tree_node() :: #node{}.
4746
%% A node in the tree structure.
4847

49-
-opaque tree_v0() :: #tree{keep_while_conds_revidx ::
50-
khepri_tree:keep_while_conds_revidx_v0()}.
51-
-opaque tree_v1() :: #tree{keep_while_conds_revidx ::
52-
khepri_tree:keep_while_conds_revidx_v1()}.
48+
-type tree(KeepWhileCondsRevIdxType) :: #tree{keep_while_conds_revidx ::
49+
KeepWhileCondsRevIdxType}.
50+
51+
-opaque tree_v0() :: tree(khepri_tree:keep_while_conds_revidx_v0()).
52+
-opaque tree_v1() :: tree(khepri_tree:keep_while_conds_revidx_v1()).
5353

5454
-type tree() :: tree_v0() | tree_v1().
5555

@@ -389,10 +389,16 @@ is_keep_while_condition_met_on_self(
389389
true
390390
end.
391391

392+
-spec update_keep_while_conds(Tree, Watcher, KeepWhile) -> NewTree when
393+
Tree :: khepri_tree:tree(),
394+
Watcher :: khepri_path:native_path(),
395+
KeepWhile :: khepri_condition:native_keep_while(),
396+
NewTree :: khepri_tree:tree().
397+
392398
update_keep_while_conds(Tree, Watcher, KeepWhile) ->
393399
AbsKeepWhile = to_absolute_keep_while(Watcher, KeepWhile),
394400
Tree1 = update_keep_while_conds_revidx(Tree, Watcher, AbsKeepWhile),
395-
#tree{keep_while_conds = KeepWhileConds} = Tree1,
401+
KeepWhileConds = get_keep_while_conds(Tree1),
396402
KeepWhileConds1 = KeepWhileConds#{Watcher => AbsKeepWhile},
397403
Tree1#tree{keep_while_conds = KeepWhileConds1}.
398404

0 commit comments

Comments
 (0)