Skip to content

Commit 19c628a

Browse files
committed
Mark invididual guards of ||, &&, if, and unless as generated
1 parent 5f616e2 commit 19c628a

6 files changed

Lines changed: 51 additions & 29 deletions

File tree

lib/elixir/lib/kernel.ex

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1999,6 +1999,12 @@ defmodule Kernel do
19991999
{:case, extra ++ meta, args}
20002000
end
20012001

2002+
defp x_is_false_or_nil do
2003+
quote generated: true do
2004+
:erlang.orelse(:erlang."=:="(x, false), :erlang."=:="(x, nil))
2005+
end
2006+
end
2007+
20022008
@doc """
20032009
Strictly boolean "or" operator.
20042010
@@ -2101,7 +2107,7 @@ defmodule Kernel do
21012107
[optimize_boolean: true, type_check: :expr],
21022108
quote do
21032109
case unquote(value) do
2104-
x when :"Elixir.Kernel".in(x, [false, nil]) -> false
2110+
x when unquote(x_is_false_or_nil()) -> false
21052111
_ -> true
21062112
end
21072113
end
@@ -2115,7 +2121,7 @@ defmodule Kernel do
21152121
[optimize_boolean: true, type_check: :expr],
21162122
quote do
21172123
case unquote(value) do
2118-
x when :"Elixir.Kernel".in(x, [false, nil]) -> true
2124+
x when unquote(x_is_false_or_nil()) -> true
21192125
_ -> false
21202126
end
21212127
end
@@ -4046,7 +4052,7 @@ defmodule Kernel do
40464052
[optimize_boolean: true, type_check: :expr],
40474053
quote do
40484054
case unquote(condition) do
4049-
x when :"Elixir.Kernel".in(x, [false, nil]) -> unquote(else_clause)
4055+
x when unquote(x_is_false_or_nil()) -> unquote(else_clause)
40504056
_ -> unquote(do_clause)
40514057
end
40524058
end
@@ -4367,7 +4373,7 @@ defmodule Kernel do
43674373
[type_check: :expr],
43684374
quote do
43694375
case unquote(left) do
4370-
x when :"Elixir.Kernel".in(x, [false, nil]) ->
4376+
x when unquote(x_is_false_or_nil()) ->
43714377
x
43724378

43734379
_ ->
@@ -4410,7 +4416,7 @@ defmodule Kernel do
44104416
[type_check: :expr],
44114417
quote do
44124418
case unquote(left) do
4413-
x when :"Elixir.Kernel".in(x, [false, nil]) ->
4419+
x when unquote(x_is_false_or_nil()) ->
44144420
unquote(right)
44154421

44164422
x ->

lib/elixir/lib/kernel/special_forms.ex

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1975,13 +1975,13 @@ defmodule Kernel.SpecialForms do
19751975
While it is not possible to match against multiple patterns in a single
19761976
clause, it's possible to match against multiple values by using guards:
19771977
1978-
iex> case :two do
1979-
...> value when value in [:one, :two] ->
1978+
iex> case 2 do
1979+
...> value when value in [1, 2] ->
19801980
...> "#{value} has been matched"
1981-
...> :three ->
1982-
...> "three has been matched"
1981+
...> 3 ->
1982+
...> "3 has been matched"
19831983
...> end
1984-
"two has been matched"
1984+
"2 has been matched"
19851985
"""
19861986
defmacro case(condition, clauses), do: error!([condition, clauses])
19871987

lib/elixir/lib/module/types/pattern.ex

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -812,15 +812,6 @@ defmodule Module.Types.Pattern do
812812
Of.map_fetch(map_fetch, type, key, stack, context)
813813
end
814814

815-
# Comparison operators
816-
def of_guard({{:., _, [:erlang, function]}, _, args}, _expected, expr, stack, context)
817-
when function in [:==, :"/=", :"=:=", :"=/="] do
818-
{_args_type, context} =
819-
Enum.map_reduce(args, context, &of_guard(&1, term(), expr, stack, &2))
820-
821-
{boolean(), context}
822-
end
823-
824815
# Remote
825816
def of_guard({{:., _, [:erlang, fun]}, meta, args} = call, expected, _expr, stack, context)
826817
when is_atom(fun) do

lib/elixir/src/elixir_expand.erl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
-export([expand/3, expand_args/3, expand_arg/3, format_error/1]).
77
-import(elixir_errors, [file_error/4, module_error/4, function_error/4]).
88
-include("elixir.hrl").
9+
-define(kernel, 'Elixir.Kernel').
910

1011
%% =
1112

@@ -794,7 +795,10 @@ expand_case(Meta, Expr, Opts, S, E) ->
794795

795796
rewrite_case_clauses([{do, [
796797
{'->', FalseMeta, [
797-
[{'when', _, [Var, {{'.', _, ['Elixir.Kernel', 'in']}, _, [Var, [false, nil]]}]}],
798+
[{'when', _, [{Var, _, ?kernel}, {{'.', _, ['erlang', 'orelse']}, _, [
799+
{{'.', _, ['erlang', '=:=']}, _, [{Var, _, ?kernel}, false]},
800+
{{'.', _, ['erlang', '=:=']}, _, [{Var, _, ?kernel}, nil]}
801+
]}]}],
798802
FalseExpr
799803
]},
800804
{'->', TrueMeta, [

lib/elixir/test/elixir/macro_test.exs

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ defmodule MacroTest do
285285
end
286286

287287
defp expand_once_and_clean(quoted, env) do
288-
cleaner = &Keyword.drop(&1, [:counter, :type_check])
288+
cleaner = &Keyword.drop(&1, [:counter, :type_check, :generated])
289289

290290
quoted
291291
|> Macro.expand_once(env)
@@ -298,8 +298,15 @@ defmodule MacroTest do
298298
quoted =
299299
quote context: Kernel do
300300
case 1 do
301-
unquote(temp_var) when :"Elixir.Kernel".in(unquote(temp_var), [false, nil]) -> false
302-
unquote(temp_var) -> unquote(temp_var)
301+
unquote(temp_var)
302+
when :erlang.orelse(
303+
:erlang."=:="(unquote(temp_var), false),
304+
:erlang."=:="(unquote(temp_var), nil)
305+
) ->
306+
false
307+
308+
unquote(temp_var) ->
309+
unquote(temp_var)
303310
end
304311
end
305312

@@ -312,8 +319,15 @@ defmodule MacroTest do
312319
quoted =
313320
quote context: Kernel do
314321
case 1 do
315-
unquote(temp_var) when :"Elixir.Kernel".in(unquote(temp_var), [false, nil]) -> false
316-
unquote(temp_var) -> unquote(temp_var)
322+
unquote(temp_var)
323+
when :erlang.orelse(
324+
:erlang."=:="(unquote(temp_var), false),
325+
:erlang."=:="(unquote(temp_var), nil)
326+
) ->
327+
false
328+
329+
unquote(temp_var) ->
330+
unquote(temp_var)
317331
end
318332
end
319333

@@ -382,7 +396,7 @@ defmodule MacroTest do
382396
end
383397

384398
defp expand_and_clean(quoted, env) do
385-
cleaner = &Keyword.drop(&1, [:counter, :type_check])
399+
cleaner = &Keyword.drop(&1, [:counter, :type_check, :generated])
386400

387401
quoted
388402
|> Macro.expand(env)
@@ -395,8 +409,15 @@ defmodule MacroTest do
395409
quoted =
396410
quote context: Kernel do
397411
case 1 do
398-
unquote(temp_var) when :"Elixir.Kernel".in(unquote(temp_var), [false, nil]) -> false
399-
unquote(temp_var) -> unquote(temp_var)
412+
unquote(temp_var)
413+
when :erlang.orelse(
414+
:erlang."=:="(unquote(temp_var), false),
415+
:erlang."=:="(unquote(temp_var), nil)
416+
) ->
417+
false
418+
419+
unquote(temp_var) ->
420+
unquote(temp_var)
400421
end
401422
end
402423

lib/elixir/test/erlang/control_test.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ optimized_oror_test() ->
4343
{'case', _, _,
4444
[{clause, 1,
4545
[{var, 1, _}],
46-
[[{op, 1, 'orelse', _, _}]],
46+
[[{op, _, 'orelse', _, _}]],
4747
[{atom, 1, done}]},
4848
{clause, 1, [{var, 1, Var}], [], [{var, 1, Var}]}]
4949
} = to_erl("is_list([]) || :done").

0 commit comments

Comments
 (0)