summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichał Muskała <michal@muskala.eu>2018-06-19 13:15:47 +0200
committerMichał Muskała <michal@muskala.eu>2018-06-19 14:33:09 +0200
commite6b1bbe74a78e1ddf8c89aa03d82c04dae21cdc1 (patch)
tree5e96898a9b156e12a18ab2457bb5a8e0ae3cce74
parent41e4a41a9ec2314d9937467a3d6d2b91b48c47f5 (diff)
downloadelixir-mm/bool-optim.tar.gz
Restore and/or optimisationmm/bool-optim
The optimize_boolean option is very sensitive to the order of clauses and the optimisation was not happening for and/2 and or/2. Add regression tests to ensure that won't happen again. Removes tests that dialyzer does not emit warnings for optimised and and or - those warnings could actually be helpful.
-rw-r--r--lib/elixir/lib/kernel.ex11
-rw-r--r--lib/elixir/test/elixir/fixtures/dialyzer/boolean_check.ex8
-rw-r--r--lib/elixir/test/erlang/control_test.erl12
3 files changed, 15 insertions, 16 deletions
diff --git a/lib/elixir/lib/kernel.ex b/lib/elixir/lib/kernel.ex
index f6ace1e2c..119b9f1c9 100644
--- a/lib/elixir/lib/kernel.ex
+++ b/lib/elixir/lib/kernel.ex
@@ -1540,14 +1540,9 @@ defmodule Kernel do
optimize_boolean(
quote do
case unquote(check) do
- true ->
- unquote(true_clause)
-
- false ->
- unquote(false_clause)
-
- other ->
- :erlang.error(BadBooleanError.exception(operator: unquote(operator), term: other))
+ false -> unquote(false_clause)
+ true -> unquote(true_clause)
+ other -> :erlang.error({:badbool, unquote(operator), other})
end
end
)
diff --git a/lib/elixir/test/elixir/fixtures/dialyzer/boolean_check.ex b/lib/elixir/test/elixir/fixtures/dialyzer/boolean_check.ex
index c19234b68..e81233153 100644
--- a/lib/elixir/test/elixir/fixtures/dialyzer/boolean_check.ex
+++ b/lib/elixir/test/elixir/fixtures/dialyzer/boolean_check.ex
@@ -3,15 +3,7 @@ defmodule Dialyzer.BooleanCheck do
arg and arg
end
- def and_check_optimized(arg) when is_integer(arg) do
- arg < :infinity and arg
- end
-
def or_check(arg) when is_boolean(arg) do
arg or arg
end
-
- def or_check_optimized(arg) when is_integer(arg) do
- arg < :infinity or arg
- end
end
diff --git a/lib/elixir/test/erlang/control_test.erl b/lib/elixir/test/erlang/control_test.erl
index ba5cb523d..b01bd3e30 100644
--- a/lib/elixir/test/erlang/control_test.erl
+++ b/lib/elixir/test/erlang/control_test.erl
@@ -215,6 +215,18 @@ optimized_oror_test() ->
{clause, 1, [{var, 1, Var}], [], [{var, 1, Var}]}]
} = to_erl("is_list([]) || :done").
+optimized_and_test() ->
+ {'case',_, _,
+ [{clause, _, [{atom, 0, false}], [], [{atom, 0, false}]},
+ {clause, _, [{atom, 0, true}], [], [{atom, 0, done}]}]
+ } = to_erl("is_list([]) and :done").
+
+optimized_or_test() ->
+ {'case', _, _,
+ [{clause, _, [{atom, 0, false}], [], [{atom, 0, done}]},
+ {clause, _, [{atom, 0, true}], [], [{atom, 0, true}]}]
+ } = to_erl("is_list([]) or :done").
+
no_after_in_try_test() ->
{'try', _, [_], [_], _, []} = to_erl("try do :foo.bar() else _ -> :ok end").