@@ -1336,7 +1336,7 @@ do_type_check_expr(Env, {bin, _, BinElements} = BinExpr) ->
1336
1336
VarBindAndCsList =
1337
1337
lists :map (fun ({bin_element , _P , Expr , _Size , _Specif } = BinElem ) ->
1338
1338
% % Treat bin type specifier as type annotation
1339
- Ty = type_of_bin_element (BinElem ),
1339
+ Ty = type_of_bin_element (BinElem , expr ),
1340
1340
type_check_expr_in (Env , Ty , Expr )
1341
1341
end ,
1342
1342
BinElements ),
@@ -3693,7 +3693,7 @@ add_type_pat({bin, _P, BinElements} = Bin, Ty, TEnv, VEnv) ->
3693
3693
lists :foldl (fun ({bin_element , _ , Pat , _Size , _Specifiers } = BinElem ,
3694
3694
{VEnvAcc , CsAcc }) ->
3695
3695
% % Check Pat against the bit syntax type specifiers
3696
- ElemTy = type_of_bin_element (BinElem ),
3696
+ ElemTy = type_of_bin_element (BinElem , pattern ),
3697
3697
{_PatTy , _UBound , VEnv2 , Cs2 } =
3698
3698
add_type_pat (Pat , ElemTy , TEnv , VEnvAcc ),
3699
3699
{VEnv2 , constraints :combine (CsAcc , Cs2 )}
@@ -3957,15 +3957,21 @@ count_var_occurrences(Exprs) ->
3957
3957
Size :: non_neg_integer () |
3958
3958
default ,
3959
3959
Specifiers :: [atom () | {unit , pos_integer ()}] |
3960
- default }) -> type ().
3961
- type_of_bin_element ({bin_element , Anno , Expr , Size , default }) ->
3962
- type_of_bin_element ({bin_element , Anno , Expr , Size , []});
3963
- type_of_bin_element ({bin_element , _P , Expr , _Size , Specifiers }) ->
3960
+ default },
3961
+ OccursAs :: pattern | expr ) -> type ().
3962
+ type_of_bin_element ({bin_element , Anno , Expr , Size , default }, OccursAs ) ->
3963
+ type_of_bin_element ({bin_element , Anno , Expr , Size , []}, OccursAs );
3964
+ type_of_bin_element ({bin_element , _P , Expr , _Size , Specifiers }, OccursAs ) ->
3964
3965
% % String literal is syntactic sugar for multiple char literals,
3965
3966
IsStringLiteral = case Expr of
3966
3967
{string , _ , _ } -> true ;
3967
3968
_ -> false
3968
3969
end ,
3970
+ IsSigned =
3971
+ case OccursAs of
3972
+ pattern -> lists :member (signed , Specifiers );
3973
+ expr -> true
3974
+ end ,
3969
3975
Types =
3970
3976
lists :filtermap (fun
3971
3977
(S ) when S == integer ;
@@ -3976,8 +3982,10 @@ type_of_bin_element({bin_element, _P, Expr, _Size, Specifiers}) ->
3976
3982
IsStringLiteral ->
3977
3983
% % <<"ab"/utf8>> == <<$a/utf8, $b/utf8>>.
3978
3984
{true , type (string )};
3979
- not IsStringLiteral ->
3980
- {true , type (integer )}
3985
+ IsSigned ->
3986
+ {true , type (integer )};
3987
+ true ->
3988
+ {true , type (non_neg_integer )}
3981
3989
end ;
3982
3990
(float ) when IsStringLiteral ->
3983
3991
% % <<"abc"/float>> is integers to floats conversion
@@ -4003,9 +4011,13 @@ type_of_bin_element({bin_element, _P, Expr, _Size, Specifiers}) ->
4003
4011
[] when IsStringLiteral ->
4004
4012
% % <<"abc">>
4005
4013
type (string );
4006
- [] ->
4007
- % % <<X>>
4014
+ [] when IsSigned ->
4015
+ % % As expr: <<X>>
4016
+ % % As pattern: <<X/signed>>
4008
4017
type (integer );
4018
+ [] when not IsSigned ->
4019
+ % % As pattern: <<X>> or <<X/unsigned>>
4020
+ type (non_neg_integer );
4009
4021
[T ] ->
4010
4022
T
4011
4023
end .
0 commit comments