diff --git a/lib/elixir/lib/code/formatter.ex b/lib/elixir/lib/code/formatter.ex index 70ea70ae0e8..b6320d199db 100644 --- a/lib/elixir/lib/code/formatter.ex +++ b/lib/elixir/lib/code/formatter.ex @@ -1457,7 +1457,7 @@ defmodule Code.Formatter do metadata = [ file: state.file, line: meta[:line], - sigil: String.to_atom(name), + sigil: String.to_unsafe_atom(name), modifiers: modifiers, opening_delimiter: opening_delimiter ] diff --git a/lib/elixir/lib/code/identifier.ex b/lib/elixir/lib/code/identifier.ex index b3adeb5692f..5030d2af0da 100644 --- a/lib/elixir/lib/code/identifier.ex +++ b/lib/elixir/lib/code/identifier.ex @@ -65,7 +65,7 @@ defmodule Code.Identifier do with "-" <> rest <- Atom.to_string(atom), [trailing | reversed] = rest |> String.split("/") |> Enum.reverse(), [arity, _inner, _count, ""] <- String.split(trailing, "-") do - {reversed |> Enum.reverse() |> Enum.join("/") |> String.to_atom(), arity} + {reversed |> Enum.reverse() |> Enum.join("/") |> String.to_unsafe_atom(), arity} else _ -> :error end diff --git a/lib/elixir/lib/code/normalizer.ex b/lib/elixir/lib/code/normalizer.ex index 02fd024fbe4..85c110e572a 100644 --- a/lib/elixir/lib/code/normalizer.ex +++ b/lib/elixir/lib/code/normalizer.ex @@ -264,7 +264,7 @@ defmodule Code.Normalizer do "Elixir." <> segments -> segments |> String.split(".") - |> Enum.map(&String.to_atom/1) + |> Enum.map(&String.to_unsafe_atom/1) end {:__aliases__, meta, segments} @@ -559,7 +559,7 @@ defmodule Code.Normalizer do atom |> Atom.to_string() |> maybe_escape_literal(state) - |> String.to_atom() + |> String.to_unsafe_atom() end defp maybe_escape_literal(term, _) do diff --git a/lib/elixir/lib/code/typespec.ex b/lib/elixir/lib/code/typespec.ex index f04cac439f7..e46a258e2a0 100644 --- a/lib/elixir/lib/code/typespec.ex +++ b/lib/elixir/lib/code/typespec.ex @@ -399,10 +399,10 @@ defmodule Code.Typespec do defp erl_to_ex_var(var) do case Atom.to_string(var) do <<"_", c::utf8, rest::binary>> -> - String.to_atom("_#{String.downcase(<>)}#{rest}") + String.to_unsafe_atom("_#{String.downcase(<>)}#{rest}") <> -> - String.to_atom("#{String.downcase(<>)}#{rest}") + String.to_unsafe_atom("#{String.downcase(<>)}#{rest}") end end diff --git a/lib/elixir/lib/enum.ex b/lib/elixir/lib/enum.ex index 01537e21d43..385d8946556 100644 --- a/lib/elixir/lib/enum.ex +++ b/lib/elixir/lib/enum.ex @@ -1442,7 +1442,7 @@ defmodule Enum do ) # Avoid warnings about Dict - dict_module = String.to_atom("Dict") + dict_module = String.to_unsafe_atom("Dict") reduce(reverse(enumerable), dict, fn entry, categories -> dict_module.update(categories, fun.(entry), [entry], &[entry | &1]) diff --git a/lib/elixir/lib/exception.ex b/lib/elixir/lib/exception.ex index 04dd4ed6052..de26d5241c5 100644 --- a/lib/elixir/lib/exception.ex +++ b/lib/elixir/lib/exception.ex @@ -1137,7 +1137,7 @@ defmodule SystemLimitError do For example, this can happen if you try to create an atom that is too large: - iex> String.to_atom(String.duplicate("a", 100_000)) + iex> String.to_unsafe_atom(String.duplicate("a", 100_000)) ** (SystemLimitError) a system limit has been reached """ @@ -1807,7 +1807,7 @@ defmodule UndefinedFunctionError do defp load_module({name, _path, _loaded?}) do name - |> List.to_atom() + |> List.to_unsafe_atom() |> Code.ensure_loaded() end diff --git a/lib/elixir/lib/hash_dict.ex b/lib/elixir/lib/hash_dict.ex index d3d56d7601e..7ea6635f1fe 100644 --- a/lib/elixir/lib/hash_dict.ex +++ b/lib/elixir/lib/hash_dict.ex @@ -265,13 +265,13 @@ defimpl Enumerable, for: HashDict do def reduce(dict, acc, fun) do # Avoid warnings about HashDict being deprecated. - module = String.to_atom("HashDict") + module = String.to_unsafe_atom("HashDict") module.reduce(dict, acc, fun) end def member?(dict, {key, value}) do # Avoid warnings about HashDict being deprecated. - module = String.to_atom("HashDict") + module = String.to_unsafe_atom("HashDict") {:ok, match?({:ok, ^value}, module.fetch(dict, key))} end @@ -281,7 +281,7 @@ defimpl Enumerable, for: HashDict do def count(dict) do # Avoid warnings about HashDict being deprecated. - module = String.to_atom("HashDict") + module = String.to_unsafe_atom("HashDict") {:ok, module.size(dict)} end @@ -296,7 +296,7 @@ defimpl Collectable, for: HashDict do def into(original) do # Avoid warnings about HashDict being deprecated. - module = String.to_atom("HashDict") + module = String.to_unsafe_atom("HashDict") collector_fun = fn dict, {:cont, {key, value}} -> module.put(dict, key, value) @@ -315,7 +315,7 @@ defimpl Inspect, for: HashDict do def inspect(dict, opts) do # Avoid warnings about HashDict being deprecated. - module = String.to_atom("HashDict") + module = String.to_unsafe_atom("HashDict") concat(["#HashDict<", Inspect.List.inspect(module.to_list(dict), opts), ">"]) end end diff --git a/lib/elixir/lib/hash_set.ex b/lib/elixir/lib/hash_set.ex index aedd38dd55c..1602e5a88da 100644 --- a/lib/elixir/lib/hash_set.ex +++ b/lib/elixir/lib/hash_set.ex @@ -279,19 +279,19 @@ defimpl Enumerable, for: HashSet do def reduce(set, acc, fun) do # Avoid warnings about HashSet being deprecated. - module = String.to_atom("HashSet") + module = String.to_unsafe_atom("HashSet") module.reduce(set, acc, fun) end def member?(set, term) do # Avoid warnings about HashSet being deprecated. - module = String.to_atom("HashSet") + module = String.to_unsafe_atom("HashSet") {:ok, module.member?(set, term)} end def count(set) do # Avoid warnings about HashSet being deprecated. - module = String.to_atom("HashSet") + module = String.to_unsafe_atom("HashSet") {:ok, module.size(set)} end @@ -306,7 +306,7 @@ defimpl Collectable, for: HashSet do def into(original) do # Avoid warnings about HashSet being deprecated. - module = String.to_atom("HashSet") + module = String.to_unsafe_atom("HashSet") collector_fun = fn set, {:cont, term} -> module.put(set, term) @@ -325,7 +325,7 @@ defimpl Inspect, for: HashSet do def inspect(set, opts) do # Avoid warnings about HashSet being deprecated. - module = String.to_atom("HashSet") + module = String.to_unsafe_atom("HashSet") concat(["#HashSet<", Inspect.List.inspect(module.to_list(set), opts), ">"]) end end diff --git a/lib/elixir/lib/kernel.ex b/lib/elixir/lib/kernel.ex index 0a9e1a9c414..bf9ad581608 100644 --- a/lib/elixir/lib/kernel.ex +++ b/lib/elixir/lib/kernel.ex @@ -5248,12 +5248,12 @@ defmodule Kernel do # defmodule Alias nested defp alias_defmodule({:__aliases__, _, [h | t]}, _module, env) when is_atom(h) do module = :elixir_aliases.concat([env.module, h]) - alias = String.to_atom("Elixir." <> Atom.to_string(h)) + alias = String.to_unsafe_atom("Elixir." <> Atom.to_string(h)) opts = [as: alias, warn: false] case t do [] -> {module, module, opts} - _ -> {String.to_atom(Enum.join([module | t], ".")), module, opts} + _ -> {String.to_unsafe_atom(Enum.join([module | t], ".")), module, opts} end end @@ -6897,7 +6897,7 @@ defmodule Kernel do defp maybe_atomize_calendar(<> = last_part, string) when alias >= ?A and alias <= ?Z do string = binary_part(string, 0, byte_size(string) - byte_size(last_part) - 1) - {String.to_atom("Elixir." <> last_part), string} + {String.to_unsafe_atom("Elixir." <> last_part), string} end defp maybe_atomize_calendar(_last_part, string) do @@ -7008,7 +7008,7 @@ defmodule Kernel do case mod do ?s -> parts - ?a -> :lists.map(&String.to_atom/1, parts) + ?a -> :lists.map(&String.to_unsafe_atom/1, parts) ?c -> :lists.map(&String.to_charlist/1, parts) end @@ -7017,7 +7017,7 @@ defmodule Kernel do case mod do ?s -> parts - ?a -> quote(do: :lists.map(&String.to_atom/1, unquote(parts))) + ?a -> quote(do: :lists.map(&String.to_unsafe_atom/1, unquote(parts))) ?c -> quote(do: :lists.map(&String.to_charlist/1, unquote(parts))) end end diff --git a/lib/elixir/lib/kernel/cli.ex b/lib/elixir/lib/kernel/cli.ex index 84c9cb76bc0..f1c6585dc30 100644 --- a/lib/elixir/lib/kernel/cli.ex +++ b/lib/elixir/lib/kernel/cli.ex @@ -433,7 +433,7 @@ defmodule Kernel.CLI do end defp process_command({:rpc_eval, node, expr}, _config) when is_list(expr) do - node = List.to_atom(node) + node = List.to_unsafe_atom(node) # Explicitly connect the node in case the rpc node was started with --sname/--name undefined. _ = :net_kernel.connect_node(node) diff --git a/lib/elixir/lib/kernel/utils.ex b/lib/elixir/lib/kernel/utils.ex index 26c6f6f40f6..47259aa2982 100644 --- a/lib/elixir/lib/kernel/utils.ex +++ b/lib/elixir/lib/kernel/utils.ex @@ -382,7 +382,7 @@ defmodule Kernel.Utils do {new_var, acc} %{} -> - generated = String.to_atom("arg" <> Integer.to_string(map_size(acc) + 1)) + generated = String.to_unsafe_atom("arg" <> Integer.to_string(map_size(acc) + 1)) new_var = Macro.unique_var(generated, module) {new_var, Map.put(acc, pair, {new_var, var})} end diff --git a/lib/elixir/lib/list.ex b/lib/elixir/lib/list.ex index 043aecd67ff..ab758ad287c 100644 --- a/lib/elixir/lib/list.ex +++ b/lib/elixir/lib/list.ex @@ -1024,6 +1024,11 @@ defmodule List do :lists.suffix(suffix, list) end + @doc deprecated: "Use to_existing_atom/1 or to_unsafe_atom/1 instead" + def to_atom(charlist) do + :erlang.list_to_atom(charlist) + end + @doc """ Converts a charlist to an atom. @@ -1034,15 +1039,15 @@ defmodule List do ## Examples - iex> List.to_atom(~c"Elixir") + iex> List.to_unsafe_atom(~c"Elixir") :Elixir - iex> List.to_atom(~c"🌢 Elixir") + iex> List.to_unsafe_atom(~c"🌢 Elixir") :"🌢 Elixir" """ - @spec to_atom(charlist) :: atom - def to_atom(charlist) do + @spec to_unsafe_atom(charlist) :: atom + def to_unsafe_atom(charlist) do :erlang.list_to_atom(charlist) end diff --git a/lib/elixir/lib/macro.ex b/lib/elixir/lib/macro.ex index 297f709a992..c2f3bacaafd 100644 --- a/lib/elixir/lib/macro.ex +++ b/lib/elixir/lib/macro.ex @@ -527,7 +527,7 @@ defmodule Macro do defp generate_arguments(amount, context, fun) when is_integer(amount) and amount > 0 and is_atom(context) do - for id <- 1..amount, do: fun.(String.to_atom("arg" <> Integer.to_string(id)), context) + for id <- 1..amount, do: fun.(String.to_unsafe_atom("arg" <> Integer.to_string(id)), context) end @doc """ diff --git a/lib/elixir/lib/module.ex b/lib/elixir/lib/module.ex index 9d18e1f6ce2..6af24400741 100644 --- a/lib/elixir/lib/module.ex +++ b/lib/elixir/lib/module.ex @@ -1148,7 +1148,7 @@ defmodule Module do defp simplify_var(var, guess_priority) do case Atom.to_string(var) do "_" -> {:_, [], guess_priority} - "_" <> rest -> {String.to_atom(rest), [], guess_priority} + "_" <> rest -> {String.to_unsafe_atom(rest), [], guess_priority} _ -> {var, [], nil} end end @@ -1159,7 +1159,7 @@ defmodule Module do rescue ArgumentError -> module else - module_name -> String.to_atom(Macro.underscore(List.last(module_name))) + module_name -> String.to_unsafe_atom(Macro.underscore(List.last(module_name))) end end diff --git a/lib/elixir/lib/module/types/descr.ex b/lib/elixir/lib/module/types/descr.ex index ce439cc97b8..c2648be488e 100644 --- a/lib/elixir/lib/module/types/descr.ex +++ b/lib/elixir/lib/module/types/descr.ex @@ -1237,7 +1237,7 @@ defmodule Module.Types.Descr do "Elixir." <> segments -> segments |> String.split(".") - |> Enum.map(&String.to_atom/1) + |> Enum.map(&String.to_unsafe_atom/1) end {:__aliases__, [], segments} diff --git a/lib/elixir/lib/option_parser.ex b/lib/elixir/lib/option_parser.ex index 50dcb4b7ee8..1e91706af93 100644 --- a/lib/elixir/lib/option_parser.ex +++ b/lib/elixir/lib/option_parser.ex @@ -852,7 +852,7 @@ defmodule OptionParser do |> to_existing_key(allow_nonexistent_atoms?) end - defp to_existing_key(option, true), do: String.to_atom(option) + defp to_existing_key(option, true), do: String.to_unsafe_atom(option) defp to_existing_key(option, false) do try do diff --git a/lib/elixir/lib/protocol.ex b/lib/elixir/lib/protocol.ex index f44a847ddc1..eb2eee93176 100644 --- a/lib/elixir/lib/protocol.ex +++ b/lib/elixir/lib/protocol.ex @@ -282,7 +282,9 @@ defmodule Protocol do type_args = :lists.map(fn _ -> quote(do: term) end, :lists.seq(2, arity)) type_args = [quote(do: t) | type_args] - to_var = fn pos -> Macro.var(String.to_atom("arg" <> Integer.to_string(pos)), __MODULE__) end + to_var = fn pos -> + Macro.var(String.to_unsafe_atom("arg" <> Integer.to_string(pos)), __MODULE__) + end call_args = :lists.map(to_var, :lists.seq(2, arity)) call_args = [quote(do: term) | call_args] @@ -1228,7 +1230,7 @@ defmodule Protocol do end def __concat__(left, right) when is_binary(right) do - String.to_atom(ensure_prefix(Atom.to_string(left)) <> "." <> right) + String.to_unsafe_atom(ensure_prefix(Atom.to_string(left)) <> "." <> right) end defp ensure_prefix("Elixir." <> _ = left), do: left diff --git a/lib/elixir/lib/record/extractor.ex b/lib/elixir/lib/record/extractor.ex index 05559927d0b..f2db0acd7b4 100644 --- a/lib/elixir/lib/record/extractor.ex +++ b/lib/elixir/lib/record/extractor.ex @@ -40,7 +40,7 @@ defmodule Record.Extractor do defp from_lib_file(file) do [app | path] = :filename.split(String.to_charlist(file)) - case :code.lib_dir(List.to_atom(app)) do + case :code.lib_dir(List.to_unsafe_atom(app)) do {:error, _} -> raise ArgumentError, "lib file #{file} could not be found" diff --git a/lib/elixir/lib/string.ex b/lib/elixir/lib/string.ex index 80a8b87f2ab..c148577da6e 100644 --- a/lib/elixir/lib/string.ex +++ b/lib/elixir/lib/string.ex @@ -2962,6 +2962,11 @@ defmodule String do end end + @doc deprecated: "Use to_existing_atom/1 or to_unsafe_atom/1 instead" + def to_atom(string) when is_binary(string) do + :erlang.binary_to_atom(string, :utf8) + end + @doc """ Converts a string to an existing atom or creates a new one. @@ -2979,12 +2984,12 @@ defmodule String do ## Examples - iex> String.to_atom("my_atom") + iex> String.to_unsafe_atom("my_atom") :my_atom """ - @spec to_atom(String.t()) :: atom - def to_atom(string) when is_binary(string) do + @spec to_unsafe_atom(String.t()) :: atom + def to_unsafe_atom(string) when is_binary(string) do :erlang.binary_to_atom(string, :utf8) end diff --git a/lib/elixir/lib/uri.ex b/lib/elixir/lib/uri.ex index 824deffa022..faf5562d996 100644 --- a/lib/elixir/lib/uri.ex +++ b/lib/elixir/lib/uri.ex @@ -252,7 +252,7 @@ defmodule URI do {{key, value}, rest} -> # Avoid warnings about Dict being deprecated - dict_module = String.to_atom("Dict") + dict_module = String.to_unsafe_atom("Dict") decode_query_into_dict(rest, dict_module.put(dict, key, value), encoding) end end diff --git a/lib/elixir/pages/anti-patterns/code-anti-patterns.md b/lib/elixir/pages/anti-patterns/code-anti-patterns.md index d4bfebc0fed..002768837e7 100644 --- a/lib/elixir/pages/anti-patterns/code-anti-patterns.md +++ b/lib/elixir/pages/anti-patterns/code-anti-patterns.md @@ -155,7 +155,7 @@ Picture yourself implementing code that converts string values into atoms. These ```elixir defmodule MyRequestHandler do def parse(%{"status" => status, "message" => message} = _payload) do - %{status: String.to_atom(status), message: message} + %{status: String.to_unsafe_atom(status), message: message} end end ``` @@ -165,11 +165,11 @@ iex> MyRequestHandler.parse(%{"status" => "ok", "message" => "all good"}) %{status: :ok, message: "all good"} ``` -When we use the `String.to_atom/1` function to dynamically create an atom, it essentially gains potential access to create arbitrary atoms in our system, causing us to lose control over adhering to the limits established by the BEAM. This issue could be exploited by someone to create enough atoms to shut down a system. +When we use the `String.to_unsafe_atom/1` function to dynamically create an atom, it essentially gains potential access to create arbitrary atoms in our system, causing us to lose control over adhering to the limits established by the BEAM. This issue could be exploited by someone to create enough atoms to shut down a system. #### Refactoring -To eliminate this anti-pattern, developers must either perform explicit conversions by mapping strings to atoms or replace the use of `String.to_atom/1` with `String.to_existing_atom/1`. An explicit conversion could be done as follows: +To eliminate this anti-pattern, developers must either perform explicit conversions by mapping strings to atoms or replace the use of `String.to_unsafe_atom/1` with `String.to_existing_atom/1`. An explicit conversion could be done as follows: ```elixir defmodule MyRequestHandler do diff --git a/lib/elixir/pages/meta-programming/domain-specific-languages.md b/lib/elixir/pages/meta-programming/domain-specific-languages.md index 6fc91f77809..0205d2e7bab 100644 --- a/lib/elixir/pages/meta-programming/domain-specific-languages.md +++ b/lib/elixir/pages/meta-programming/domain-specific-languages.md @@ -96,7 +96,7 @@ defmodule TestCase do """ defmacro test(description, do: block) do - function_name = String.to_atom("test " <> description) + function_name = String.to_unsafe_atom("test " <> description) quote do def unquote(function_name)(), do: unquote(block) end @@ -159,7 +159,7 @@ defmodule TestCase do """ defmacro test(description, do: block) do - function_name = String.to_atom("test " <> description) + function_name = String.to_unsafe_atom("test " <> description) quote do # Prepend the newly defined test to the list of tests @tests [unquote(function_name) | @tests] diff --git a/lib/elixir/pages/mix-and-otp/config-and-distribution.md b/lib/elixir/pages/mix-and-otp/config-and-distribution.md index d50b3039bfe..20d18bf22d7 100644 --- a/lib/elixir/pages/mix-and-otp/config-and-distribution.md +++ b/lib/elixir/pages/mix-and-otp/config-and-distribution.md @@ -261,7 +261,7 @@ Open up `config/runtime.exs` and add this to the bottom: nodes = System.get_env("NODES", "") |> String.split(",", trim: true) - |> Enum.map(&String.to_atom/1) + |> Enum.map(&String.to_unsafe_atom/1) config :kv, :nodes, nodes ``` diff --git a/lib/elixir/scripts/cover_record.exs b/lib/elixir/scripts/cover_record.exs index ffe78f3ed85..afc3068aa23 100644 --- a/lib/elixir/scripts/cover_record.exs +++ b/lib/elixir/scripts/cover_record.exs @@ -85,7 +85,7 @@ defmodule CoverageRecorder do ] defp skip_from_coverage?(file) do - mod = file |> Path.basename(".beam") |> String.to_atom() + mod = file |> Path.basename(".beam") |> String.to_unsafe_atom() mod in @to_skip or match?({:docs_v1, _, _, _, _, %{deprecated: _}, _}, Code.fetch_docs(mod)) end end diff --git a/lib/elixir/src/elixir_rewrite.erl b/lib/elixir/src/elixir_rewrite.erl index cbf260129c2..c3a3a4fae33 100644 --- a/lib/elixir/src/elixir_rewrite.erl +++ b/lib/elixir/src/elixir_rewrite.erl @@ -147,7 +147,10 @@ inline(Mod, Fun, Arity) -> inner_inline(ex_to_erl, Mod, Fun, Arity). ?inline(?kernel, trunc, 1, erlang, trunc); ?inline(?kernel, tuple_size, 1, erlang, tuple_size); -?inline(?list, to_atom, 1, erlang, list_to_atom); +% we just want ex_to_erl, not erl_to_ex +inner_inline(ex_to_erl, ?list, to_atom, 1) -> {erlang, list_to_atom}; + +?inline(?list, to_unsafe_atom, 1, erlang, list_to_atom); ?inline(?list, to_existing_atom, 1, erlang, list_to_existing_atom); ?inline(?list, to_float, 1, erlang, list_to_float); ?inline(?list, to_integer, 1, erlang, list_to_integer); @@ -205,8 +208,11 @@ inline(Mod, Fun, Arity) -> inner_inline(ex_to_erl, Mod, Fun, Arity). ?inline(?process, unlink, 1, erlang, unlink); ?inline(?process, unregister, 1, erlang, unregister); +% we just want ex_to_erl, not erl_to_ex +inner_inline(ex_to_erl, ?string, to_atom, 1) -> {erlang, binary_to_atom}; + ?inline(?string, duplicate, 2, binary, copy); -?inline(?string, to_atom, 1, erlang, binary_to_atom); +?inline(?string, to_unsafe_atom, 1, erlang, binary_to_atom); ?inline(?string, to_existing_atom, 1, erlang, binary_to_existing_atom); ?inline(?string, to_float, 1, erlang, binary_to_float); ?inline(?string, to_integer, 1, erlang, binary_to_integer); diff --git a/lib/elixir/test/elixir/atom_test.exs b/lib/elixir/test/elixir/atom_test.exs index e72b7fd9ff7..318d9b5da58 100644 --- a/lib/elixir/test/elixir/atom_test.exs +++ b/lib/elixir/test/elixir/atom_test.exs @@ -10,10 +10,10 @@ defmodule AtomTest do doctest Atom, except: [:moduledoc] test "to_string/1" do - assert "héllo" |> String.to_atom() |> Atom.to_string() == "héllo" + assert "héllo" |> String.to_unsafe_atom() |> Atom.to_string() == "héllo" end test "to_charlist/1" do - assert "héllo" |> String.to_atom() |> Atom.to_charlist() == ~c"héllo" + assert "héllo" |> String.to_unsafe_atom() |> Atom.to_charlist() == ~c"héllo" end end diff --git a/lib/elixir/test/elixir/enum_test.exs b/lib/elixir/test/elixir/enum_test.exs index 616999dfb28..1be9e4a2eee 100644 --- a/lib/elixir/test/elixir/enum_test.exs +++ b/lib/elixir/test/elixir/enum_test.exs @@ -98,12 +98,12 @@ defmodule EnumTest do end test "chunk/3" do - enum = String.to_atom("Elixir.Enum") + enum = String.to_unsafe_atom("Elixir.Enum") assert enum.chunk(1..5, 2, 1) == Enum.chunk_every(1..5, 2, 1, :discard) end test "chunk/4" do - enum = String.to_atom("Elixir.Enum") + enum = String.to_unsafe_atom("Elixir.Enum") assert enum.chunk(1..5, 2, 1, nil) == Enum.chunk_every(1..5, 2, 1, :discard) end diff --git a/lib/elixir/test/elixir/exception_test.exs b/lib/elixir/test/elixir/exception_test.exs index cc8c8040666..47daab9f858 100644 --- a/lib/elixir/test/elixir/exception_test.exs +++ b/lib/elixir/test/elixir/exception_test.exs @@ -210,7 +210,7 @@ defmodule ExceptionTest do assert Exception.format_mfa(Foo, :こんにちは世界, [1, 2]) == "Foo.こんにちは世界(1, 2)" nfd = :unicode.characters_to_nfd_binary("olá") - assert Exception.format_mfa(Foo, String.to_atom(nfd), [1, 2]) == "Foo.\"#{nfd}\"(1, 2)" + assert Exception.format_mfa(Foo, String.to_unsafe_atom(nfd), [1, 2]) == "Foo.\"#{nfd}\"(1, 2)" end test "format_fa/2" do diff --git a/lib/elixir/test/elixir/fixtures/dialyzer/remote_call.ex b/lib/elixir/test/elixir/fixtures/dialyzer/remote_call.ex index a63654b4c8d..9882704fcf8 100644 --- a/lib/elixir/test/elixir/fixtures/dialyzer/remote_call.ex +++ b/lib/elixir/test/elixir/fixtures/dialyzer/remote_call.ex @@ -23,7 +23,7 @@ defmodule Dialyzer.RemoteCall do end def mod_var() do - module = String.to_atom("Elixir.Hello") + module = String.to_unsafe_atom("Elixir.Hello") module.fun() end end diff --git a/lib/elixir/test/elixir/inspect_test.exs b/lib/elixir/test/elixir/inspect_test.exs index ace9a2391c1..2016aef1a16 100644 --- a/lib/elixir/test/elixir/inspect_test.exs +++ b/lib/elixir/test/elixir/inspect_test.exs @@ -102,7 +102,7 @@ defmodule Inspect.AtomTest do assert inspect(:こんにちは世界) == ":こんにちは世界" nfd = :unicode.characters_to_nfd_binary("olá") - assert inspect(String.to_atom(nfd)) == ":\"#{nfd}\"" + assert inspect(String.to_unsafe_atom(nfd)) == ":\"#{nfd}\"" end end diff --git a/lib/elixir/test/elixir/integer_test.exs b/lib/elixir/test/elixir/integer_test.exs index a9ba693cc52..c6c96d8da64 100644 --- a/lib/elixir/test/elixir/integer_test.exs +++ b/lib/elixir/test/elixir/integer_test.exs @@ -224,7 +224,7 @@ defmodule IntegerTest do end test "to_charlist/2" do - module = String.to_atom("Elixir.Integer") + module = String.to_unsafe_atom("Elixir.Integer") assert Integer.to_charlist(42) == ~c"42" assert Integer.to_charlist(+42) == ~c"42" diff --git a/lib/elixir/test/elixir/kernel/fn_test.exs b/lib/elixir/test/elixir/kernel/fn_test.exs index 21a8c58efe6..079ceff64b5 100644 --- a/lib/elixir/test/elixir/kernel/fn_test.exs +++ b/lib/elixir/test/elixir/kernel/fn_test.exs @@ -101,7 +101,7 @@ defmodule Kernel.FnTest do test "local partial application" do assert (&atb(&1, :utf8)).(:a) == "a" - assert (&atb(List.to_atom(&1), :utf8)).(~c"a") == "a" + assert (&atb(List.to_unsafe_atom(&1), :utf8)).(~c"a") == "a" end test "imported partial application" do diff --git a/lib/elixir/test/elixir/kernel/guard_test.exs b/lib/elixir/test/elixir/kernel/guard_test.exs index 543c3dd2e41..83e357683d1 100644 --- a/lib/elixir/test/elixir/kernel/guard_test.exs +++ b/lib/elixir/test/elixir/kernel/guard_test.exs @@ -67,7 +67,7 @@ defmodule Kernel.GuardTest do defmodule UnquotedInGuardCall do @value :foo - defguard unquote(String.to_atom("is_#{@value}"))(x) when x == unquote(@value) + defguard unquote(String.to_unsafe_atom("is_#{@value}"))(x) when x == unquote(@value) end test "guards names can be defined dynamically using unquote" do diff --git a/lib/elixir/test/elixir/kernel/macros_test.exs b/lib/elixir/test/elixir/kernel/macros_test.exs index bbb9f39de03..19a78f2b4f4 100644 --- a/lib/elixir/test/elixir/kernel/macros_test.exs +++ b/lib/elixir/test/elixir/kernel/macros_test.exs @@ -87,7 +87,7 @@ defmodule Kernel.MacrosTest do end test "macros cannot be called dynamically" do - x = String.to_atom("Elixir.Nested") + x = String.to_unsafe_atom("Elixir.Nested") assert_raise UndefinedFunctionError, fn -> x.func() end end diff --git a/lib/elixir/test/elixir/kernel/string_tokenizer_test.exs b/lib/elixir/test/elixir/kernel/string_tokenizer_test.exs index 316b5d1de41..91b6f21cb0a 100644 --- a/lib/elixir/test/elixir/kernel/string_tokenizer_test.exs +++ b/lib/elixir/test/elixir/kernel/string_tokenizer_test.exs @@ -65,8 +65,8 @@ defmodule Kernel.StringTokenizerTest do end test "tokenizes aliases" do - assert Code.string_to_quoted!("Ola") |> aliases() == String.to_atom("Ola") - assert Code.string_to_quoted!("M_123") |> aliases() == String.to_atom("M_123") + assert Code.string_to_quoted!("Ola") |> aliases() == String.to_unsafe_atom("Ola") + assert Code.string_to_quoted!("M_123") |> aliases() == String.to_unsafe_atom("M_123") assert {:error, _} = Code.string_to_quoted("Óla") assert {:error, _} = Code.string_to_quoted("Olá") assert {:error, _} = Code.string_to_quoted("Ol@") diff --git a/lib/elixir/test/elixir/macro_test.exs b/lib/elixir/test/elixir/macro_test.exs index 405d1916ecd..ac5a0bc7273 100644 --- a/lib/elixir/test/elixir/macro_test.exs +++ b/lib/elixir/test/elixir/macro_test.exs @@ -1081,7 +1081,7 @@ defmodule MacroTest do describe "to_string/2" do defp macro_to_string(var, fun \\ fn _ast, string -> string end) do - module = String.to_atom("Elixir.Macro") + module = String.to_unsafe_atom("Elixir.Macro") module.to_string(var, fun) end diff --git a/lib/elixir/test/elixir/module/types/expr_test.exs b/lib/elixir/test/elixir/module/types/expr_test.exs index 25134a7bc11..fcd614dbebc 100644 --- a/lib/elixir/test/elixir/module/types/expr_test.exs +++ b/lib/elixir/test/elixir/module/types/expr_test.exs @@ -627,7 +627,7 @@ defmodule Module.Types.ExprTest do describe "remote capture" do test "strong" do - assert typecheck!(&String.to_atom/1) == fun([binary()], atom()) + assert typecheck!(&String.to_unsafe_atom/1) == fun([binary()], atom()) assert typecheck!(&:erlang.element/2) == fun([integer(), open_tuple([])], dynamic()) end @@ -1274,12 +1274,12 @@ defmodule Module.Types.ExprTest do [key], ( x = %{String.to_integer(key) => :old} - %{x | String.to_atom(key) => :new} + %{x | String.to_unsafe_atom(key) => :new} ) ) == ~l""" expected a map with key of type atom() in map update syntax: - %{x | String.to_atom(key) => :new} + %{x | String.to_unsafe_atom(key) => :new} but got type: @@ -1302,12 +1302,12 @@ defmodule Module.Types.ExprTest do [key], ( x = %{key: :old} - %{x | String.to_atom(key) => :new} + %{x | String.to_unsafe_atom(key) => :new} ) ) == ~l""" expected a map with key of type atom() in map update syntax: - %{x | String.to_atom(key) => :new} + %{x | String.to_unsafe_atom(key) => :new} but got type: @@ -1317,7 +1317,7 @@ defmodule Module.Types.ExprTest do # type: binary() # from: types_test.ex:LINE-2 - String.to_atom(key) + String.to_unsafe_atom(key) where "x" was given the type: @@ -2218,7 +2218,7 @@ defmodule Module.Types.ExprTest do assert typewarn!( [x], - case String.to_atom(x) do + case String.to_unsafe_atom(x) do :ok -> 1 :ok -> 2 end diff --git a/lib/elixir/test/elixir/module/types/helpers_test.exs b/lib/elixir/test/elixir/module/types/helpers_test.exs index efa09afb32f..0d32abbc2ab 100644 --- a/lib/elixir/test/elixir/module/types/helpers_test.exs +++ b/lib/elixir/test/elixir/module/types/helpers_test.exs @@ -17,7 +17,7 @@ defmodule Module.Types.HelpersTest do assert expr_to_string(quote(do: :erlang.band(a, b))) == "Bitwise.band(a, b)" assert expr_to_string(quote(do: :erlang.orelse(a, b))) == "a or b" assert expr_to_string(quote(do: :erlang."=:="(a, b))) == "a === b" - assert expr_to_string(quote(do: :erlang.list_to_atom(a))) == "List.to_atom(a)" + assert expr_to_string(quote(do: :erlang.list_to_atom(a))) == "List.to_unsafe_atom(a)" assert expr_to_string(quote(do: :erlang.element(1, a))) == "elem(a, 0)" assert expr_to_string(quote(do: :erlang.element(:erlang.+(a, 1), b))) == "elem(b, a)" assert expr_to_string(quote(do: :lists.member(a, []))) == "a in []" diff --git a/lib/elixir/test/elixir/module/types/map_test.exs b/lib/elixir/test/elixir/module/types/map_test.exs index d871af0a938..e0cc57c24c9 100644 --- a/lib/elixir/test/elixir/module/types/map_test.exs +++ b/lib/elixir/test/elixir/module/types/map_test.exs @@ -132,7 +132,7 @@ defmodule Module.Types.MapTest do assert typecheck!([x], x |> Map.delete(:key) |> Map.put(:key, "123")) == dynamic(open_map(key: binary())) - assert typecheck!([x, y], x |> Map.delete(:key) |> Map.put(String.to_atom(y), "123")) == + assert typecheck!([x, y], x |> Map.delete(:key) |> Map.put(String.to_unsafe_atom(y), "123")) == dynamic(open_map(key: if_set(binary()))) end end diff --git a/lib/elixir/test/elixir/protocol/consolidation_test.exs b/lib/elixir/test/elixir/protocol/consolidation_test.exs index 0d273433d66..804c7cec8e2 100644 --- a/lib/elixir/test/elixir/protocol/consolidation_test.exs +++ b/lib/elixir/test/elixir/protocol/consolidation_test.exs @@ -267,7 +267,7 @@ defmodule Protocol.ConsolidationTest do "\n\nGot value:\n\n :foo\n" assert_raise Protocol.UndefinedError, message, fn -> - sample = String.to_atom("Elixir.Protocol.ConsolidationTest.Sample") + sample = String.to_unsafe_atom("Elixir.Protocol.ConsolidationTest.Sample") sample.ok(:foo) end end diff --git a/lib/elixir/test/elixir/protocol_test.exs b/lib/elixir/test/elixir/protocol_test.exs index 6c6764371a9..a39201788e2 100644 --- a/lib/elixir/test/elixir/protocol_test.exs +++ b/lib/elixir/test/elixir/protocol_test.exs @@ -135,7 +135,7 @@ defmodule ProtocolTest do """ assert_raise Protocol.UndefinedError, message, fn -> - sample = String.to_atom("Elixir.ProtocolTest.Sample") + sample = String.to_unsafe_atom("Elixir.ProtocolTest.Sample") sample.ok(:foo) end end diff --git a/lib/elixir/test/elixir/system_test.exs b/lib/elixir/test/elixir/system_test.exs index b6d56dec778..5e49e6af196 100644 --- a/lib/elixir/test/elixir/system_test.exs +++ b/lib/elixir/test/elixir/system_test.exs @@ -81,10 +81,10 @@ defmodule SystemTest do System.put_env(%{@test_var => "MAP_STRING"}) assert System.get_env(@test_var) == "MAP_STRING" - System.put_env([{String.to_atom(@test_var), "KW_ATOM"}]) + System.put_env([{String.to_unsafe_atom(@test_var), "KW_ATOM"}]) assert System.get_env(@test_var) == "KW_ATOM" - System.put_env([{String.to_atom(@test_var), nil}]) + System.put_env([{String.to_unsafe_atom(@test_var), nil}]) assert System.get_env(@test_var) == nil end diff --git a/lib/ex_unit/lib/ex_unit/case.ex b/lib/ex_unit/lib/ex_unit/case.ex index aca3179f2c9..942c662e1f8 100644 --- a/lib/ex_unit/lib/ex_unit/case.ex +++ b/lib/ex_unit/lib/ex_unit/case.ex @@ -926,7 +926,7 @@ defmodule ExUnit.Case do defp build_test_name(name) do try do - String.to_atom(name) + String.to_unsafe_atom(name) rescue SystemLimitError -> raise SystemLimitError, """ diff --git a/lib/ex_unit/lib/ex_unit/filters.ex b/lib/ex_unit/lib/ex_unit/filters.ex index 9348656b4e6..fb89c4c16ce 100644 --- a/lib/ex_unit/lib/ex_unit/filters.ex +++ b/lib/ex_unit/lib/ex_unit/filters.ex @@ -134,8 +134,8 @@ defmodule ExUnit.Filters do def parse(filters) do Enum.map(filters, fn filter -> case :binary.split(filter, ":") do - [key, value] -> parse_kv(String.to_atom(key), value) - [key] -> String.to_atom(key) + [key, value] -> parse_kv(String.to_unsafe_atom(key), value) + [key] -> String.to_unsafe_atom(key) end end) end diff --git a/lib/ex_unit/test/ex_unit/formatter_test.exs b/lib/ex_unit/test/ex_unit/formatter_test.exs index 6dd28f1094f..01843bdc775 100644 --- a/lib/ex_unit/test/ex_unit/formatter_test.exs +++ b/lib/ex_unit/test/ex_unit/formatter_test.exs @@ -37,7 +37,7 @@ defmodule ExUnit.FormatterTest do long_name = "test " <> String.duplicate("a", 300) %ExUnit.Test{ - name: String.to_atom("truncated"), + name: String.to_unsafe_atom("truncated"), description: long_name, module: Hello, tags: %{file: __ENV__.file, line: 1} diff --git a/lib/iex/lib/iex/autocomplete.ex b/lib/iex/lib/iex/autocomplete.ex index 373341b9688..95d38a218e0 100644 --- a/lib/iex/lib/iex/autocomplete.ex +++ b/lib/iex/lib/iex/autocomplete.ex @@ -100,7 +100,7 @@ defmodule IEx.Autocomplete do expand_dot(path, List.to_string(hint), true, shell) {:dot_call, path, hint} -> - expand_dot_call(path, List.to_atom(hint), shell) + expand_dot_call(path, List.to_unsafe_atom(hint), shell) :expr -> expand_container_context(code, :expr, "", shell) || expand_local_or_var("", shell) @@ -116,7 +116,7 @@ defmodule IEx.Autocomplete do expand_aliases("", shell) {:local_call, local} -> - expand_local_call(List.to_atom(local), shell) + expand_local_call(List.to_unsafe_atom(local), shell) {:operator, operator} when operator in ~w(:: -)c -> expand_container_context(code, :operator, "", shell) || @@ -238,7 +238,7 @@ defmodule IEx.Autocomplete do end defp expand_dot_path({:unquoted_atom, var}, _shell) do - {:ok, List.to_atom(var)} + {:ok, List.to_unsafe_atom(var)} end defp expand_dot_path(path, shell) do @@ -249,7 +249,7 @@ defmodule IEx.Autocomplete do end defp recur_expand_dot_path({:var, var}, _shell) do - {:ok, [List.to_atom(var)]} + {:ok, [List.to_unsafe_atom(var)]} end defp recur_expand_dot_path({:alias, var}, shell) do @@ -258,7 +258,7 @@ defmodule IEx.Autocomplete do defp recur_expand_dot_path({:dot, parent, call}, shell) do case recur_expand_dot_path(parent, shell) do - {:ok, [_ | _] = path} -> {:ok, [List.to_atom(call) | path]} + {:ok, [_ | _] = path} -> {:ok, [List.to_unsafe_atom(call) | path]} _ -> :error end end @@ -339,7 +339,7 @@ defmodule IEx.Autocomplete do modules = for "Elixir." <> name = full_name <- match_modules("Elixir." <> hint, true), String.starts_with?(name, hint), - mod = String.to_atom(full_name), + mod = String.to_unsafe_atom(full_name), do: {mod, name} all = aliases ++ modules @@ -608,7 +608,7 @@ defmodule IEx.Autocomplete do defp usable_as_unquoted_module?(name) do # Conversion to atom is not a problem because # it is only called with existing modules names. - Macro.classify_atom(String.to_atom(name)) in [:identifier, :unquoted] + Macro.classify_atom(String.to_unsafe_atom(name)) in [:identifier, :unquoted] end defp match_modules(hint, elixir_root?) do diff --git a/lib/iex/lib/iex/introspection.ex b/lib/iex/lib/iex/introspection.ex index 6c3aad09dc7..31f412bd20d 100644 --- a/lib/iex/lib/iex/introspection.ex +++ b/lib/iex/lib/iex/introspection.ex @@ -706,7 +706,7 @@ defmodule IEx.Introspection do def translate_callback_name_arity({name, arity}) do case Atom.to_string(name) do - "MACRO-" <> macro_name -> {:macrocallback, String.to_atom(macro_name), arity - 1} + "MACRO-" <> macro_name -> {:macrocallback, String.to_unsafe_atom(macro_name), arity - 1} _ -> {:callback, name, arity} end end diff --git a/lib/iex/lib/iex/pry.ex b/lib/iex/lib/iex/pry.ex index 333365f65b6..5ea96e47acb 100644 --- a/lib/iex/lib/iex/pry.ex +++ b/lib/iex/lib/iex/pry.ex @@ -530,7 +530,7 @@ defmodule IEx.Pry do # Have an extra binding per argument for case matching. case_vars = for id <- 1..arity//1 do - {String.to_atom("arg" <> Integer.to_string(id)), [version: -id], __MODULE__} + {String.to_unsafe_atom("arg" <> Integer.to_string(id)), [version: -id], __MODULE__} end case_head = {:{}, [], case_vars} diff --git a/lib/logger/lib/logger/formatter.ex b/lib/logger/lib/logger/formatter.ex index f70c017dcb9..fe98474cd22 100644 --- a/lib/logger/lib/logger/formatter.ex +++ b/lib/logger/lib/logger/formatter.ex @@ -441,7 +441,7 @@ defmodule Logger.Formatter do for part <- Regex.split(regex, str, on: [:head, :tail], trim: true) do case part do - "$" <> code -> compile_code(String.to_atom(code)) + "$" <> code -> compile_code(String.to_unsafe_atom(code)) _ -> part end end diff --git a/lib/mix/lib/mix/cli.ex b/lib/mix/lib/mix/cli.ex index d1b60b4aadd..155804f94d6 100644 --- a/lib/mix/lib/mix/cli.ex +++ b/lib/mix/lib/mix/cli.ex @@ -164,7 +164,7 @@ defmodule Mix.CLI do end defp maybe_change_env_and_target(task, project) do - task = String.to_atom(task) + task = String.to_unsafe_atom(task) config = Mix.Project.config() env = preferred_cli_env(project, task, config) diff --git a/lib/mix/lib/mix/compilers/elixir.ex b/lib/mix/lib/mix/compilers/elixir.ex index 35f73bc072c..24e65f106fc 100644 --- a/lib/mix/lib/mix/compilers/elixir.ex +++ b/lib/mix/lib/mix/compilers/elixir.ex @@ -766,7 +766,7 @@ defmodule Mix.Compilers.Elixir do defp purge_modules_in_path(path) do with {:ok, beams} <- File.ls(path) do Enum.each(beams, fn beam -> - module = beam |> Path.rootname() |> String.to_atom() + module = beam |> Path.rootname() |> String.to_unsafe_atom() if Code.loaded?(module) do :code.purge(module) diff --git a/lib/mix/lib/mix/compilers/erlang.ex b/lib/mix/lib/mix/compilers/erlang.ex index c88857a8fe6..5f77a261698 100644 --- a/lib/mix/lib/mix/compilers/erlang.ex +++ b/lib/mix/lib/mix/compilers/erlang.ex @@ -371,6 +371,6 @@ defmodule Mix.Compilers.Erlang do end defp module_from_path(path) do - path |> Path.basename() |> Path.rootname() |> String.to_atom() + path |> Path.basename() |> Path.rootname() |> String.to_unsafe_atom() end end diff --git a/lib/mix/lib/mix/dep.ex b/lib/mix/lib/mix/dep.ex index 151c7efe819..254362aea22 100644 --- a/lib/mix/lib/mix/dep.ex +++ b/lib/mix/lib/mix/dep.ex @@ -549,7 +549,7 @@ defmodule Mix.Dep do defp to_app_names(given) do Enum.map(given, fn app -> - if is_binary(app), do: String.to_atom(app), else: app + if is_binary(app), do: String.to_unsafe_atom(app), else: app end) end end diff --git a/lib/mix/lib/mix/dep/fetcher.ex b/lib/mix/lib/mix/dep/fetcher.ex index 1e477e8f4af..e881c8c323f 100644 --- a/lib/mix/lib/mix/dep/fetcher.ex +++ b/lib/mix/lib/mix/dep/fetcher.ex @@ -161,7 +161,7 @@ defmodule Mix.Dep.Fetcher do defp to_app_names(given) do Enum.map(given, fn app -> - if is_binary(app), do: String.to_atom(app), else: app + if is_binary(app), do: String.to_unsafe_atom(app), else: app end) end diff --git a/lib/mix/lib/mix/local/installer.ex b/lib/mix/lib/mix/local/installer.ex index 59c1f6eb47b..65393898283 100644 --- a/lib/mix/lib/mix/local/installer.ex +++ b/lib/mix/lib/mix/local/installer.ex @@ -252,11 +252,11 @@ defmodule Mix.Local.Installer do end dep_opts = [ - hex: String.to_atom(package_name), + hex: String.to_unsafe_atom(package_name), repo: hex_repo(opts) ] - {:fetcher, {String.to_atom(app_name), version, dep_opts}} + {:fetcher, {String.to_unsafe_atom(app_name), version, dep_opts}} end def parse_args(["hex" | [_package_name | rest]], _opts) do @@ -283,7 +283,7 @@ defmodule Mix.Local.Installer do "new package" end - {:fetcher, {String.to_atom(app_name), git_opts}} + {:fetcher, {String.to_unsafe_atom(app_name), git_opts}} end defp ref_to_config("branch", branch), do: [branch: branch] diff --git a/lib/mix/lib/mix/project.ex b/lib/mix/lib/mix/project.ex index 93ff56bed96..4d915481c08 100644 --- a/lib/mix/lib/mix/project.ex +++ b/lib/mix/lib/mix/project.ex @@ -280,7 +280,7 @@ defmodule Mix.Project do do: apply(module, state_loader, []), else: [] - task = String.to_atom(task || config[:default_task] || "run") + task = String.to_unsafe_atom(task || config[:default_task] || "run") if !System.get_env("MIX_ENV") do if env = config[:preferred_envs][task] || @preferred_envs[task] || config[:default_env] do @@ -480,7 +480,7 @@ defmodule Mix.Project do defp umbrella_apps(nil, apps_path) do case File.ls(apps_path) do - {:ok, apps} -> Enum.map(apps, &String.to_atom/1) + {:ok, apps} -> Enum.map(apps, &String.to_unsafe_atom/1) {:error, _} -> [] end end diff --git a/lib/mix/lib/mix/state.ex b/lib/mix/lib/mix/state.ex index 425707c3402..056c4f59928 100644 --- a/lib/mix/lib/mix/state.ex +++ b/lib/mix/lib/mix/state.ex @@ -88,7 +88,7 @@ defmodule Mix.State do case System.get_env(varname) do nil -> default "" -> default - value -> String.to_atom(value) + value -> String.to_unsafe_atom(value) end end @@ -112,7 +112,7 @@ defmodule Mix.State do defp app_from_code_path(path) do case path |> Enum.reverse() |> discard_ebin() |> collect_dir([]) do [] -> nil - app -> List.to_atom(app) + app -> List.to_unsafe_atom(app) end end diff --git a/lib/mix/lib/mix/task.ex b/lib/mix/lib/mix/task.ex index da21368cac6..d336ba639cd 100644 --- a/lib/mix/lib/mix/task.ex +++ b/lib/mix/lib/mix/task.ex @@ -309,7 +309,7 @@ defmodule Mix.Task do """ @spec alias?(task_name) :: boolean def alias?(task) when is_binary(task) do - alias?(String.to_atom(task)) + alias?(String.to_unsafe_atom(task)) end def alias?(task) when is_atom(task) do @@ -419,7 +419,7 @@ defmodule Mix.Task do defp do_run(task, args, apps) when is_binary(task) do proj = Mix.Project.get() - alias = Mix.Project.config()[:aliases][String.to_atom(task)] + alias = Mix.Project.config()[:aliases][String.to_unsafe_atom(task)] cond do alias && Mix.TasksServer.run({:alias, task, proj}) -> @@ -441,7 +441,7 @@ defmodule Mix.Task do end defp recur_umbrella_children_alias(task, args, apps) do - alias_key = String.to_atom(task) + alias_key = String.to_unsafe_atom(task) entries = Mix.ProjectStack.recur(fn -> diff --git a/lib/mix/lib/mix/tasks/app.tree.ex b/lib/mix/lib/mix/tasks/app.tree.ex index 02d0114af1e..6bf9a489f6e 100644 --- a/lib/mix/lib/mix/tasks/app.tree.ex +++ b/lib/mix/lib/mix/tasks/app.tree.ex @@ -65,10 +65,10 @@ defmodule Mix.Tasks.App.Tree do {app, opts} {opts, [app]} -> - {String.to_atom(app), opts} + {String.to_unsafe_atom(app), opts} end - excluded = Keyword.get_values(opts, :exclude) |> Enum.map(&String.to_atom/1) + excluded = Keyword.get_values(opts, :exclude) |> Enum.map(&String.to_unsafe_atom/1) excluded = @default_excluded ++ excluded callback = fn {app, type} -> diff --git a/lib/mix/lib/mix/tasks/cmd.ex b/lib/mix/lib/mix/tasks/cmd.ex index db2c852daba..65c2c3b24b2 100644 --- a/lib/mix/lib/mix/tasks/cmd.ex +++ b/lib/mix/lib/mix/tasks/cmd.ex @@ -106,7 +106,7 @@ defmodule Mix.Tasks.Cmd do apps = opts |> Keyword.get_values(:app) - |> Enum.map(&String.to_atom/1) + |> Enum.map(&String.to_unsafe_atom/1) if apps != [] do IO.warn("the --app in mix cmd is deprecated. Use mix do --app instead.") diff --git a/lib/mix/lib/mix/tasks/compile.app.ex b/lib/mix/lib/mix/tasks/compile.app.ex index 8a4b99d617d..fb2b453765e 100644 --- a/lib/mix/lib/mix/tasks/compile.app.ex +++ b/lib/mix/lib/mix/tasks/compile.app.ex @@ -263,7 +263,7 @@ defmodule Mix.Tasks.Compile.App do Enum.sort( for entry <- entries, String.ends_with?(entry, ".beam"), - do: entry |> binary_part(0, byte_size(entry) - 5) |> String.to_atom() + do: entry |> binary_part(0, byte_size(entry) - 5) |> String.to_unsafe_atom() ) {:error, _} -> diff --git a/lib/mix/lib/mix/tasks/compile.erlang.ex b/lib/mix/lib/mix/tasks/compile.erlang.ex index 94194ff3f1c..aaf3c201df2 100644 --- a/lib/mix/lib/mix/tasks/compile.erlang.ex +++ b/lib/mix/lib/mix/tasks/compile.erlang.ex @@ -91,7 +91,7 @@ defmodule Mix.Tasks.Compile.Erlang do Erlang.compile_entries(manifest(), sorted, :erl, :beam, opts, fn input, _output -> # We're purging the module because a previous compiler (for example, Phoenix) # might have already loaded the previous version of it. - module = input |> Path.basename(".erl") |> String.to_atom() + module = input |> Path.basename(".erl") |> String.to_unsafe_atom() :code.purge(module) :code.delete(module) @@ -131,7 +131,7 @@ defmodule Mix.Tasks.Compile.Erlang do output |> Path.basename() |> Path.rootname() - |> String.to_atom() + |> String.to_unsafe_atom() end end @@ -248,6 +248,6 @@ defmodule Mix.Tasks.Compile.Erlang do end defp module_from_artifact(artifact) do - artifact |> Path.basename() |> Path.rootname() |> String.to_atom() + artifact |> Path.basename() |> Path.rootname() |> String.to_unsafe_atom() end end diff --git a/lib/mix/lib/mix/tasks/compile.ex b/lib/mix/lib/mix/tasks/compile.ex index 62d91a53cb1..58d5e692491 100644 --- a/lib/mix/lib/mix/tasks/compile.ex +++ b/lib/mix/lib/mix/tasks/compile.ex @@ -222,7 +222,7 @@ defmodule Mix.Tasks.Compile do defp load_protocol(file) do case file do "Elixir." <> _ -> - module = file |> Path.rootname() |> String.to_atom() + module = file |> Path.rootname() |> String.to_unsafe_atom() :code.purge(module) :code.delete(module) diff --git a/lib/mix/lib/mix/tasks/deps.ex b/lib/mix/lib/mix/tasks/deps.ex index 82d4e42fc48..b0b28a8e590 100644 --- a/lib/mix/lib/mix/tasks/deps.ex +++ b/lib/mix/lib/mix/tasks/deps.ex @@ -206,7 +206,7 @@ defmodule Mix.Tasks.Deps do apps = apps - |> Enum.map(&String.to_atom/1) + |> Enum.map(&String.to_unsafe_atom/1) |> Enum.uniq() # Sort deps when showing all or preserve input order when filtering diff --git a/lib/mix/lib/mix/tasks/deps.partition.ex b/lib/mix/lib/mix/tasks/deps.partition.ex index 287661f7a0d..8a2943d89bd 100644 --- a/lib/mix/lib/mix/tasks/deps.partition.ex +++ b/lib/mix/lib/mix/tasks/deps.partition.ex @@ -153,7 +153,7 @@ defmodule Mix.Tasks.Deps.Partition do receive do {:tcp, socket, data} -> [app, compiled?] = - data |> String.trim() |> String.split(":") |> Enum.map(&String.to_atom/1) + data |> String.trim() |> String.split(":") |> Enum.map(&String.to_unsafe_atom/1) deps = Enum.reject(deps, &(&1.app == app)) status = Map.replace!(status, app, compiled?) @@ -313,7 +313,7 @@ defmodule Mix.Tasks.Deps.Partition do def client_loop(socket, deps, force?, config) do case :gen_tcp.recv(socket, 0, :infinity) do {:ok, app} -> - app = app |> String.trim() |> String.to_atom() + app = app |> String.trim() |> String.to_unsafe_atom() dep = Enum.find(deps, &(&1.app == app)) || raise "could not find dependency #{inspect(app)}" diff --git a/lib/mix/lib/mix/tasks/deps.tree.ex b/lib/mix/lib/mix/tasks/deps.tree.ex index 7b8164804fe..6a59be32e65 100644 --- a/lib/mix/lib/mix/tasks/deps.tree.ex +++ b/lib/mix/lib/mix/tasks/deps.tree.ex @@ -96,7 +96,7 @@ defmodule Mix.Tasks.Deps.Tree do Mix.raise("no application given and none found in mix.exs file") [app] -> - app = String.to_atom(app) + app = String.to_unsafe_atom(app) find_dep(deps, app) || Mix.raise("could not find dependency #{app}") end @@ -127,7 +127,7 @@ defmodule Mix.Tasks.Deps.Tree do defp callback(formatter, deps, opts) do umbrella_only? = Keyword.get(opts, :umbrella_only, false) - excluded = Keyword.get_values(opts, :exclude) |> Enum.map(&String.to_atom/1) + excluded = Keyword.get_values(opts, :exclude) |> Enum.map(&String.to_unsafe_atom/1) if umbrella_only? && !Mix.Project.parent_umbrella_project_file() do Mix.raise("The --umbrella-only option can only be used in umbrella projects") diff --git a/lib/mix/lib/mix/tasks/deps.unlock.ex b/lib/mix/lib/mix/tasks/deps.unlock.ex index 9bc109578d7..4901bccc95d 100644 --- a/lib/mix/lib/mix/tasks/deps.unlock.ex +++ b/lib/mix/lib/mix/tasks/deps.unlock.ex @@ -73,7 +73,7 @@ defmodule Mix.Tasks.Deps.Unlock do apps != [] -> lock = Mix.Dep.Lock.read() - apps = Enum.map(apps, &String.to_atom/1) + apps = Enum.map(apps, &String.to_unsafe_atom/1) unlocked = apps -- Map.keys(lock) for app <- unlocked do diff --git a/lib/mix/lib/mix/tasks/deps.update.ex b/lib/mix/lib/mix/tasks/deps.update.ex index 4e650a9c8ce..f9bed188fa9 100644 --- a/lib/mix/lib/mix/tasks/deps.update.ex +++ b/lib/mix/lib/mix/tasks/deps.update.ex @@ -78,7 +78,7 @@ defmodule Mix.Tasks.Deps.Update do defp to_app_names(given) do Enum.map(given, fn app -> - if is_binary(app), do: String.to_atom(app), else: app + if is_binary(app), do: String.to_unsafe_atom(app), else: app end) end end diff --git a/lib/mix/lib/mix/tasks/do.ex b/lib/mix/lib/mix/tasks/do.ex index ab4cf23e390..76299fecf45 100644 --- a/lib/mix/lib/mix/tasks/do.ex +++ b/lib/mix/lib/mix/tasks/do.ex @@ -114,7 +114,7 @@ defmodule Mix.Tasks.Do do apps = opts |> Keyword.get_values(:app) - |> Enum.map(&String.to_atom/1) + |> Enum.map(&String.to_unsafe_atom/1) {apps, args} end diff --git a/lib/mix/lib/mix/tasks/escript.build.ex b/lib/mix/lib/mix/tasks/escript.build.ex index 53629183a9c..e1c76efc999 100644 --- a/lib/mix/lib/mix/tasks/escript.build.ex +++ b/lib/mix/lib/mix/tasks/escript.build.ex @@ -188,7 +188,7 @@ defmodule Mix.Tasks.Escript.Build do end) |> parse_strip_beams_options() - escript_mod = String.to_atom(Atom.to_string(app) <> "_escript") + escript_mod = String.to_unsafe_atom(Atom.to_string(app) <> "_escript") include_priv_for = MapSet.new(escript_opts[:include_priv_for] || []) diff --git a/lib/mix/lib/mix/tasks/help.ex b/lib/mix/lib/mix/tasks/help.ex index 54834bc9863..c478bd8a1b0 100644 --- a/lib/mix/lib/mix/tasks/help.ex +++ b/lib/mix/lib/mix/tasks/help.ex @@ -115,7 +115,7 @@ defmodule Mix.Tasks.Help do def run(["app:" <> app]) do loadpaths!() - app = String.to_atom(app) + app = String.to_unsafe_atom(app) # If the application is not available, attempt to load it from Erlang/Elixir if is_nil(Application.spec(app, :vsn)) do diff --git a/lib/mix/lib/mix/tasks/new.ex b/lib/mix/lib/mix/tasks/new.ex index 8cdf7ff9aab..a8dbc3c101a 100644 --- a/lib/mix/lib/mix/tasks/new.ex +++ b/lib/mix/lib/mix/tasks/new.ex @@ -209,7 +209,7 @@ defmodule Mix.Tasks.New do end defp reserved_app(name) do - atom_name = String.to_atom(name) + atom_name = String.to_unsafe_atom(name) if atom_name in reserved_application_names() or Application.ensure_loaded(atom_name) == :ok do "Cannot use application name #{inspect(name)} because it is already used by Erlang/OTP or Elixir" diff --git a/lib/mix/lib/mix/tasks/release.ex b/lib/mix/lib/mix/tasks/release.ex index b9cc0caa4bf..34253f79d7c 100644 --- a/lib/mix/lib/mix/tasks/release.ex +++ b/lib/mix/lib/mix/tasks/release.ex @@ -1067,9 +1067,14 @@ defmodule Mix.Tasks.Release do release = case OptionParser.parse!(args, strict: @switches, aliases: @aliases) do - {overrides, [name]} -> Mix.Release.from_config!(String.to_atom(name), config, overrides) - {overrides, []} -> Mix.Release.from_config!(nil, config, overrides) - {_, _} -> Mix.raise("Expected \"mix release\" or \"mix release NAME\"") + {overrides, [name]} -> + Mix.Release.from_config!(String.to_unsafe_atom(name), config, overrides) + + {overrides, []} -> + Mix.Release.from_config!(nil, config, overrides) + + {_, _} -> + Mix.raise("Expected \"mix release\" or \"mix release NAME\"") end if not File.exists?(release.version_path) or diff --git a/lib/mix/lib/mix/tasks/test.coverage.ex b/lib/mix/lib/mix/tasks/test.coverage.ex index 267d9bf38ca..d9cdbc8b94e 100644 --- a/lib/mix/lib/mix/tasks/test.coverage.ex +++ b/lib/mix/lib/mix/tasks/test.coverage.ex @@ -248,7 +248,7 @@ defmodule Mix.Tasks.Test.Coverage do for file <- File.ls!(dir), Path.extname(file) == ".beam" do with true <- file in consolidated, - [_ | _] = path <- :code.which(file |> Path.rootname() |> String.to_atom()) do + [_ | _] = path <- :code.which(file |> Path.rootname() |> String.to_unsafe_atom()) do path else _ -> String.to_charlist(Path.join(dir, file)) diff --git a/lib/mix/test/fixtures/escript_test/lib/escript_test.ex b/lib/mix/test/fixtures/escript_test/lib/escript_test.ex index 2dd248824a1..44a5aff7ea9 100644 --- a/lib/mix/test/fixtures/escript_test/lib/escript_test.ex +++ b/lib/mix/test/fixtures/escript_test/lib/escript_test.ex @@ -26,7 +26,7 @@ defmodule EscriptTest do # Note: :erl_prim_loader usage with Escript is currently deprecated, # but we use it only in tests for convenience - app = String.to_atom(app_name) + app = String.to_unsafe_atom(app_name) :erl_prim_loader.list_dir(~c"#{:code.lib_dir(app)}/priv") |> IO.inspect() end diff --git a/lib/mix/test/mix/tasks/release_test.exs b/lib/mix/test/mix/tasks/release_test.exs index 414802821ce..4a79df298c7 100644 --- a/lib/mix/test/mix/tasks/release_test.exs +++ b/lib/mix/test/mix/tasks/release_test.exs @@ -554,7 +554,7 @@ defmodule Mix.Tasks.ReleaseTest do File.write!("different_config/runtime.exs", """ import Config - config :release_test, :static, String.to_atom(System.get_env("RELEASE_STATIC")) + config :release_test, :static, String.to_unsafe_atom(System.get_env("RELEASE_STATIC")) """) Mix.Project.in_project(:release_test, ".", config, fn _ -> @@ -594,7 +594,7 @@ defmodule Mix.Tasks.ReleaseTest do File.write!("config/runtime.exs", """ import Config - config :release_test, :static, String.to_atom(System.get_env("RELEASE_STATIC")) + config :release_test, :static, String.to_unsafe_atom(System.get_env("RELEASE_STATIC")) config :release_test, :runtime, mode: :code.get_mode() """) diff --git a/lib/mix/test/mix/tasks/xref_test.exs b/lib/mix/test/mix/tasks/xref_test.exs index d925ad72e9b..2e858983281 100644 --- a/lib/mix/test/mix/tasks/xref_test.exs +++ b/lib/mix/test/mix/tasks/xref_test.exs @@ -86,7 +86,7 @@ defmodule Mix.Tasks.XrefTest do Mix.Task.run("compile") after_compile.() - xref = String.to_atom("Elixir.Mix.Tasks.Xref") + xref = String.to_unsafe_atom("Elixir.Mix.Tasks.Xref") assert Enum.sort(xref.calls()) == Enum.sort(expected) end) end