Fill AACI and coerce type specs

Any error reasons or paths are just term() still, and ACI doesn't have a defined spec in the compiler, so whatever, but the AACI types, the erlang representation of terms, and the four different kinds of coerce function are all spec'd now.

Also some internal type substitution functions were given types, just in the hopes of catching some errors, but dyalizer doesn't seem to complain at all no matter how badly I break my code. Strange approach to making a type system, but oh well.
This commit is contained in:
Jarvis Carroll
2026-02-26 12:54:28 +00:00
parent bda4e89e58
commit 540b2c513b
2 changed files with 115 additions and 7 deletions
+29 -5
View File
@@ -10,14 +10,20 @@
-include_lib("eunit/include/eunit.hrl").
-spec parse_literal(String) -> Result
when String :: string(),
Result :: {ok, gmb_fate_data:fate_type()}
| {error, Reason :: term()}.
-spec parse_literal(Sophia) -> {ok, FATE} | {error, Reason}
when Sophia :: string(),
FATE :: gmb_fate_data:fate_type(),
Reason :: term().
parse_literal(String) ->
parse_literal(unknown_type(), String).
-spec parse_literal(Type, Sophia) -> {ok, FATE} | {error, Reason}
when Type :: hz_aaci:annotated_type(),
Sophia :: string(),
FATE :: gmb_fate_data:fate_type(),
Reason :: term().
parse_literal(Type, String) ->
case parse_expression(Type, {1, 1}, String) of
{ok, {Result, NewPos, NewString}} ->
@@ -917,16 +923,34 @@ wrap_error(Reason, _) -> Reason.
%%% Pretty Printing
-spec fate_to_list(FATE) -> Sophia
when FATE :: gmb_fate_data:fate_type(),
Sophia :: string().
fate_to_list(Term) ->
fate_to_list(unknown_type(), Term).
-spec fate_to_list(Type, FATE) -> Sophia
when Type :: hz_aaci:annotated_type(),
FATE :: gmb_fate_data:fate_type(),
Sophia :: string().
fate_to_list(Type, Term) ->
IOList = fate_to_iolist(Type, Term),
unicode:characters_to_list(IOList).
-spec fate_to_iolist(FATE) -> Sophia
when FATE :: gmb_fate_data:fate_type(),
Sophia :: iolist().
fate_to_iolist(Term) ->
fate_to_iolist(unknown_type(), Term).
-spec fate_to_iolist(Type, FATE) -> Sophia
when Type :: hz_aaci:annotated_type(),
FATE :: gmb_fate_data:fate_type(),
Sophia :: iolist().
% Special case for singleton records, since they are erased during compilation.
fate_to_iolist({_, _, {record, [{FieldName, FieldType}]}}, Term) ->
singleton_record_to_iolist(FieldName, FieldType, Term);
@@ -1430,6 +1454,6 @@ singleton_test() ->
% Also if we wanted an integer, the singleton is NOT dropped, so is also an
% error.
{error, {expected_close_paren, 1, 3}} = parse_literal({integer, alread_normalized, integer}, "(1,)"),
{error, {expected_close_paren, 1, 3}} = parse_literal({integer, already_normalized, integer}, "(1,)"),
ok.