From 27ec4a9770c458da340fae3ce0ebb53c5b2835fc Mon Sep 17 00:00:00 2001 From: James Fish Date: Wed, 3 Sep 2014 19:24:52 +0100 Subject: [PATCH] Fix elixir dialyzer warnings --- lib/elixir/lib/application.ex | 2 +- lib/elixir/lib/file.ex | 31 +++++++++++++++---------- lib/elixir/lib/gen_event/stream.ex | 2 +- lib/elixir/lib/inspect/algebra.ex | 2 +- lib/elixir/lib/integer.ex | 4 ++-- lib/elixir/lib/kernel.ex | 2 +- lib/elixir/lib/kernel/cli.ex | 2 +- lib/elixir/lib/keyword.ex | 2 +- lib/elixir/lib/list.ex | 4 ++-- lib/elixir/lib/module/locals_tracker.ex | 2 +- lib/elixir/lib/node.ex | 2 +- lib/elixir/lib/process.ex | 2 +- lib/elixir/lib/regex.ex | 14 ++++++++++- lib/elixir/lib/string.ex | 2 +- lib/elixir/lib/supervisor.ex | 4 ++-- lib/elixir/src/elixir_errors.erl | 10 ++++---- 16 files changed, 53 insertions(+), 34 deletions(-) diff --git a/lib/elixir/lib/application.ex b/lib/elixir/lib/application.ex index b3d3b37813..df5c82aedd 100644 --- a/lib/elixir/lib/application.ex +++ b/lib/elixir/lib/application.ex @@ -201,7 +201,7 @@ defmodule Application do `:applications` in the `.app` file in case they were not previously started. """ - @spec ensure_all_started(app, start_type) :: {:ok, [app]} | {:error, term} + @spec ensure_all_started(app, start_type) :: {:ok, [app]} | {:error, {app, term}} def ensure_all_started(app, type \\ :temporary) when is_atom(app) do :application.ensure_all_started(app, type) end diff --git a/lib/elixir/lib/file.ex b/lib/elixir/lib/file.ex index e9a47a1a1e..c76dc3dfcc 100644 --- a/lib/elixir/lib/file.ex +++ b/lib/elixir/lib/file.ex @@ -75,6 +75,12 @@ defmodule File do @type posix :: :file.posix() @type io_device :: :file.io_device() @type stat_options :: [time: :local | :universal | :posix] + @type mode :: :append | :binary | :compressed | :delayed_write | :exclusive | + :raw | :read | :read_ahead | :sync | :write | + {:encoding , :latin1 | :unicode | :utf16 | :utf32 | :utf8 | + {:utf16, :big | :little} | {:utf32, :big | :little}} | + {:read_ahead, pos_integer} | + {:delayed_write, non_neg_integer, non_neg_integer} @doc """ Returns `true` if the path is a regular file. @@ -612,7 +618,7 @@ defmodule File do Check `File.open/2` for other available options. """ - @spec write(Path.t, iodata, list) :: :ok | {:error, posix} + @spec write(Path.t, iodata, [mode]) :: :ok | {:error, posix} def write(path, content, modes \\ []) do F.write_file(IO.chardata_to_string(path), content, modes) end @@ -620,7 +626,7 @@ defmodule File do @doc """ Same as `write/3` but raises an exception if it fails, returns `:ok` otherwise. """ - @spec write!(Path.t, iodata, list) :: :ok | no_return + @spec write!(Path.t, iodata, [mode]) :: :ok | no_return def write!(path, content, modes \\ []) do path = IO.chardata_to_string(path) case F.write_file(path, content, modes) do @@ -902,7 +908,8 @@ defmodule File do File.close(file) """ - @spec open(Path.t, list) :: {:ok, io_device} | {:error, posix} + @spec open(Path.t, [mode | :ram]) :: {:ok, io_device} | {:error, posix} + @spec open(Path.t, (io_device -> res)) :: {:ok, res} | {:error, posix} when res: var def open(path, modes \\ []) def open(path, modes) when is_list(modes) do @@ -935,7 +942,7 @@ defmodule File do end) """ - @spec open(Path.t, list, (io_device -> res)) :: {:ok, res} | {:error, posix} when res: var + @spec open(Path.t, [mode | :ram], (io_device -> res)) :: {:ok, res} | {:error, posix} when res: var def open(path, modes, function) do case open(path, modes) do {:ok, device} -> @@ -953,7 +960,7 @@ defmodule File do Returns the `io_device` otherwise. """ - @spec open!(Path.t, list) :: io_device | no_return + @spec open!(Path.t, [mode]) :: io_device | no_return def open!(path, modes \\ []) do path = IO.chardata_to_string(path) case open(path, modes) do @@ -968,7 +975,7 @@ defmodule File do Returns the function result otherwise. """ - @spec open!(Path.t, list, (io_device -> res)) :: res | no_return when res: var + @spec open!(Path.t, [mode | :ram], (io_device -> res)) :: res | no_return when res: var def open!(path, modes, function) do path = IO.chardata_to_string(path) case open(path, modes, function) do @@ -1124,7 +1131,7 @@ defmodule File do Returns `:ok` on success, or `{:error, reason}` on failure. """ - @spec chmod(Path.t, integer) :: :ok | {:error, posix} + @spec chmod(Path.t, non_neg_integer) :: :ok | {:error, posix} def chmod(path, mode) do F.change_mode(IO.chardata_to_string(path), mode) end @@ -1132,7 +1139,7 @@ defmodule File do @doc """ Same as `chmod/2`, but raises an exception in case of failure. Otherwise `:ok`. """ - @spec chmod!(Path.t, integer) :: :ok | no_return + @spec chmod!(Path.t, non_neg_integer) :: :ok | no_return def chmod!(path, mode) do path = IO.chardata_to_string(path) case chmod(path, mode) do @@ -1147,7 +1154,7 @@ defmodule File do for a given `file`. Returns `:ok` on success, or `{:error, reason}` on failure. """ - @spec chgrp(Path.t, integer) :: :ok | {:error, posix} + @spec chgrp(Path.t, non_neg_integer) :: :ok | {:error, posix} def chgrp(path, gid) do F.change_group(IO.chardata_to_string(path), gid) end @@ -1155,7 +1162,7 @@ defmodule File do @doc """ Same as `chgrp/2`, but raises an exception in case of failure. Otherwise `:ok`. """ - @spec chgrp!(Path.t, integer) :: :ok | no_return + @spec chgrp!(Path.t, non_neg_integer) :: :ok | no_return def chgrp!(path, gid) do path = IO.chardata_to_string(path) case chgrp(path, gid) do @@ -1170,7 +1177,7 @@ defmodule File do for a given `file`. Returns `:ok` on success, or `{:error, reason}` on failure. """ - @spec chown(Path.t, integer) :: :ok | {:error, posix} + @spec chown(Path.t, non_neg_integer) :: :ok | {:error, posix} def chown(path, uid) do F.change_owner(IO.chardata_to_string(path), uid) end @@ -1178,7 +1185,7 @@ defmodule File do @doc """ Same as `chown/2`, but raises an exception in case of failure. Otherwise `:ok`. """ - @spec chown!(Path.t, integer) :: :ok | no_return + @spec chown!(Path.t, non_neg_integer) :: :ok | no_return def chown!(path, uid) do path = IO.chardata_to_string(path) case chown(path, uid) do diff --git a/lib/elixir/lib/gen_event/stream.ex b/lib/elixir/lib/gen_event/stream.ex index c680d261fd..ef8422bb3d 100644 --- a/lib/elixir/lib/gen_event/stream.ex +++ b/lib/elixir/lib/gen_event/stream.ex @@ -150,7 +150,7 @@ defimpl Enumerable, for: GenEvent.Stream do # If we reach this branch, the handler was not removed yet, # so we trigger a request for doing so. defp stop(stream, {pid, ref, _} = acc) do - Task.start(fn -> GenEvent.remove_handler(pid, {GenEvent.Stream, ref}, :shutdown) end) + _ = Task.start(fn -> GenEvent.remove_handler(pid, {GenEvent.Stream, ref}, :shutdown) end) stop(stream, {:removed, acc}) end diff --git a/lib/elixir/lib/inspect/algebra.ex b/lib/elixir/lib/inspect/algebra.ex index ec8eae7f49..66cc3ffb87 100644 --- a/lib/elixir/lib/inspect/algebra.ex +++ b/lib/elixir/lib/inspect/algebra.ex @@ -482,7 +482,7 @@ defmodule Inspect.Algebra do and returns an IO data representation of the best layout for the document to fit in the given width. """ - @spec format(t, non_neg_integer | :infinity) :: binary + @spec format(t, non_neg_integer | :infinity) :: iodata def format(d, w) do format(w, 0, [{0, default_mode(w), doc_group(d)}]) end diff --git a/lib/elixir/lib/integer.ex b/lib/elixir/lib/integer.ex index efc3abaf4b..083326f4b5 100644 --- a/lib/elixir/lib/integer.ex +++ b/lib/elixir/lib/integer.ex @@ -111,7 +111,7 @@ defmodule Integer do "64" """ - @spec to_string(integer, pos_integer) :: String.t + @spec to_string(integer, 2..36) :: String.t def to_string(some_integer, base) do :erlang.integer_to_binary(some_integer, base) end @@ -144,7 +144,7 @@ defmodule Integer do '3FF' """ - @spec to_char_list(integer, pos_integer) :: char_list + @spec to_char_list(integer, 2..36) :: char_list def to_char_list(number, base) do :erlang.integer_to_list(number, base) end diff --git a/lib/elixir/lib/kernel.ex b/lib/elixir/lib/kernel.ex index d7a8ca5d15..83452e5a36 100644 --- a/lib/elixir/lib/kernel.ex +++ b/lib/elixir/lib/kernel.ex @@ -2384,7 +2384,7 @@ defmodule Kernel do it is not loaded. Check `Code.ensure_loaded/1` for more information. """ - @spec function_exported?(atom | tuple, atom, integer) :: boolean + @spec function_exported?(atom | tuple, atom, arity) :: boolean def function_exported?(module, function, arity) do :erlang.function_exported(module, function, arity) end diff --git a/lib/elixir/lib/kernel/cli.ex b/lib/elixir/lib/kernel/cli.ex index e5b5f57889..9700e2fb7e 100644 --- a/lib/elixir/lib/kernel/cli.ex +++ b/lib/elixir/lib/kernel/cli.ex @@ -408,7 +408,7 @@ defmodule Kernel.CLI do end defp wrapper(fun) do - fun.() + _ = fun.() :ok end diff --git a/lib/elixir/lib/keyword.ex b/lib/elixir/lib/keyword.ex index 61719b7507..6ce1df7555 100644 --- a/lib/elixir/lib/keyword.ex +++ b/lib/elixir/lib/keyword.ex @@ -136,7 +136,7 @@ defmodule Keyword do :error """ - @spec fetch(t, key) :: {:ok, value} + @spec fetch(t, key) :: {:ok, value} | :error def fetch(keywords, key) when is_list(keywords) and is_atom(key) do case :lists.keyfind(key, 1, keywords) do {^key, value} -> {:ok, value} diff --git a/lib/elixir/lib/list.ex b/lib/elixir/lib/list.ex index 31b91bade7..9ac0959944 100644 --- a/lib/elixir/lib/list.ex +++ b/lib/elixir/lib/list.ex @@ -247,7 +247,7 @@ defmodule List do [a: 1, b: 2, c: 3] """ - @spec keystore([tuple], any, non_neg_integer, tuple) :: [tuple] + @spec keystore([tuple], any, non_neg_integer, tuple) :: [tuple, ...] def keystore(list, key, position, new_tuple) do :lists.keystore(key, position + 1, list, new_tuple) end @@ -532,7 +532,7 @@ defmodule List do 1023 """ - @spec to_integer(char_list, non_neg_integer) :: integer + @spec to_integer(char_list, 2..36) :: integer def to_integer(char_list, base) do :erlang.list_to_integer(char_list, base) end diff --git a/lib/elixir/lib/module/locals_tracker.ex b/lib/elixir/lib/module/locals_tracker.ex index 26c7905ada..5554709dc5 100644 --- a/lib/elixir/lib/module/locals_tracker.ex +++ b/lib/elixir/lib/module/locals_tracker.ex @@ -360,7 +360,7 @@ defmodule Module.LocalsTracker do end defp replace_edge!(d, from, to) do - unless :lists.member(to, :digraph.out_neighbours(d, from)) do + _ = unless :lists.member(to, :digraph.out_neighbours(d, from)) do [:"$e"|_] = :digraph.add_edge(d, from, to) end :ok diff --git a/lib/elixir/lib/node.ex b/lib/elixir/lib/node.ex index 9b52e451f0..aa2c4cdbe5 100644 --- a/lib/elixir/lib/node.ex +++ b/lib/elixir/lib/node.ex @@ -30,7 +30,7 @@ defmodule Node do returns `{:error, :not_allowed}`. Returns `{:error, :not_found}` if the local node is not alive. """ - @spec stop() :: :ok | {:error, term} + @spec stop() :: :ok | {:error, :not_allowed | :not_found} def stop() do :net_kernel.stop() end diff --git a/lib/elixir/lib/process.ex b/lib/elixir/lib/process.ex index e30a148a3b..9db91a7227 100644 --- a/lib/elixir/lib/process.ex +++ b/lib/elixir/lib/process.ex @@ -345,7 +345,7 @@ defmodule Process do See http://www.erlang.org/doc/man/erlang.html#process_flag-3 for more info. """ - @spec flag(pid, process_flag, term) :: term + @spec flag(pid, :save_calls, non_neg_integer) :: non_neg_integer def flag(pid, flag, value) do :erlang.process_flag(pid, flag, value) end diff --git a/lib/elixir/lib/regex.ex b/lib/elixir/lib/regex.ex index 96af9178fc..3e9168255a 100644 --- a/lib/elixir/lib/regex.ex +++ b/lib/elixir/lib/regex.ex @@ -133,6 +133,7 @@ defmodule Regex do Compiles the regular expression according to the given options. Fails with `Regex.CompileError` if the regex cannot be compiled. """ + @spec compile(binary, binary | [term]) :: t def compile!(source, options \\ "") do case compile(source, options) do {:ok, regex} -> regex @@ -152,6 +153,7 @@ defmodule Regex do false """ + @spec match?(t, String.t) :: boolean def match?(%Regex{re_pattern: compiled}, string) when is_binary(string) do :re.run(string, compiled, [{:capture, :none}]) == :match end @@ -168,6 +170,8 @@ defmodule Regex do false """ + @spec regex?(t) :: true + @spec regex?(any) :: false def regex?(%Regex{}), do: true def regex?(_), do: false @@ -193,6 +197,7 @@ defmodule Regex do [{2,2},{3,1}] """ + @spec run(t, binary, [term]) :: nil | [binary] | [{integer, integer}] def run(regex, string, options \\ []) def run(%Regex{re_pattern: compiled}, string, options) when is_binary(string) do @@ -223,6 +228,7 @@ defmodule Regex do nil """ + @spec named_captures(t, String.t, [term]) :: map | nil def named_captures(regex, string, options \\ []) when is_binary(string) do names = names(regex) options = Keyword.put(options, :capture, names) @@ -233,6 +239,7 @@ defmodule Regex do @doc """ Returns the underlying `re_pattern` in the regular expression. """ + @spec re_pattern(t) :: term def re_pattern(%Regex{re_pattern: compiled}) do compiled end @@ -246,6 +253,7 @@ defmodule Regex do "foo" """ + @spec source(t) :: String.t def source(%Regex{source: source}) do source end @@ -259,6 +267,7 @@ defmodule Regex do "m" """ + @spec opts(t) :: String.t def opts(%Regex{opts: opts}) do opts end @@ -272,6 +281,7 @@ defmodule Regex do ["foo"] """ + @spec names(t) :: [String.t] def names(%Regex{re_pattern: re_pattern}) do {:namelist, names} = :re.inspect(re_pattern, :namelist) names @@ -301,6 +311,7 @@ defmodule Regex do [] """ + @spec scan(t, String.t, [term]) :: [[String.t]] def scan(regex, string, options \\ []) def scan(%Regex{re_pattern: compiled}, string, options) when is_binary(string) do @@ -353,7 +364,7 @@ defmodule Regex do ["a", "c"] """ - + @spec split(t, String.t, [term]) :: [String.t] def split(regex, string, options \\ []) def split(%Regex{}, "", _opts), do: [""] @@ -439,6 +450,7 @@ defmodule Regex do "[b][d]" """ + @spec replace(t, String.t, String.t | (... -> String.t), [term]) :: String.t def replace(regex, string, replacement, options \\ []) def replace(regex, string, replacement, options) when is_binary(replacement) do diff --git a/lib/elixir/lib/string.ex b/lib/elixir/lib/string.ex index 317e2c0d16..018539a3c6 100644 --- a/lib/elixir/lib/string.ex +++ b/lib/elixir/lib/string.ex @@ -1423,7 +1423,7 @@ defmodule String do 1023 """ - @spec to_integer(String.t, pos_integer) :: integer + @spec to_integer(String.t, 2..36) :: integer def to_integer(string, base) do :erlang.binary_to_integer(string, base) end diff --git a/lib/elixir/lib/supervisor.ex b/lib/elixir/lib/supervisor.ex index b7ff965945..4d1f631d9f 100644 --- a/lib/elixir/lib/supervisor.ex +++ b/lib/elixir/lib/supervisor.ex @@ -391,8 +391,8 @@ defmodule Supervisor do """ @spec count_children(supervisor) :: - [specs: non_neg_integer, active: non_neg_integer, - supervisors: non_neg_integer, workers: non_neg_integer] + %{specs: non_neg_integer, active: non_neg_integer, + supervisors: non_neg_integer, workers: non_neg_integer} def count_children(supervisor) do call(supervisor, :count_children) |> :maps.from_list end diff --git a/lib/elixir/src/elixir_errors.erl b/lib/elixir/src/elixir_errors.erl index e09e8a0c09..c49c5c49ef 100644 --- a/lib/elixir/src/elixir_errors.erl +++ b/lib/elixir/src/elixir_errors.erl @@ -6,12 +6,12 @@ handle_file_warning/2, handle_file_warning/3, handle_file_error/2]). -include("elixir.hrl"). --spec warn(non_neg_integer(), binary(), iolist()) -> ok. +-spec warn(non_neg_integer(), binary(), unicode:chardata()) -> ok. warn(Line, File, Warning) when is_integer(Line), is_binary(File) -> warn(file_format(Line, File), Warning). --spec warn(iolist(), iolist()) -> ok. +-spec warn(unicode:chardata(), unicode:chardata()) -> ok. warn(Caller, Warning) -> do_warn([Caller, "warning: ", Warning, $\n]). @@ -31,8 +31,8 @@ form_warn(Meta, File, Module, Desc) when is_list(Meta) -> %% Compilation error. --spec compile_error(list(), binary(), iolist()) -> no_return(). --spec compile_error(list(), binary(), iolist(), list()) -> no_return(). +-spec compile_error(list(), binary(), unicode:charlist()) -> no_return(). +-spec compile_error(list(), binary(), string(), list()) -> no_return(). compile_error(Meta, File, Message) when is_list(Message) -> raise(Meta, File, 'Elixir.CompileError', elixir_utils:characters_to_binary(Message)). @@ -241,4 +241,4 @@ do_raise(Line, File, Kind, Message) when is_integer(Line), is_binary(File), is_b end, Stacktrace = erlang:get_stacktrace(), Exception = Kind:exception([{description, Message}, {file, File}, {line, Line}]), - erlang:raise(error, Exception, tl(Stacktrace)). \ No newline at end of file + erlang:raise(error, Exception, tl(Stacktrace)).