Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package elixir for openSUSE:Factory checked in at 2022-04-10 19:05:43 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/elixir (Old) and /work/SRC/openSUSE:Factory/.elixir.new.1900 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "elixir" Sun Apr 10 19:05:43 2022 rev:22 rq:968216 version:1.13.4 Changes: -------- --- /work/SRC/openSUSE:Factory/elixir/elixir.changes 2022-02-27 22:43:21.294635008 +0100 +++ /work/SRC/openSUSE:Factory/.elixir.new.1900/elixir.changes 2022-04-10 19:06:00.450099025 +0200 @@ -1,0 +2,23 @@ +Sat Apr 9 11:16:39 UTC 2022 - Fabrizio Sestito <fabrizio.sest...@suse.com> + +- Elixir 1.13.4 + * 1. Enhancements + Elixir + + [Code] Allow iodata to be returned in sigil formatting functions + [Code] Pass opening delimiter information to sigil formatting functions + + * 2. Bug fixes + Elixir + + [Kernel] Tweak type unification to fix infinite loop with recursive vars + [Kernel] Add compile-time dependencies on require + [Registry] Make Registry send work with named triplets + + * 3. Deprecations + Mix + + [mix rebar] Deprecate Rebar 2 as it no longer works on Erlang/OTP 25 + + +------------------------------------------------------------------- Old: ---- elixir-1.13.3.tar.gz New: ---- elixir-1.13.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ elixir-doc.spec ++++++ --- /var/tmp/diff_new_pack.Iludqv/_old 2022-04-10 19:06:01.094091895 +0200 +++ /var/tmp/diff_new_pack.Iludqv/_new 2022-04-10 19:06:01.098091851 +0200 @@ -17,7 +17,7 @@ Name: elixir-doc -Version: 1.13.3 +Version: 1.13.4 Release: 0 Summary: Documentation for elixir License: Apache-2.0 elixir.spec: same change ++++++ elixir-1.13.3.tar.gz -> elixir-1.13.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/.github/workflows/ci.yml new/elixir-1.13.4/.github/workflows/ci.yml --- old/elixir-1.13.3/.github/workflows/ci.yml 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/.github/workflows/ci.yml 2022-04-07 08:08:02.000000000 +0200 @@ -14,7 +14,7 @@ strategy: fail-fast: false matrix: - otp_release: ['OTP-24.0', 'OTP-23.3', 'OTP-23.0', 'OTP-22.3', 'OTP-22.0'] + otp_release: ['OTP-24.3', 'OTP-24.0', 'OTP-23.3', 'OTP-23.0', 'OTP-22.3', 'OTP-22.0'] development: [false] include: - otp_release: master diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/CHANGELOG.md new/elixir-1.13.4/CHANGELOG.md --- old/elixir-1.13.3/CHANGELOG.md 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/CHANGELOG.md 2022-04-07 08:08:02.000000000 +0200 @@ -128,6 +128,31 @@ Finally, the `Code` module has also been augmented with two functions: `Code.string_to_quoted_with_comments/2` and `Code.quoted_to_algebra/2`. Those functions allow someone to retrieve the Elixir AST with their original source code comments, and then convert this AST to formatted code. In other words, those functions provide a wrapper around the Elixir Code Formatter, supporting developers who wish to create tools that directly manipulate and custom format Elixir source code. +## v1.13.4 (2022-04-07) + +This release has been verified to work with Erlang/OTP 25 RC2. + +### 1. Enhancements + +#### Elixir + + * [Code] Allow iodata to be returned in sigil formatting functions + * [Code] Pass opening delimiter information to sigil formatting functions + +### 2. Bug fixes + +#### Elixir + + * [Kernel] Tweak type unification to fix infinite loop with recursive vars + * [Kernel] Add compile-time dependencies on `require` + * [Registry] Make `Registry` send work with named triplets + +### 3. Deprecations + +#### Mix + + * [mix rebar] Deprecate Rebar 2 as it no longer works on Erlang/OTP 25 + ## v1.13.3 (2022-02-09) ### 1. Enhancements diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/Makefile new/elixir-1.13.4/Makefile --- old/elixir-1.13.3/Makefile 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/Makefile 2022-04-07 08:08:02.000000000 +0200 @@ -171,6 +171,7 @@ rm -rf lib/mix/test/fixtures/git_rebar/ rm -rf lib/mix/test/fixtures/git_repo/ rm -rf lib/mix/test/fixtures/git_sparse_repo/ + rm -rf lib/mix/test/fixtures/archive/ebin/ rm -f erl_crash.dump $(Q) $(MAKE) clean_man diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/VERSION new/elixir-1.13.4/VERSION --- old/elixir-1.13.3/VERSION 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/VERSION 2022-04-07 08:08:02.000000000 +0200 @@ -1 +1 @@ -1.13.3 \ No newline at end of file +1.13.4 \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/bin/elixir new/elixir-1.13.4/bin/elixir --- old/elixir-1.13.3/bin/elixir 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/bin/elixir 2022-04-07 08:08:02.000000000 +0200 @@ -1,7 +1,7 @@ #!/bin/sh set -e -ELIXIR_VERSION=1.13.3 +ELIXIR_VERSION=1.13.4 if [ $# -eq 0 ] || { [ $# -eq 1 ] && { [ "$1" = "--help" ] || [ "$1" = "-h" ]; }; }; then cat <<USAGE >&2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/bin/elixir.bat new/elixir-1.13.4/bin/elixir.bat --- old/elixir-1.13.3/bin/elixir.bat 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/bin/elixir.bat 2022-04-07 08:08:02.000000000 +0200 @@ -1,6 +1,6 @@ @if defined ELIXIR_CLI_ECHO (@echo on) else (@echo off) -set ELIXIR_VERSION=1.13.3 +set ELIXIR_VERSION=1.13.4 setlocal enabledelayedexpansion if ""%1""=="""" if ""%2""=="""" goto documentation diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/elixir/lib/base.ex new/elixir-1.13.4/lib/elixir/lib/base.ex --- old/elixir-1.13.3/lib/elixir/lib/base.ex 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/elixir/lib/base.ex 2022-04-07 08:08:02.000000000 +0200 @@ -340,7 +340,7 @@ "foobar" """ - @spec decode16!(binary, case: encode_case) :: binary + @spec decode16!(binary, case: decode_case) :: binary def decode16!(string, opts \\ []) def decode16!(string, opts) when is_binary(string) and rem(byte_size(string), 2) == 0 do diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/elixir/lib/code/formatter.ex new/elixir-1.13.4/lib/elixir/lib/code/formatter.ex --- old/elixir-1.13.3/lib/elixir/lib/code/formatter.ex 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/elixir/lib/code/formatter.ex 2022-04-07 08:08:02.000000000 +0200 @@ -1326,16 +1326,17 @@ file: state.file, line: meta[:line], sigil: List.to_atom([name]), - modifiers: modifiers + modifiers: modifiers, + opening_delimiter: opening_delimiter ] case callback.(hd(entries), metadata) do - binary when is_binary(binary) -> - [binary] + iodata when is_binary(iodata) or is_list(iodata) -> + [IO.iodata_to_binary(iodata)] other -> raise ArgumentError, - "expected sigil callback to return a binary, got: #{inspect(other)}" + "expected sigil callback to return iodata, got: #{inspect(other)}" end %{} -> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/elixir/lib/kernel/lexical_tracker.ex new/elixir-1.13.4/lib/elixir/lib/kernel/lexical_tracker.ex --- old/elixir-1.13.3/lib/elixir/lib/kernel/lexical_tracker.ex 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/elixir/lib/kernel/lexical_tracker.ex 2022-04-07 08:08:02.000000000 +0200 @@ -30,8 +30,8 @@ end @doc false - def add_require(pid, module) when is_atom(module) do - :gen_server.cast(pid, {:add_require, module}) + def add_export(pid, module) when is_atom(module) do + :gen_server.cast(pid, {:add_export, module}) end @doc false @@ -168,15 +168,16 @@ {:noreply, update_in(state.compile_env, &:ordsets.add_element({app, path, return}, &1))} end - def handle_cast({:add_require, module}, state) do + def handle_cast({:add_export, module}, state) do {:noreply, put_in(state.exports[module], true)} end def handle_cast({:add_import, module, fas, line, warn}, state) do - to_remove = for {{:import, {^module, _, _}} = key, _} <- state.directives, do: key + %{directives: directives, exports: exports} = state + to_remove = for {{:import, {^module, _, _}} = key, _} <- directives, do: key directives = - state.directives + directives |> Map.drop(to_remove) |> add_directive(module, line, warn, :import) @@ -185,7 +186,7 @@ add_directive(directives, {module, function, arity}, line, warn, :import) end) - {:noreply, %{state | directives: directives}} + {:noreply, %{state | directives: directives, exports: Map.put(exports, module, true)}} end def handle_cast({:add_alias, module, line, warn}, state) do @@ -221,9 +222,9 @@ do: Map.put(references, module, :compile) defp add_reference(references, module, :runtime) when is_atom(module) do - case Map.fetch(references, module) do - {:ok, _} -> references - :error -> Map.put(references, module, :runtime) + case references do + %{^module => _} -> references + _ -> Map.put(references, module, :runtime) end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/elixir/lib/kernel/special_forms.ex new/elixir-1.13.4/lib/elixir/lib/kernel/special_forms.ex --- old/elixir-1.13.3/lib/elixir/lib/kernel/special_forms.ex 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/elixir/lib/kernel/special_forms.ex 2022-04-07 08:08:02.000000000 +0200 @@ -554,7 +554,9 @@ defmacro alias(module, opts), do: error!([module, opts]) @doc """ - Requires a module in order to use its macros. + Requires a module as a compile-time dependency. + + Requiring a module is necessary in order to use its macros. ## Examples @@ -576,7 +578,6 @@ `require/2` also accepts `:as` as an option so it automatically sets up an alias. Please check `alias/2` for more information. - """ defmacro require(module, opts), do: error!([module, opts]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/elixir/lib/module/types/unify.ex new/elixir-1.13.4/lib/elixir/lib/module/types/unify.ex --- old/elixir-1.13.3/lib/elixir/lib/module/types/unify.ex 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/elixir/lib/module/types/unify.ex 2022-04-07 08:08:02.000000000 +0200 @@ -43,14 +43,14 @@ {:ok, same, context} end - def unify(type, {:var, var}, stack, context) do - unify_var(var, type, stack, context, _var_source = false) - end - def unify({:var, var}, type, stack, context) do unify_var(var, type, stack, context, _var_source = true) end + def unify(type, {:var, var}, stack, context) do + unify_var(var, type, stack, context, _var_source = false) + end + def unify({:tuple, n, sources}, {:tuple, n, targets}, stack, context) do result = map_reduce_ok(Enum.zip(sources, targets), context, fn {source, target}, context -> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/elixir/lib/module.ex new/elixir-1.13.4/lib/elixir/lib/module.ex --- old/elixir-1.13.3/lib/elixir/lib/module.ex 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/elixir/lib/module.ex 2022-04-07 08:08:02.000000000 +0200 @@ -1811,7 +1811,8 @@ acc true -> - :elixir_env.trace({:require, [], behaviour, []}, env) + event = {:remote_function, [], behaviour, :behaviour_info, 1} + :elixir_env.trace(event, %{env | function: {:__info__, 1}}) optional_callbacks = behaviour_info(behaviour, :optional_callbacks) callbacks = behaviour_info(behaviour, :callbacks) Enum.reduce(callbacks, acc, &add_callback(&1, behaviour, env, optional_callbacks, &2)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/elixir/lib/registry.ex new/elixir-1.13.4/lib/elixir/lib/registry.ex --- old/elixir-1.13.3/lib/elixir/lib/registry.ex 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/elixir/lib/registry.ex 2022-04-07 08:08:02.000000000 +0200 @@ -260,6 +260,10 @@ end end + def send({registry, key, _value}, msg) do + Registry.send({registry, key}, msg) + end + @doc false def unregister_name({registry, key}), do: unregister(registry, key) def unregister_name({registry, key, _value}), do: unregister(registry, key) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/elixir/lib/uri.ex new/elixir-1.13.4/lib/elixir/lib/uri.ex --- old/elixir-1.13.3/lib/elixir/lib/uri.ex 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/elixir/lib/uri.ex 2022-04-07 08:08:02.000000000 +0200 @@ -37,6 +37,7 @@ defmodule Error do defexception [:action, :reason, :part] + @doc false def message(%Error{action: action, reason: reason, part: part}) do "cannot #{action} due to reason #{reason}: #{inspect(part)}" end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/elixir/src/elixir_expand.erl new/elixir-1.13.4/lib/elixir/src/elixir_expand.erl --- old/elixir-1.13.3/lib/elixir/src/elixir_expand.erl 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/elixir/src/elixir_expand.erl 2022-04-07 08:08:02.000000000 +0200 @@ -85,6 +85,7 @@ if is_atom(ERef) -> elixir_aliases:ensure_loaded(Meta, ERef, ET), + elixir_env:trace({require, Meta, ERef, EOpts}, ET), {ERef, ST, expand_require(Meta, ERef, EOpts, ET)}; true -> form_error(Meta, E, ?MODULE, {expected_compile_time_module, require, Ref}) @@ -931,7 +932,6 @@ Other. expand_require(Meta, Ref, Opts, E) -> - elixir_env:trace({require, Meta, Ref, Opts}, E), RE = E#{requires := ordsets:add_element(Ref, ?key(E, requires))}, expand_alias(Meta, false, Ref, Opts, RE). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/elixir/src/elixir_lexical.erl new/elixir-1.13.4/lib/elixir/src/elixir_lexical.erl --- old/elixir-1.13.3/lib/elixir/src/elixir_lexical.erl 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/elixir/src/elixir_lexical.erl 2022-04-07 08:08:02.000000000 +0200 @@ -47,10 +47,10 @@ ?tracker:alias_dispatch(Pid, Lookup), ok; trace({require, _Meta, Module, _Opts}, #{lexical_tracker := Pid}) -> - ?tracker:add_require(Pid, Module), + ?tracker:remote_dispatch(Pid, Module, compile), ok; trace({struct_expansion, _Meta, Module, _Keys}, #{lexical_tracker := Pid}) -> - ?tracker:add_require(Pid, Module), + ?tracker:add_export(Pid, Module), ok; trace({alias_reference, _Meta, Module}, #{lexical_tracker := Pid} = E) -> ?tracker:remote_dispatch(Pid, Module, mode(E)), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/elixir/test/elixir/code_formatter/general_test.exs new/elixir-1.13.4/lib/elixir/test/elixir/code_formatter/general_test.exs --- old/elixir-1.13.3/lib/elixir/test/elixir/code_formatter/general_test.exs 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/elixir/test/elixir/code_formatter/general_test.exs 2022-04-07 08:08:02.000000000 +0200 @@ -126,23 +126,23 @@ """ formatter = fn content, opts -> - assert opts == [file: nil, line: 1, sigil: :W, modifiers: []] + assert opts == [file: nil, line: 1, sigil: :W, modifiers: [], opening_delimiter: "/"] content |> String.split(~r/ +/) |> Enum.join(" ") end assert_format bad, good, sigils: [W: formatter] bad = """ - var = ~W/foo bar baz/abc + var = ~W<foo bar baz>abc """ good = """ - var = ~W/foo bar baz/abc + var = ~W<foo bar baz>abc """ formatter = fn content, opts -> - assert opts == [file: nil, line: 1, sigil: :W, modifiers: 'abc'] - content |> String.split(~r/ +/) |> Enum.join(" ") + assert opts == [file: nil, line: 1, sigil: :W, modifiers: 'abc', opening_delimiter: "<"] + content |> String.split(~r/ +/) |> Enum.intersperse(" ") end assert_format bad, good, sigils: [W: formatter] @@ -162,34 +162,41 @@ """ formatter = fn content, opts -> - assert opts == [file: nil, line: 1, sigil: :W, modifiers: []] + assert opts == [file: nil, line: 1, sigil: :W, modifiers: [], opening_delimiter: "'''"] content |> String.split(~r/ +/) |> Enum.join(" ") end assert_format bad, good, sigils: [W: formatter] - bad = """ + bad = ~S''' if true do - ~W''' + ~W""" foo bar baz - '''abc + """abc end - """ + ''' - good = """ + good = ~S''' if true do - ~W''' + ~W""" foo bar baz - '''abc + """abc end - """ + ''' formatter = fn content, opts -> - assert opts == [file: nil, line: 2, sigil: :W, modifiers: 'abc'] + assert opts == [ + file: nil, + line: 2, + sigil: :W, + modifiers: 'abc', + opening_delimiter: ~S/"""/ + ] + content |> String.split(~r/ +/) |> Enum.join("\n") end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/elixir/test/elixir/code_test.exs new/elixir-1.13.4/lib/elixir/test/elixir/code_test.exs --- old/elixir-1.13.3/lib/elixir/test/elixir/code_test.exs 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/elixir/test/elixir/code_test.exs 2022-04-07 08:08:02.000000000 +0200 @@ -78,18 +78,20 @@ end end - test "raises streamlined argument errors" do - assert_raise ArgumentError, - ~r"argument error while evaluating at line 1", - fn -> Code.eval_string("a <> b", a: :a, b: :b) end + if System.otp_release() < "25" do + test "raises streamlined argument errors" do + assert_raise ArgumentError, + ~r"argument error while evaluating at line 1", + fn -> Code.eval_string("a <> b", a: :a, b: :b) end - assert_raise ArgumentError, - ~r"argument error while evaluating example.ex at line 1", - fn -> Code.eval_string("a <> b", [a: :a, b: :b], file: "example.ex") end + assert_raise ArgumentError, + ~r"argument error while evaluating example.ex at line 1", + fn -> Code.eval_string("a <> b", [a: :a, b: :b], file: "example.ex") end - assert_raise ArgumentError, - ~r"argument error while evaluating example.ex between lines 1 and 2", - fn -> Code.eval_string("a <>\nb", [a: :a, b: :b], file: "example.ex") end + assert_raise ArgumentError, + ~r"argument error while evaluating example.ex between lines 1 and 2", + fn -> Code.eval_string("a <>\nb", [a: :a, b: :b], file: "example.ex") end + end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/elixir/test/elixir/kernel/lexical_tracker_test.exs new/elixir-1.13.4/lib/elixir/test/elixir/kernel/lexical_tracker_test.exs --- old/elixir-1.13.3/lib/elixir/test/elixir/kernel/lexical_tracker_test.exs 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/elixir/test/elixir/kernel/lexical_tracker_test.exs 2022-04-07 08:08:02.000000000 +0200 @@ -21,8 +21,8 @@ assert D.references(config[:pid]) == {[String], [], [], []} end - test "can add requires", config do - D.add_require(config[:pid], URI) + test "can add module requires and exports", config do + D.add_export(config[:pid], URI) assert D.references(config[:pid]) == {[], [URI], [], []} D.remote_dispatch(config[:pid], URI, :runtime) @@ -33,7 +33,6 @@ end test "can add module imports", config do - D.add_require(config[:pid], String) D.add_import(config[:pid], String, [], 1, true) D.import_dispatch(config[:pid], String, {:upcase, 1}, :runtime) @@ -44,7 +43,7 @@ end test "can add module with {function, arity} imports", config do - D.add_require(config[:pid], String) + D.add_export(config[:pid], String) D.add_import(config[:pid], String, [upcase: 1], 1, true) D.import_dispatch(config[:pid], String, {:upcase, 1}, :compile) @@ -181,18 +180,18 @@ {{compile, _exports, runtime, _}, _binding} = Code.eval_string(""" defmodule Kernel.LexicalTrackerTest.Defdelegate do - defdelegate a, to: A + defdelegate parse(arg), to: URI - opts = [to: B] - defdelegate b, opts + opts = [to: Range] + defdelegate disjoint?(left, right), opts Kernel.LexicalTracker.references(__ENV__.lexical_tracker) end |> elem(3) """) - refute A in compile - assert B in compile - assert A in runtime + refute URI in compile + assert Range in compile + assert URI in runtime end test "imports adds an export dependency" do @@ -209,6 +208,20 @@ refute String in runtime end + test "requires adds a compile dependency" do + {{compile, exports, runtime, _}, _binding} = + Code.eval_string(""" + defmodule Kernel.LexicalTrackerTest.Requires do + require String + Kernel.LexicalTracker.references(__ENV__.lexical_tracker) + end |> elem(3) + """) + + assert String in compile + refute String in exports + refute String in runtime + end + test "structs are exports or compile time" do {{compile, exports, runtime, _}, _binding} = Code.eval_string(""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/elixir/test/elixir/module/locals_tracker_test.exs new/elixir-1.13.4/lib/elixir/test/elixir/module/locals_tracker_test.exs --- old/elixir-1.13.3/lib/elixir/test/elixir/module/locals_tracker_test.exs 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/elixir/test/elixir/module/locals_tracker_test.exs 2022-04-07 08:08:02.000000000 +0200 @@ -119,7 +119,6 @@ end test "does not include unreachable locals" do - assert NoPrivate.module_info(:functions) == - [__info__: 1, baz: 0, module_info: 0, module_info: 1] + assert NoPrivate.module_info(:functions) |> Keyword.take([:foo, :bar, :"MACRO-foo"]) == [] end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/elixir/test/elixir/module/types/types_test.exs new/elixir-1.13.4/lib/elixir/test/elixir/module/types/types_test.exs --- old/elixir-1.13.3/lib/elixir/test/elixir/module/types/types_test.exs 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/elixir/test/elixir/module/types/types_test.exs 2022-04-07 08:08:02.000000000 +0200 @@ -200,20 +200,20 @@ # types_test.ex:1 is_binary(y) - where "y" was given the same type as "x" in: + where "x" was given the same type as "y" in: # types_test.ex:1 x = y - where "y" was given the type binary() in: + where "y" was given the type integer() in: # types_test.ex:1 - is_binary(y) + is_integer(x) - where "x" was given the type integer() in: + where "y" was given the type binary() in: # types_test.ex:1 - is_integer(x) + is_binary(y) """ end @@ -256,20 +256,20 @@ # types_test.ex:1 is_binary(y) - where "y" was given the same type as "x" in: + where "x" was given the same type as "y" in: # types_test.ex:1 x = y - where "y" was given the type binary() in: + where "y" was given the type integer() in: # types_test.ex:1 - is_binary(y) + is_integer(x) - where "x" was given the type integer() in: + where "y" was given the type binary() in: # types_test.ex:1 - is_integer(x) + is_binary(y) """ end @@ -443,7 +443,17 @@ # types_test.ex:5 %{"id" => user_id} = user - where "user" was given the same type as "amount" in: + where "amount" was given the type binary() in: + + # types_test.ex:3 + %{"amount" => amount} = event + + where "amount" was given the same type as "user" in: + + # types_test.ex:4 + %{"user" => user} = event + + where "user" was given the type binary() in: # types_test.ex:4 %{"user" => user} = event @@ -452,11 +462,6 @@ # types_test.ex:5 %{"id" => user_id} = user - - where "amount" was given the type binary() in: - - # types_test.ex:3 - %{"amount" => amount} = event """ end @@ -700,5 +705,32 @@ ) ) == :none end + + test "other recursive" do + assert warning( + [x, y], + ( + key_var = y + %{^key_var => _value} = x + key_var2 = y + %{^key_var2 => _value2} = x + y.z + ) + ) == :none + end + + test "other recursive2" do + assert warning( + [x, y], + ( + key_var = y + %{^key_var => _value} = x + key_var2 = y + %{^key_var2 => _value2} = x + key_var3 = y + %{^key_var3 => _value3} = x + ) + ) == :none + end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/elixir/test/elixir/module/types/unify_test.exs new/elixir-1.13.4/lib/elixir/test/elixir/module/types/unify_test.exs --- old/elixir-1.13.3/lib/elixir/test/elixir/module/types/unify_test.exs 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/elixir/test/elixir/module/types/unify_test.exs 2022-04-07 08:08:02.000000000 +0200 @@ -502,25 +502,25 @@ assert {:ok, {:var, _}, context} = unify({:var, 0}, :tuple, var_context) assert {:ok, {:var, _}, context} = unify({:var, 1}, {:var, 0}, context) assert {:ok, {:var, _}, context} = unify({:var, 0}, {:var, 1}, context) - assert context.types[0] == {:var, 1} - assert context.types[1] == :tuple + assert context.types[0] == :tuple + assert context.types[1] == {:var, 0} assert {:ok, {:var, _}, context} = unify({:var, 0}, {:var, 1}, var_context) assert {:ok, {:var, _}, context} = unify({:var, 1}, {:var, 2}, context) assert {:ok, {:var, _}, _context} = unify({:var, 2}, {:var, 0}, context) - assert context.types[0] == :unbound - assert context.types[1] == {:var, 0} - assert context.types[2] == {:var, 1} + assert context.types[0] == {:var, 1} + assert context.types[1] == {:var, 2} + assert context.types[2] == :unbound assert {:ok, {:var, _}, context} = unify({:var, 0}, {:var, 1}, var_context) - assert {:error, {:unable_unify, {{:var, 0}, {:tuple, 1, [{:var, 0}]}, _}}} = + assert {:error, {:unable_unify, {{:var, 1}, {:tuple, 1, [{:var, 0}]}, _}}} = unify_lift({:var, 1}, {:tuple, 1, [{:var, 0}]}, context) assert {:ok, {:var, _}, context} = unify({:var, 0}, {:var, 1}, var_context) assert {:ok, {:var, _}, context} = unify({:var, 1}, {:var, 2}, context) - assert {:error, {:unable_unify, {{:var, 0}, {:tuple, 1, [{:var, 0}]}, _}}} = + assert {:error, {:unable_unify, {{:var, 2}, {:tuple, 1, [{:var, 0}]}, _}}} = unify_lift({:var, 2}, {:tuple, 1, [{:var, 0}]}, context) end @@ -707,9 +707,9 @@ {{:var, 0}, var_context} = new_var({:foo, [version: 0], nil}, new_context()) {{:var, 1}, var_context} = new_var({:bar, [version: 1], nil}, var_context) - {:ok, {:var, 1}, var_context} = unify({:var, 0}, {:var, 1}, var_context) - assert flatten_union({:var, 0}, var_context) == [{:var, 0}] - assert flatten_union({:var, 1}, var_context) == [{:var, 0}] + {:ok, {:var, 0}, var_context} = unify({:var, 0}, {:var, 1}, var_context) + assert flatten_union({:var, 0}, var_context) == [{:var, 1}] + assert flatten_union({:var, 1}, var_context) == [{:var, 1}] end test "format_type/1" do diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/elixir/test/elixir/registry_test.exs new/elixir-1.13.4/lib/elixir/test/elixir/registry_test.exs --- old/elixir-1.13.3/lib/elixir/test/elixir/registry_test.exs 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/elixir/test/elixir/registry_test.exs 2022-04-07 08:08:02.000000000 +0200 @@ -896,6 +896,20 @@ assert {%RuntimeError{message: "some error"}, _stacktrace} = error end + test "send works", %{registry: registry} do + name = {registry, "self"} + Registry.register_name(name, self()) + GenServer.cast({:via, Registry, name}, :message) + assert_received {:"$gen_cast", :message} + end + + test "send works with value", %{registry: registry} do + name = {registry, "self", "value"} + Registry.register_name(name, self()) + GenServer.cast({:via, Registry, name}, :message) + assert_received {:"$gen_cast", :message} + end + defp register_task(registry, key, value) do parent = self() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/mix/lib/mix/dep/loader.ex new/elixir-1.13.4/lib/mix/lib/mix/dep/loader.ex --- old/elixir-1.13.3/lib/mix/lib/mix/dep/loader.ex 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/mix/lib/mix/dep/loader.ex 2022-04-07 08:08:02.000000000 +0200 @@ -90,6 +90,15 @@ # 4. Inferred from files in dependency (mix.exs, rebar.config, Makefile) manager = opts[:manager] || scm_manager(scm, opts) || manager || infer_manager(opts[:dest]) + # TODO: Remove rebar2 support on Elixir v1.15+. + if manager == :rebar do + Mix.shell().error( + "dependency #{inspect(dep.app)} is using Rebar 2, " <> + "which is no longer maintained and no longer works in recent Erlang/OTP versions. " <> + "Remove the :manager option or set it to :rebar3 instead" + ) + end + dep = %{dep | manager: manager, status: scm_status(scm, opts)} {dep, children} = diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/mix/lib/mix/tasks/xref.ex new/elixir-1.13.4/lib/mix/lib/mix/tasks/xref.ex --- old/elixir-1.13.3/lib/mix/lib/mix/tasks/xref.ex 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/mix/lib/mix/tasks/xref.ex 2022-04-07 08:08:02.000000000 +0200 @@ -510,13 +510,16 @@ @doc false def trace({:require, meta, module, _opts}, env), - do: add_trace(:export, :require, module, module, meta, env) + do: add_trace(:compile, :require, module, module, meta, env) + + def trace({:import, meta, module, _opts}, env), + do: add_trace(:export, :import, module, module, meta, env) def trace({:struct_expansion, meta, module, _keys}, env), do: add_trace(:export, :struct, module, module, meta, env) def trace({:alias_reference, meta, module}, env) when env.module != module, - do: add_trace(mode(env), :alias, module, module, meta, env) + do: add_trace(mode(env), :module, module, module, meta, env) def trace({:remote_function, meta, module, function, arity}, env), do: add_trace(mode(env), :call, module, {module, function, arity}, meta, env) @@ -551,14 +554,14 @@ # We don't want to show aliases if there is an entry of the same type non_aliases = for {_file, _line, module_or_mfa, mode, type} <- entries, - type != :alias, + type != :module, into: %{}, do: {{trace_module(module_or_mfa), mode}, []} shell = Mix.shell() for {file, line, module_or_mfa, mode, type} <- entries, - type != :alias or not Map.has_key?(non_aliases, {module_or_mfa, mode}) do + type != :module or not Map.has_key?(non_aliases, {module_or_mfa, mode}) do shell.info([ Exception.format_file_line(Path.relative_to_cwd(file), line), ?\s, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/mix/test/fixtures/.gitignore new/elixir-1.13.4/lib/mix/test/fixtures/.gitignore --- old/elixir-1.13.3/lib/mix/test/fixtures/.gitignore 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/mix/test/fixtures/.gitignore 2022-04-07 08:08:02.000000000 +0200 @@ -4,3 +4,4 @@ /git_rebar/ /git_repo/ /git_sparse_repo/ +/archive/ebin/ Binary files old/elixir-1.13.3/lib/mix/test/fixtures/archive/ebin/Elixir.Mix.Tasks.Local.Sample.beam and new/elixir-1.13.4/lib/mix/test/fixtures/archive/ebin/Elixir.Mix.Tasks.Local.Sample.beam differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/mix/test/fixtures/archive/ebin/local_sample.app new/elixir-1.13.4/lib/mix/test/fixtures/archive/ebin/local_sample.app --- old/elixir-1.13.3/lib/mix/test/fixtures/archive/ebin/local_sample.app 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/mix/test/fixtures/archive/ebin/local_sample.app 1970-01-01 01:00:00.000000000 +0100 @@ -1,3 +0,0 @@ -{application,local_sample, - [{modules,['Elixir.Mix.Tasks.Local.Sample']}, - {applications,[kernel,stdlib,elixir]}]}. Binary files old/elixir-1.13.3/lib/mix/test/fixtures/rebar3 and new/elixir-1.13.4/lib/mix/test/fixtures/rebar3 differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/mix/test/mix/dep_test.exs new/elixir-1.13.4/lib/mix/test/mix/dep_test.exs --- old/elixir-1.13.3/lib/mix/test/mix/dep_test.exs 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/mix/test/mix/dep_test.exs 2022-04-07 08:08:02.000000000 +0200 @@ -496,8 +496,11 @@ with_deps(deps, fn -> in_fixture("deps_status", fn -> - assert Enum.map(Mix.Dep.load_on_environment([]), & &1.app) == - [:git_repo, :abc_repo, :deps_repo] + # Both orders below are valid after topological sort + assert Enum.map(Mix.Dep.load_on_environment([]), & &1.app) in [ + [:git_repo, :abc_repo, :deps_repo], + [:abc_repo, :git_repo, :deps_repo] + ] assert Map.keys(Mix.Project.deps_paths()) == [:abc_repo, :deps_repo, :git_repo] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/mix/test/mix/rebar_test.exs new/elixir-1.13.4/lib/mix/test/mix/rebar_test.exs --- old/elixir-1.13.3/lib/mix/test/mix/rebar_test.exs 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/mix/test/mix/rebar_test.exs 2022-04-07 08:08:02.000000000 +0200 @@ -202,7 +202,7 @@ # We run only on Unix because Windows has a hard time # removing the Rebar executable after executed. - @tag [unix: true] + @tag :unix test "gets and compiles dependencies" do in_tmp("get and compile dependencies", fn -> Mix.Project.push(RebarAsDep) @@ -256,7 +256,7 @@ # We run only on Unix because Windows has a hard time # removing the Rebar executable after executed. - @tag [unix: true] + @tag :unix test "applies variables from :system_env option when compiling dependencies" do in_tmp("applies variables from system_env", fn -> Mix.Project.push(RebarAsDepWithEnv) @@ -295,6 +295,7 @@ File.rm(MixTest.Case.tmp_path("rebar_dep/mix.exs")) end + @tag :rebar test "gets and compiles dependencies with Rebar2" do in_tmp("get and compile dependencies for Rebar2", fn -> Mix.Project.push(Rebar2AsDep) @@ -328,7 +329,8 @@ # We run only on Unix because Windows has a hard time # removing the Rebar executable after executed. - @tag [unix: true] + @tag :unix + @tag :rebar test "applies variables from :system_env option when compiling dependencies for Rebar2" do in_tmp("applies variables from system_env for Rebar2", fn -> Mix.Project.push(Rebar2AsDep) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/mix/test/mix/tasks/test_test.exs new/elixir-1.13.4/lib/mix/test/mix/tasks/test_test.exs --- old/elixir-1.13.3/lib/mix/test/mix/tasks/test_test.exs 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/mix/test/mix/tasks/test_test.exs 2022-04-07 08:08:02.000000000 +0200 @@ -433,9 +433,14 @@ in_fixture("umbrella_test", fn -> # Run false positive test first so at least the code is compiled # and we can perform more aggressive assertions later - assert mix(["test", "apps/unknown_app/test"]) =~ """ + output = mix(["test", "apps/unknown_app/test"]) + + assert output =~ """ ==> bar Paths given to "mix test" did not match any directory/file: apps/unknown_app/test + """ + + assert output =~ """ ==> foo Paths given to "mix test" did not match any directory/file: apps/unknown_app/test """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/mix/test/mix/tasks/xref_test.exs new/elixir-1.13.4/lib/mix/test/mix/tasks/xref_test.exs --- old/elixir-1.13.3/lib/mix/test/mix/tasks/xref_test.exs 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/mix/test/mix/tasks/xref_test.exs 2022-04-07 08:08:02.000000000 +0200 @@ -253,7 +253,7 @@ output = """ Compiling 2 files (.ex) Generated sample app - lib/b.ex:2: require A (export) + lib/b.ex:2: import A (export) lib/b.ex:3: call A.macro/0 (compile) lib/b.ex:4: import A.macro/0 (compile) lib/b.ex:5: call A.fun/0 (compile) @@ -287,6 +287,7 @@ output = """ Compiling 2 files (.ex) Generated sample app + lib/b.ex:2: require A (compile) lib/b.ex:3: call A.macro/0 (compile) """ @@ -313,10 +314,11 @@ output = """ Compiling 2 files (.ex) Generated sample app + lib/b.ex:3: require A (compile) lib/b.ex:3: call A.macro/0 (compile) """ - message = "Too many traces (found: 1, permitted: 0)" + message = "Too many traces (found: 2, permitted: 0)" assert_raise Mix.Error, message, fn -> assert_trace(~w[--label compile --fail-above 0], "lib/b.ex", files, output) @@ -759,10 +761,7 @@ defmodule B do # Let's also test that we track literal atom behaviours @behaviour :"Elixir.A.Behaviour" - - def foo do - A.foo() - end + def foo, do: :foo end """) @@ -772,7 +771,7 @@ digraph "xref graph" { "lib/a.ex" "lib/a.ex" -> "lib/b.ex" [label="(compile)"] - "lib/b.ex" -> "lib/a.ex" [label="(export)"] + "lib/b.ex" -> "lib/a.ex" "lib/b.ex" } """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/mix/test/mix/umbrella_test.exs new/elixir-1.13.4/lib/mix/test/mix/umbrella_test.exs --- old/elixir-1.13.3/lib/mix/test/mix/umbrella_test.exs 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/mix/test/mix/umbrella_test.exs 2022-04-07 08:08:02.000000000 +0200 @@ -391,7 +391,7 @@ assert_received {:mix_shell, :info, ["Compiled lib/bar.ex"]} # But exports dependencies are not recompiled - File.write!("lib/bar.ex", "defmodule Bar, do: (require Foo)") + File.write!("lib/bar.ex", "defmodule Bar, do: (import Foo, warn: false)") assert Mix.Tasks.Compile.Elixir.run(["--verbose"]) == {:ok, []} assert_received {:mix_shell, :info, ["Compiled lib/bar.ex"]} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/elixir-1.13.3/lib/mix/test/test_helper.exs new/elixir-1.13.4/lib/mix/test/test_helper.exs --- old/elixir-1.13.3/lib/mix/test/test_helper.exs 2022-02-09 16:26:17.000000000 +0100 +++ new/elixir-1.13.4/lib/mix/test/test_helper.exs 2022-04-07 08:08:02.000000000 +0200 @@ -7,12 +7,13 @@ os_exclude = if match?({:win32, _}, :os.type()), do: [unix: true], else: [windows: true] epmd_exclude = if match?({:win32, _}, :os.type()), do: [epmd: true], else: [] -ExUnit.start(trace: "--trace" in System.argv(), exclude: epmd_exclude ++ os_exclude) +git_exclude = if Mix.SCM.Git.git_version() <= {1, 7, 4}, do: [git_sparse: true], else: [] +rebar_exclude = if System.otp_release() >= "25", do: [rebar: true], else: [] -unless {1, 7, 4} <= Mix.SCM.Git.git_version() do - IO.puts(:stderr, "Skipping tests with git sparse checkouts...") - ExUnit.configure(exclude: :git_sparse) -end +ExUnit.start( + trace: "--trace" in System.argv(), + exclude: epmd_exclude ++ os_exclude ++ git_exclude ++ rebar_exclude +) # Clear environment variables that may affect tests System.delete_env("http_proxy") @@ -412,6 +413,26 @@ File.mkdir_p!(Path.expand("fixtures/deps_status/deps/#{dep}/.git", __DIR__)) end) +# Archive ebin +target = Path.expand("fixtures/archive", __DIR__) + +unless File.dir?(Path.join(target, "ebin")) do + File.mkdir_p!(Path.join(target, "ebin")) + + File.write!(Path.join([target, "ebin", "local_sample.app"]), """ + {application,local_sample, + [ + {modules,['Elixir.Mix.Tasks.Local.Sample']}, + {applications,[kernel,stdlib,elixir]} + ] + }. + """) + + [{name, bin}] = Code.compile_file("lib/local.sample.ex", target) + + File.write!(Path.join([target, "ebin", Atom.to_string(name) <> ".beam"]), bin) +end + ## Generate helper modules path = MixTest.Case.tmp_path("beams")