Skip to content

Commit 1406a1e

Browse files
committed
Let the type system and erlang compiler decide on the meaning optimize_boolean
1 parent 425c68e commit 1406a1e

File tree

5 files changed

+28
-25
lines changed

5 files changed

+28
-25
lines changed

lib/elixir/lib/module/types/expr.ex

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,13 @@ defmodule Module.Types.Expr do
246246
def of_expr({:case, meta, [case_expr, [{:do, clauses}]]}, stack, context) do
247247
{case_type, context} = of_expr(case_expr, stack, context)
248248

249-
clauses
249+
# If we are only type checking the expression and the expression is a literal,
250+
# let's mark it as generated, as it is most likely a macro code.
251+
if is_atom(case_expr) and {:type_check, :expr} in meta do
252+
for {:->, meta, args} <- clauses, do: {:->, [generated: true] ++ meta, args}
253+
else
254+
clauses
255+
end
250256
|> of_clauses([case_type], {:case, meta, case_type, case_expr}, stack, {none(), context})
251257
|> dynamic_unless_static(stack)
252258
end

lib/elixir/src/elixir_erl_pass.erl

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,9 +302,16 @@ translate(Other, Ann, S) ->
302302

303303
translate_case(Meta, Expr, Opts, S) ->
304304
Ann = ?ann(Meta),
305-
Clauses = elixir_erl_clauses:get_clauses(do, Opts, match),
306305
{TExpr, SE} = translate(Expr, Ann, S),
307-
{TClauses, SC} = elixir_erl_clauses:clauses(Clauses, SE),
306+
Clauses = elixir_erl_clauses:get_clauses(do, Opts, match),
307+
RClauses =
308+
%% For constructs that optimize booleans, we mark them as generated
309+
%% to avoid reports from the Erlang compiler but specially Dialyzer.
310+
case lists:member({optimize_boolean, true}, Meta) of
311+
true -> [{N, ?generated(M), H, B} || {N, M, H, B} <- Clauses];
312+
false -> Clauses
313+
end,
314+
{TClauses, SC} = elixir_erl_clauses:clauses(RClauses, SE),
308315
{{'case', Ann, TExpr, TClauses}, SC}.
309316

310317
translate_list([{'|', _, [Left, Right]}], Ann, List, Acc) ->

lib/elixir/src/elixir_expand.erl

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -720,15 +720,9 @@ expand_case(Meta, Expr, Opts, S, E) ->
720720
{EExpr, SE, EE} = expand(Expr, S, E),
721721

722722
ROpts =
723-
case proplists:get_value(optimize_boolean, Meta, false) of
724-
true ->
725-
case elixir_utils:returns_boolean(EExpr) of
726-
true -> rewrite_case_clauses(Opts);
727-
false -> generated_case_clauses(Opts)
728-
end;
729-
730-
false ->
731-
Opts
723+
case lists:member({optimize_boolean, true}, Meta) andalso elixir_utils:returns_boolean(EExpr) of
724+
true -> rewrite_case_clauses(Opts);
725+
false -> Opts
732726
end,
733727

734728
{EOpts, SO, EO} = elixir_clauses:'case'(Meta, ROpts, SE, EE),
@@ -752,19 +746,15 @@ rewrite_case_clauses([{do, [
752746
]}]) ->
753747
rewrite_case_clauses(FalseMeta, FalseExpr, TrueMeta, TrueExpr);
754748

755-
rewrite_case_clauses(Other) ->
756-
generated_case_clauses(Other).
749+
rewrite_case_clauses(Opts) ->
750+
Opts.
757751

758752
rewrite_case_clauses(FalseMeta, FalseExpr, TrueMeta, TrueExpr) ->
759753
[{do, [
760-
{'->', ?generated(FalseMeta), [[false], FalseExpr]},
761-
{'->', ?generated(TrueMeta), [[true], TrueExpr]}
754+
{'->', FalseMeta, [[false], FalseExpr]},
755+
{'->', TrueMeta, [[true], TrueExpr]}
762756
]}].
763757

764-
generated_case_clauses([{do, Clauses}]) ->
765-
RClauses = [{'->', ?generated(Meta), Args} || {'->', Meta, Args} <- Clauses],
766-
[{do, RClauses}].
767-
768758
%% Comprehensions
769759

770760
expand_for({for, Meta, [_ | _] = Args}, S, E, Return) ->

lib/elixir/test/elixir/kernel/import_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ defmodule Kernel.ImportTest do
219219
end
220220

221221
test "import lexical on case" do
222-
case true do
222+
case Process.get(:unused, true) do
223223
false ->
224224
import List
225225
flatten([1, [2], 3])

lib/elixir/test/elixir/kernel_test.exs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,8 @@ defmodule KernelTest do
301301
assert (false and true) == false
302302
assert (false and 0) == false
303303
assert (false and raise("oops")) == false
304-
assert ((x = true) and not x) == false
305-
assert_raise BadBooleanError, fn -> 0 and 1 end
304+
assert ((x = Process.get(:unused, true)) and not x) == false
305+
assert_raise BadBooleanError, fn -> Process.get(:unused, 0) and 1 end
306306
end
307307

308308
test "or/2" do
@@ -313,8 +313,8 @@ defmodule KernelTest do
313313
assert (false or false) == false
314314
assert (false or true) == true
315315
assert (false or 0) == 0
316-
assert ((x = false) or not x) == true
317-
assert_raise BadBooleanError, fn -> 0 or 1 end
316+
assert ((x = Process.get(:unused, false)) or not x) == true
317+
assert_raise BadBooleanError, fn -> Process.get(:unused, 0) or 1 end
318318
end
319319

320320
defp delegate_is_struct(arg), do: is_struct(arg)

0 commit comments

Comments
 (0)