Alright folks, in a nutshell, this release addresses all feedback from the previous RCs:
-
Fully compatible with Erlang/OTP 28.1+
-
Struct update syntax has been adapted into a type assertion operator
-
Addresses issues with projecting taking too long to compile
This should be our final stop before v1.19, please give it a try!
32 Likes
While compiling the following functions Iโm getting a warning that did not show in Elixir 1.18.x.
@impl Event
def to_payload(%GameTransactionCompleted{} = e) do
# ...
end
def to_payload(%GameTransactionCompleted.ExternalTransaction{} = e) do
# ...
end
def to_payload(%GameTransactionCompleted.InternalTransaction{} = e) do
# ...
end
def to_payload(%GameTransactionCompleted.Stake{} = s) do
# ...
end
def to_payload(%Game{} = g) do
# ...
end
The Event protocol defines the callback as:
@spec to_payload(struct()) :: map()
def to_payload(struct)
And this is the warning that I get:
Compiling 1 file (.ex)
warning: the 1st pattern in clause will never match:
%Dragonara.Outbox.GameTransactionCompleted.ExternalTransaction{} = e
because it is expected to receive type:
dynamic(%Dragonara.Outbox.GameTransactionCompleted{})
typing violation found at:
โ
101 โ def to_payload(%GameTransactionCompleted.ExternalTransaction{} = e) do
โ ~
โ
โโ lib/dragonara/outbox/game_transaction_completed.ex:101:68: Dragonara.Outbox.Event.Dragonara.Outbox.GameTransactionCompleted.to_payload/1
warning: the 1st pattern in clause will never match:
%Dragonara.Outbox.GameTransactionCompleted.InternalTransaction{} = e
because it is expected to receive type:
dynamic(%Dragonara.Outbox.GameTransactionCompleted{})
typing violation found at:
โ
120 โ def to_payload(%GameTransactionCompleted.InternalTransaction{} = e) do
โ ~
โ
โโ lib/dragonara/outbox/game_transaction_completed.ex:120:68: Dragonara.Outbox.Event.Dragonara.Outbox.GameTransactionCompleted.to_payload/1
warning: the 1st pattern in clause will never match:
%Dragonara.Outbox.GameTransactionCompleted.Stake{} = s
because it is expected to receive type:
dynamic(%Dragonara.Outbox.GameTransactionCompleted{})
typing violation found at:
โ
140 โ def to_payload(%GameTransactionCompleted.Stake{} = s) do
โ ~
โ
โโ lib/dragonara/outbox/game_transaction_completed.ex:140:54: Dragonara.Outbox.Event.Dragonara.Outbox.GameTransactionCompleted.to_payload/1
warning: the 1st pattern in clause will never match:
%Bluelabs.Game{} = g
because it is expected to receive type:
dynamic(%Dragonara.Outbox.GameTransactionCompleted{})
typing violation found at:
โ
144 โ def to_payload(%Game{} = g) do
โ ~
โ
โโ lib/dragonara/outbox/game_transaction_completed.ex:144:28: Dragonara.Outbox.Event.Dragonara.Outbox.GameTransactionCompleted.to_payload/1
warning: the 1st pattern in clause will never match:
nil
because it is expected to receive type:
dynamic(%Dragonara.Outbox.GameTransactionCompleted{})
typing violation found at:
โ
171 โ def to_payload(nil) do
โ ~~~~~~~~~~~~~~~~~~~~~~
โ
โโ lib/dragonara/outbox/game_transaction_completed.ex:171: Dragonara.Outbox.Event.Dragonara.Outbox.GameTransactionCompleted.to_payload/1
Generated dragonara app
Looks like the compiler is not able to understand that this is a multiclause function that acts differently depending on the struct that it receives. It is true that from the outside this function is only called with the %GameTransactionCompleted{}
struct but that call also uses the other clauses for nested structs.
EDIT: I also want to note that if I rename the problematic clauses so they are not part of the same function (for example payload
instead of to_payload
) the warnings go away. While this workaround fixes the issue I still wonder if this should happen and why the compiler is not able to detect that the other clauses are also being called with the proper structs.