Skip to content

Commit cf3132e

Browse files
committed
Add guards and introduce error_type() for clarity
1 parent 44d94b0 commit cf3132e

File tree

2 files changed

+10
-10
lines changed

2 files changed

+10
-10
lines changed

lib/elixir/lib/module/types/descr.ex

+4-4
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,7 @@ defmodule Module.Types.Descr do
733733
"""
734734
def map_fetch(:term, _key), do: :badmap
735735

736-
def map_fetch(%{} = descr, key) do
736+
def map_fetch(%{} = descr, key) when is_atom(key) do
737737
case :maps.take(:dynamic, descr) do
738738
:error ->
739739
if descr_key?(descr, :map) and map_only?(descr) do
@@ -792,9 +792,9 @@ defmodule Module.Types.Descr do
792792
a map (or dynamic).
793793
"""
794794
def map_put(:term, _key, _type), do: :badmap
795-
def map_put(descr, key, :term), do: map_put_static_value(descr, key, :term)
795+
def map_put(descr, key, :term) when is_atom(key), do: map_put_static_value(descr, key, :term)
796796

797-
def map_put(descr, key, type) do
797+
def map_put(descr, key, type) when is_atom(key) do
798798
case :maps.take(:dynamic, type) do
799799
:error -> map_put_static_value(descr, key, type)
800800
{dynamic, _static} -> dynamic(map_put_static_value(descr, key, dynamic))
@@ -981,7 +981,7 @@ defmodule Module.Types.Descr do
981981
"""
982982
def map_delete(:term, _key), do: :badmap
983983

984-
def map_delete(descr, key) do
984+
def map_delete(descr, key) when is_atom(key) do
985985
case :maps.take(:dynamic, descr) do
986986
:error ->
987987
# Note: the empty typ is not a valid input

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

+6-6
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ defmodule Module.Types.Expr do
156156
{:ok, map_type, context} <- of_expr(map, stack, context) do
157157
if disjoint?(struct_type, map_type) do
158158
warning = {:badupdate, :struct, expr, struct_type, map_type, context}
159-
{:ok, dynamic(), warn(__MODULE__, warning, update_meta, stack, context)}
159+
{:ok, error_type(), warn(__MODULE__, warning, update_meta, stack, context)}
160160
else
161161
# TODO: Merge args_type into map_type with dynamic/static key requirement
162162
Of.struct(module, args_types, :merge_defaults, struct_meta, stack, context)
@@ -384,12 +384,10 @@ defmodule Module.Types.Expr do
384384
if Code.ensure_loaded?(exception) and function_exported?(exception, :__struct__, 0) do
385385
Of.struct(exception, args, :merge_defaults, meta, stack, context)
386386
else
387-
# Whenever there is a failure (such as undefined function),
388-
# we return dynamic to avoid cascading errors. In this case,
389-
# we can return something a bit more precise than dynamic,
390-
# but we still want an open map to avoid cascading.
387+
# If the exception cannot be found or is invalid,
388+
# we call Of.remote/5 to emit a warning.
391389
context = Of.remote(exception, :__struct__, 0, meta, stack, context)
392-
{:ok, dynamic(open_map([__struct__: atom([exception])] ++ args)), context}
390+
{:ok, error_type(), context}
393391
end
394392
end) do
395393
context =
@@ -480,6 +478,8 @@ defmodule Module.Types.Expr do
480478

481479
## General helpers
482480

481+
defp error_type(), do: dynamic()
482+
483483
defp apply_many([], _function, _args_types, _expr, _stack, context) do
484484
{:ok, dynamic(), context}
485485
end

0 commit comments

Comments
 (0)