-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Closed
Description
Elixir and Erlang/OTP versions
Erlang/OTP 27 [erts-15.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]
Elixir 1.17.2 (compiled with Erlang/OTP 27)
Operating system
linux
Current behavior
Create an empty project, insert this code and try to compile it by calling mix
. Compilation will freeze
defmodule Xxx do
def hello do
variable = :x
fn
:delete, {x, function} ->
try do
{:ok,
x
|> case do
%{x: value} = map ->
%{
map
| x:
value
|> case do
%{^variable => value} = map ->
case function.(value) do
{:ok, new_value} -> %{map | variable => new_value}
:delete_me -> Map.delete(map, variable)
:error -> throw(:path_not_found)
end
[{_, _} | _] = keyword when is_atom(variable) ->
Pathex.Builder.SimpleDeleter.keyword_update(keyword, variable, function)
list when is_list(list) and is_integer(variable) and variable >= 0 ->
if variable >= length(list) do
throw(:path_not_found)
else
case function.(:lists.nth(variable + 1, list)) do
{:ok, new_value} -> List.replace_at(list, variable, new_value)
:delete_me -> List.delete_at(list, variable)
:error -> throw(:path_not_found)
end
end
list when is_list(list) and is_integer(variable) and variable < 0 ->
index = length(list) + variable
if index < 0 do
throw(:path_not_found)
else
case function.(:lists.nth(index + 1, list)) do
{:ok, new_value} -> List.replace_at(list, index, new_value)
:delete_me -> List.delete_at(list, index)
:error -> throw(:path_not_found)
end
end
tuple
when is_tuple(tuple) and is_integer(variable) and variable >= 0 and
tuple_size(tuple) > variable ->
index = variable + 1
case function.(:erlang.element(index, tuple)) do
{:ok, new_value} -> :erlang.setelement(index, tuple, new_value)
:delete_me -> :erlang.delete_element(index, tuple)
:error -> throw(:path_not_found)
end
tuple
when is_tuple(tuple) and is_integer(variable) and variable < 0 and
tuple_size(tuple) >= -variable ->
index = tuple_size(tuple) + variable + 1
case function.(:erlang.element(index, tuple)) do
{:ok, new_value} -> :erlang.setelement(index, tuple, new_value)
:delete_me -> :erlang.delete_element(index, tuple)
:error -> throw(:path_not_found)
end
_ ->
throw(:path_not_found)
end
}
[{a, _} | _] = keyword when is_atom(a) ->
Pathex.Builder.Setter.keyword_update(keyword, :x, fn x ->
x
|> case do
%{^variable => value} = map ->
case function.(value) do
{:ok, new_value} -> %{map | variable => new_value}
:delete_me -> Map.delete(map, variable)
:error -> throw(:path_not_found)
end
[{_, _} | _] = keyword when is_atom(variable) ->
Pathex.Builder.SimpleDeleter.keyword_update(keyword, variable, function)
list when is_list(list) and is_integer(variable) and variable >= 0 ->
if variable >= length(list) do
throw(:path_not_found)
else
case function.(:lists.nth(variable + 1, list)) do
{:ok, new_value} -> List.replace_at(list, variable, new_value)
:delete_me -> List.delete_at(list, variable)
:error -> throw(:path_not_found)
end
end
list when is_list(list) and is_integer(variable) and variable < 0 ->
index = length(list) + variable
if index < 0 do
throw(:path_not_found)
else
case function.(:lists.nth(index + 1, list)) do
{:ok, new_value} -> List.replace_at(list, index, new_value)
:delete_me -> List.delete_at(list, index)
:error -> throw(:path_not_found)
end
end
tuple
when is_tuple(tuple) and is_integer(variable) and variable >= 0 and
tuple_size(tuple) > variable ->
index = variable + 1
case function.(:erlang.element(index, tuple)) do
{:ok, new_value} -> :erlang.setelement(index, tuple, new_value)
:delete_me -> :erlang.delete_element(index, tuple)
:error -> throw(:path_not_found)
end
tuple
when is_tuple(tuple) and is_integer(variable) and variable < 0 and
tuple_size(tuple) >= -variable ->
index = tuple_size(tuple) + variable + 1
case function.(:erlang.element(index, tuple)) do
{:ok, new_value} -> :erlang.setelement(index, tuple, new_value)
:delete_me -> :erlang.delete_element(index, tuple)
:error -> throw(:path_not_found)
end
_ ->
throw(:path_not_found)
end
end)
_ ->
throw(:path_not_found)
end}
catch
:path_not_found -> :error
end
:inspect, _ ->
{:path, [], [{:/, [], [:x, variable]}]}
:update, {x, function} ->
try do
{:ok,
x
|> case do
%{x: value} = map ->
%{
map
| x:
value
|> case do
%{^variable => value} = map ->
%{
map
| variable =>
value
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
}
keyword when is_list(keyword) and is_atom(variable) ->
Pathex.Builder.Setter.keyword_update(keyword, variable, fn x ->
x
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
end)
list when is_list(list) and is_integer(variable) and variable >= 0 ->
if variable >= length(list) do
throw(:path_not_found)
else
List.update_at(list, variable, fn x ->
x
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
end)
end
list when is_list(list) and is_integer(variable) and variable < 0 ->
if -variable > length(list) do
throw(:path_not_found)
else
List.update_at(list, variable, fn x ->
x
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
end)
end
tuple
when is_tuple(tuple) and is_integer(variable) and variable >= 0 and
tuple_size(tuple) > variable ->
indexplusone = variable + 1
val =
indexplusone
|> :erlang.element(tuple)
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
:erlang.setelement(indexplusone, tuple, val)
tuple
when is_tuple(tuple) and is_integer(variable) and variable < 0 and
tuple_size(tuple) >= -variable ->
index = tuple_size(tuple) + variable + 1
val =
:erlang.element(index, tuple)
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
:erlang.setelement(index, tuple, val)
_ ->
throw(:path_not_found)
end
}
[{a, _} | _] = keyword when is_atom(a) ->
Pathex.Builder.Setter.keyword_update(keyword, :x, fn x ->
x
|> case do
%{^variable => value} = map ->
%{
map
| variable =>
value
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
}
keyword when is_list(keyword) and is_atom(variable) ->
Pathex.Builder.Setter.keyword_update(keyword, variable, fn x ->
x
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
end)
list when is_list(list) and is_integer(variable) and variable >= 0 ->
if variable >= length(list) do
throw(:path_not_found)
else
List.update_at(list, variable, fn x ->
x
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
end)
end
list when is_list(list) and is_integer(variable) and variable < 0 ->
if -variable > length(list) do
throw(:path_not_found)
else
List.update_at(list, variable, fn x ->
x
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
end)
end
tuple
when is_tuple(tuple) and is_integer(variable) and variable >= 0 and
tuple_size(tuple) > variable ->
indexplusone = variable + 1
val =
indexplusone
|> :erlang.element(tuple)
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
:erlang.setelement(indexplusone, tuple, val)
tuple
when is_tuple(tuple) and is_integer(variable) and variable < 0 and
tuple_size(tuple) >= -variable ->
index = tuple_size(tuple) + variable + 1
val =
:erlang.element(index, tuple)
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
:erlang.setelement(index, tuple, val)
_ ->
throw(:path_not_found)
end
end)
_ ->
throw(:path_not_found)
end}
catch
:path_not_found -> :error
end
:view, {x, function} ->
x
|> case do
%{x: x} ->
case x do
%{^variable => x} ->
function.(x)
kwd when is_list(kwd) and is_atom(variable) ->
with {:ok, value} <- Keyword.fetch(kwd, variable) do
function.(value)
end
list when is_list(list) and is_integer(variable) ->
case Enum.at(list, variable, :__pathex_var_not_found__) do
:__pathex_var_not_found__ -> :error
value -> function.(value)
end
tuple
when is_tuple(tuple) and is_integer(variable) and variable >= 0 and
tuple_size(tuple) > variable ->
function.(elem(tuple, variable))
tuple
when is_tuple(tuple) and is_integer(variable) and variable < 0 and
tuple_size(tuple) >= -variable ->
index = tuple_size(tuple) + variable + 1
function.(:erlang.element(index, tuple))
_ ->
:error
end
kwd when is_list(kwd) ->
with {:ok, value} <- Keyword.fetch(kwd, :x) do
case value do
%{^variable => x} ->
function.(x)
kwd when is_list(kwd) and is_atom(variable) ->
with {:ok, value} <- Keyword.fetch(kwd, variable) do
function.(value)
end
list when is_list(list) and is_integer(variable) ->
case Enum.at(list, variable, :__pathex_var_not_found__) do
:__pathex_var_not_found__ -> :error
value -> function.(value)
end
tuple
when is_tuple(tuple) and is_integer(variable) and variable >= 0 and
tuple_size(tuple) > variable ->
function.(elem(tuple, variable))
tuple
when is_tuple(tuple) and is_integer(variable) and variable < 0 and
tuple_size(tuple) >= -variable ->
index = tuple_size(tuple) + variable + 1
function.(:erlang.element(index, tuple))
_ ->
:error
end
end
_ ->
:error
end
:force_update, {x, function, default} ->
try do
{:ok,
x
|> case do
%{x: value} = map ->
%{
map
| x:
value
|> case do
%{^variable => value} = map ->
%{
map
| variable =>
value
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
}
keyword when is_list(keyword) and is_atom(variable) ->
Keyword.update(keyword, variable, default, fn val ->
val
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
end)
list when is_list(list) and variable == -1 ->
[default | list]
list when is_list(list) and is_integer(variable) and variable < 0 ->
length = length(list)
if -variable > length do
len = max(-variable - 1 - length, 0)
[default | List.duplicate(nil, len)] ++ list
else
List.update_at(list, variable, fn x ->
x
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
end)
end
list when is_list(list) and is_integer(variable) ->
length = length(list)
if variable > length do
len = max(variable - length, 0)
list ++ List.duplicate(nil, len) ++ [default]
else
List.update_at(list, variable, fn x ->
x
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
end)
end
tuple
when is_tuple(tuple) and is_integer(variable) and variable >= 0 and
tuple_size(tuple) <= variable ->
len = max(variable - tuple_size(tuple), 0)
List.to_tuple(Tuple.to_list(tuple) ++ List.duplicate(nil, len) ++ [default])
tuple
when is_tuple(tuple) and is_integer(variable) and variable < 0 and
tuple_size(tuple) < -variable ->
len = max(-variable - tuple_size(tuple) - 1, 0)
List.to_tuple([default | List.duplicate(nil, len)] ++ Tuple.to_list(tuple))
tuple when is_tuple(tuple) and is_integer(variable) and variable < 0 ->
index = tuple_size(tuple) + variable + 1
val =
:erlang.element(index, tuple)
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
:erlang.setelement(index, tuple, val)
tuple when is_tuple(tuple) and is_integer(variable) and variable >= 0 ->
indexplusone = variable + 1
val =
indexplusone
|> :erlang.element(tuple)
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
:erlang.setelement(indexplusone, tuple, val)
%{} = other ->
Map.put(other, variable, default)
kwd when is_list(kwd) ->
[{variable, default} | kwd]
l when is_list(l) and variable == -1 ->
[default | l]
l when is_list(l) and is_integer(variable) and variable >= 0 ->
len = max(variable - length(l), 0)
l ++ List.duplicate(nil, len) ++ [default]
l when is_list(l) and is_integer(variable) ->
len = max(-variable - 1 - length(l), 0)
[default | List.duplicate(nil, len)] ++ l
t when is_tuple(t) and is_integer(variable) and variable >= 0 ->
len = variable - tuple_size(t)
List.to_tuple(Tuple.to_list(t) ++ List.duplicate(nil, len) ++ [default])
t when is_tuple(t) and is_integer(variable) ->
len = -variable - tuple_size(t) - 1
List.to_tuple([default | List.duplicate(nil, len)] ++ Tuple.to_list(t))
_ ->
throw(:path_not_found)
end
}
keyword when is_list(keyword) ->
Keyword.update(keyword, :x, %{variable => default}, fn val ->
val
|> case do
%{^variable => value} = map ->
%{
map
| variable =>
value
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
}
keyword when is_list(keyword) and is_atom(variable) ->
Keyword.update(keyword, variable, default, fn val ->
val
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
end)
list when is_list(list) and variable == -1 ->
[default | list]
list when is_list(list) and is_integer(variable) and variable < 0 ->
length = length(list)
if -variable > length do
len = max(-variable - 1 - length, 0)
[default | List.duplicate(nil, len)] ++ list
else
List.update_at(list, variable, fn x ->
x
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
end)
end
list when is_list(list) and is_integer(variable) ->
length = length(list)
if variable > length do
len = max(variable - length, 0)
list ++ List.duplicate(nil, len) ++ [default]
else
List.update_at(list, variable, fn x ->
x
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
end)
end
tuple
when is_tuple(tuple) and is_integer(variable) and variable >= 0 and
tuple_size(tuple) <= variable ->
len = max(variable - tuple_size(tuple), 0)
List.to_tuple(Tuple.to_list(tuple) ++ List.duplicate(nil, len) ++ [default])
tuple
when is_tuple(tuple) and is_integer(variable) and variable < 0 and
tuple_size(tuple) < -variable ->
len = max(-variable - tuple_size(tuple) - 1, 0)
List.to_tuple([default | List.duplicate(nil, len)] ++ Tuple.to_list(tuple))
tuple when is_tuple(tuple) and is_integer(variable) and variable < 0 ->
index = tuple_size(tuple) + variable + 1
val =
:erlang.element(index, tuple)
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
:erlang.setelement(index, tuple, val)
tuple when is_tuple(tuple) and is_integer(variable) and variable >= 0 ->
indexplusone = variable + 1
val =
indexplusone
|> :erlang.element(tuple)
|> (function.()
|> case do
{:ok, value} -> value
:error -> throw(:path_not_found)
end)
:erlang.setelement(indexplusone, tuple, val)
%{} = other ->
Map.put(other, variable, default)
kwd when is_list(kwd) ->
[{variable, default} | kwd]
l when is_list(l) and variable == -1 ->
[default | l]
l when is_list(l) and is_integer(variable) and variable >= 0 ->
len = max(variable - length(l), 0)
l ++ List.duplicate(nil, len) ++ [default]
l when is_list(l) and is_integer(variable) ->
len = max(-variable - 1 - length(l), 0)
[default | List.duplicate(nil, len)] ++ l
t when is_tuple(t) and is_integer(variable) and variable >= 0 ->
len = variable - tuple_size(t)
List.to_tuple(Tuple.to_list(t) ++ List.duplicate(nil, len) ++ [default])
t when is_tuple(t) and is_integer(variable) ->
len = -variable - tuple_size(t) - 1
List.to_tuple([default | List.duplicate(nil, len)] ++ Tuple.to_list(t))
_ ->
throw(:path_not_found)
end
end)
%{} = other ->
Map.put(other, :x, %{variable => default})
kwd when is_list(kwd) ->
[{:x, %{variable => default}} | kwd]
_ ->
throw(:path_not_found)
end}
catch
:path_not_found -> :error
end
end
end
end
Expected behavior
This code doesn't freeze the compilation and is compiled successfully (as in 1.16, for example)
Metadata
Metadata
Assignees
Labels
No labels