Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

broken type spec for socket:sendto/4 in OTP-27.2 #9180

Open
RoadRunnr opened this issue Dec 11, 2024 · 2 comments
Open

broken type spec for socket:sendto/4 in OTP-27.2 #9180

RoadRunnr opened this issue Dec 11, 2024 · 2 comments
Assignees
Labels
bug Issue is reported as a bug team:PS Assigned to OTP team PS

Comments

@RoadRunnr
Copy link
Contributor

Describe the bug

Between 27.1.3 and 27.2 the type spec for socket:sendto/4 was changed. The updated type spec does no longer allow nowait as the value for the 4th parameter.

The implementation has not changed and based on the implementation nowait is clearly valid.

These lines https://github.com/erlang/otp/blob/OTP-27.1.3/lib/kernel/src/socket.erl#L3727-L3728 from 27.1.3 have been lost in PR-8986

To Reproduce

Run dialyzer on this

-module(sock).

-export([sendto/4]).

family({_,_,_,_}) -> inet;
family({_,_,_,_,_,_,_,_}) -> inet6.

sendto(Socket, IP, Port, Data) ->
    Dest = #{family => family(IP),
             addr => IP,
             port => Port},
    case socket:sendto(Socket, Data, Dest, nowait) of
        ok -> ok;
        Other  ->
            logger:debug("sendto(~p) failed with: ~p", [Dest, Other]),
            ok
    end.

Results in this error:

Line 12 Column 10: The contract socket:sendto(Socket::socket(),Data::iodata(),Dest::sockaddr(),Flags::[any()]) -> Result when Result :: 'ok' | {'ok',RestData::binary()} | {'error',Reason} | {'error',{Reason,RestData::binary()}}, Reason :: posix() | 'closed' | invalid();(Socket::socket(),Data::iodata(),Cont::select_info(),TimeoutOrHandle::dynamic()) -> Result when Result :: 'ok' | {'ok',RestData::binary()} | {'error',Reason} | {'error',{Reason,RestData::binary()}}, Reason :: posix() | 'closed' | invalid() cannot be right because the inferred return for sendto(Socket::any(),Data::any(),Dest::#{'addr':={_,_,_,_} | {_,_,_,_,_,_,_,_}, 'family':='inet' | 'inet6', 'port':=_},'nowait') on line {12,10} is any()

Used to work in 27.1

Expected behavior
Call is not reported as violating the function specification.

Affected versions

27.2

@RoadRunnr RoadRunnr added the bug Issue is reported as a bug label Dec 11, 2024
@IngelaAndin IngelaAndin added the team:PS Assigned to OTP team PS label Dec 11, 2024
@bmk
Copy link
Contributor

bmk commented Jan 7, 2025

Hi,

Could you please provide the exact dialyzer command?

Regards,
/Micael

@RoadRunnr
Copy link
Contributor Author

@bmk

Save the sample snippet to sock.erl, then debug compile sock.erl and make sure you have a plt:

$ erlc +debug_info sock.erl
$ dialyzer --build_plt --apps erts kernel stdlib compiler crypto parsetools
  Creating PLT /home/aschultz/.cache/erlang/.dialyzer_plt ... done in 0m25.79s
done (passed successfully)

Then run dialyzer on the sock.beam produced by erlc:

$ dialyzer -Wno_return sock.beam 
  Checking whether the PLT /home/aschultz/.cache/erlang/.dialyzer_plt is up-to-date... yes
  Proceeding with analysis...
sock.erl:12:10: The contract socket:sendto
          (Socket :: socket(),
          Data :: iodata(),
          Dest :: sockaddr(),
          Flags :: [any()]) ->
             Result
             when
                 Result ::
                     'ok' |
                     {'ok', RestData :: binary()} |
                     {'error', Reason} |
                     {'error', {Reason, RestData :: binary()}},
                 Reason :: posix() | 'closed' | invalid();
         (Socket :: socket(),
          Data :: iodata(),
          Cont :: select_info(),
          TimeoutOrHandle :: dynamic()) ->
             Result
             when
                 Result ::
                     'ok' |
                     {'ok', RestData :: binary()} |
                     {'error', Reason} |
                     {'error', {Reason, RestData :: binary()}},
                 Reason :: posix() | 'closed' | invalid() cannot be right because the inferred return for sendto
         (Socket :: any(),
          Data :: any(),
          Dest ::
              #{'addr' := {_, _, _, _} | {_, _, _, _, _, _, _, _},
                'family' := 'inet' | 'inet6',
                'port' := _},
          'nowait') on position 12:10 is 
          any()
 done in 0m0.23s
done (warnings were emitted)

Before 27.2 the above used to work without warnings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue is reported as a bug team:PS Assigned to OTP team PS
Projects
None yet
Development

No branches or pull requests

3 participants