From 8bc79d3b3fa83c258ae62c48803a7b41b273a72b Mon Sep 17 00:00:00 2001 From: Jarvis Carroll Date: Fri, 15 May 2026 05:47:48 +0000 Subject: [PATCH] Fix dialyzer warnings for hz_aaci A while ago I tried dialyzer and discovered that actually a lot of the AACI generation process never fails, and whatever the one failure was that was possible, I think I decided was unnecessary, and made that produce {ok, unknown_type} instead. I then set the types of these functions to be {ok, Result} | {error, none()}, since there were in fact no errors, but dialyzer still spewed out warnings for all the case blocks that redundantly check for these impossible error conditions. Anyway now that is fixed! The behavior and external interface are all the same still, there are just fewer warnings now. Also added specs for a couple more internal functions, just because. So noperhaps realized that actually none of it should fail. I never went in and removed all the {ok, _} wrappers, but I did at least type the functions with the correct error list --- src/hz_aaci.erl | 79 +++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/src/hz_aaci.erl b/src/hz_aaci.erl index de3d8ea..a18f142 100644 --- a/src/hz_aaci.erl +++ b/src/hz_aaci.erl @@ -631,6 +631,16 @@ builtin_typedefs() -> % can simply render the normalized type expression and know that the error will % make sense. +-spec annotate_function_specs(OpaqueSpecs, Types, Acc) -> Specs + when OpaqueSpecs :: [{string(), ArgsOpaque, ResultOpaque}], + ArgsOpaque :: [{string(), opaque_type()}], + ResultOpaque :: opaque_type(), + Types :: #{string() => typedef()}, + Acc :: #{string() => {ArgsAnnotated, ResultAnnotated}}, + Specs :: #{string() => {ArgsAnnotated, ResultAnnotated}}, + ArgsAnnotated :: [{string(), annotated_type()}], + ResultAnnotated :: annotated_type(). + annotate_function_specs([], _Types, Specs) -> Specs; annotate_function_specs([{Name, ArgsOpaque, ResultOpaque} | Rest], Types, Specs) -> @@ -639,40 +649,29 @@ annotate_function_specs([{Name, ArgsOpaque, ResultOpaque} | Rest], Types, Specs) NewSpecs = maps:put(Name, {Args, Result}, Specs), annotate_function_specs(Rest, Types, NewSpecs). --spec annotate_type(Opaque, Types) -> {ok, Annotated} | {error, Reason} +-spec annotate_type(Opaque, Types) -> {ok, Annotated} when Opaque :: opaque_type(), Types :: #{string() => typedef()}, - Annotated :: annotated_type(), - Reason :: none(). + Annotated :: annotated_type(). annotate_type(T, Types) -> case normalize_opaque_type(T, Types) of + {ok, _, _, unknown_type} -> + {ok, {T, unknown_type, unknown_type}}; {ok, AlreadyNormalized, NOpaque, NExpanded} -> - annotate_type2(T, AlreadyNormalized, NOpaque, NExpanded, Types); - Error -> - Error + annotate_type2(T, AlreadyNormalized, NOpaque, NExpanded, Types) end. -annotate_type2(T, _, _, unknown_type, _) -> - % If a type is unknown, then it should not be reported as the normalized - % name. - {ok, {T, unknown_type, unknown_type}}; annotate_type2(T, AlreadyNormalized, NOpaque, NExpanded, Types) -> - case annotate_type_subexpressions(NExpanded, Types) of - {ok, Flat} -> - case AlreadyNormalized of - true -> {ok, {T, already_normalized, Flat}}; - false -> {ok, {T, NOpaque, Flat}} - end; - Error -> - Error + {ok, Flat} = annotate_type_subexpressions(NExpanded, Types), + case AlreadyNormalized of + true -> {ok, {T, already_normalized, Flat}}; + false -> {ok, {T, NOpaque, Flat}} end. annotate_types([T | Rest], Types, Acc) -> - case annotate_type(T, Types) of - {ok, Type} -> annotate_types(Rest, Types, [Type | Acc]); - Error -> Error - end; + {ok, Type} = annotate_type(T, Types), + annotate_types(Rest, Types, [Type | Acc]); annotate_types([], _Types, Acc) -> {ok, lists:reverse(Acc)}. @@ -683,34 +682,30 @@ annotate_type_subexpressions({bytes, [Count]}, _Types) -> % opaque type. {ok, {bytes, [Count]}}; annotate_type_subexpressions({variant, VariantsOpaque}, Types) -> - case annotate_variants(VariantsOpaque, Types, []) of - {ok, Variants} -> {ok, {variant, Variants}}; - Error -> Error - end; + {ok, Variants} = annotate_variants(VariantsOpaque, Types, []), + {ok, {variant, Variants}}; annotate_type_subexpressions({record, FieldsOpaque}, Types) -> - case annotate_bindings(FieldsOpaque, Types, []) of - {ok, Fields} -> {ok, {record, Fields}}; - Error -> Error - end; + {ok, Fields} = annotate_bindings(FieldsOpaque, Types, []), + {ok, {record, Fields}}; annotate_type_subexpressions({T, ElemsOpaque}, Types) -> - case annotate_types(ElemsOpaque, Types, []) of - {ok, Elems} -> {ok, {T, Elems}}; - Error -> Error - end. + {ok, Elems} = annotate_types(ElemsOpaque, Types, []), + {ok, {T, Elems}}. + +-spec annotate_bindings(Bindings, Types, Acc) -> {ok, Annotated} + when Bindings :: [{string(), opaque_type()}], + Types :: #{string() => typedef()}, + Acc :: [{string(), annotated_type()}], + Annotated :: [{string(), annotated_type()}]. annotate_bindings([{Name, T} | Rest], Types, Acc) -> - case annotate_type(T, Types) of - {ok, Type} -> annotate_bindings(Rest, Types, [{Name, Type} | Acc]); - Error -> Error - end; + {ok, Next} = annotate_type(T, Types), + annotate_bindings(Rest, Types, [{Name, Next} | Acc]); annotate_bindings([], _Types, Acc) -> {ok, lists:reverse(Acc)}. annotate_variants([{Name, Elems} | Rest], Types, Acc) -> - case annotate_types(Elems, Types, []) of - {ok, ElemsFlat} -> annotate_variants(Rest, Types, [{Name, ElemsFlat} | Acc]); - Error -> Error - end; + {ok, ElemsFlat} = annotate_types(Elems, Types, []), + annotate_variants(Rest, Types, [{Name, ElemsFlat} | Acc]); annotate_variants([], _Types, Acc) -> {ok, lists:reverse(Acc)}.