Skip to content

Commit cb2e036

Browse files
authored
Perform return type inference and application across local calls (#13984)
1 parent 6689eb9 commit cb2e036

39 files changed

+1747
-1729
lines changed

CHANGELOG.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ TODO.
66

77
* Type inference of patterns (typing inference of guards will be part of an upcoming release)
88

9-
* [Support for tuples and lists as composite types](https://elixir-lang.org/blog/2024/08/28/typing-lists-and-tuples/) as well as type checking of their basic operations
10-
11-
* Type checking of all language constructs, except `for`, `with`, and closures
9+
* Type checking of all language constructs, including local and remote calls, except `for`, `with`, and closures
1210

1311
* Type checking of all `Kernel` and conversion functions inlined by the compiler
1412

15-
* Detection of clauses and patterns that never match
13+
* [Support for tuples and lists as composite types](https://elixir-lang.org/blog/2024/08/28/typing-lists-and-tuples/) as well as type checking of their basic operations
14+
15+
* Detection of clauses and patterns that will never match from `case`, `cond`, and `=`
16+
17+
* Detection of unused clauses from private functions
1618

1719
## ExUnit improvements
1820

lib/elixir/lib/calendar/time.ex

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -797,15 +797,8 @@ defmodule Time do
797797
@doc since: "1.5.0"
798798
@spec convert!(Calendar.time(), Calendar.calendar()) :: t
799799
def convert!(time, calendar) do
800-
case convert(time, calendar) do
801-
{:ok, value} ->
802-
value
803-
804-
{:error, reason} ->
805-
raise ArgumentError,
806-
"cannot convert #{inspect(time)} to target calendar #{inspect(calendar)}, " <>
807-
"reason: #{inspect(reason)}"
808-
end
800+
{:ok, value} = convert(time, calendar)
801+
value
809802
end
810803

811804
@doc """

lib/elixir/lib/code.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1649,7 +1649,7 @@ defmodule Code do
16491649
16501650
* `:infer_signatures` (since v1.18.0) - when `false`, it disables module-local
16511651
signature inference used when type checking remote calls to the compiled
1652-
module. Type checking will be executed regardless of this value of this option.
1652+
module. Type checking will be executed regardless of the value of this option.
16531653
Defaults to `true`.
16541654
16551655
`mix test` automatically disables this option via the `:test_elixirc_options`

lib/elixir/lib/kernel.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ defmodule Kernel do
302302
@compile {:inline, bootstrapped?: 1}
303303
case :code.ensure_loaded(Kernel) do
304304
{:module, _} ->
305-
defp bootstrapped?(_), do: true
305+
defp bootstrapped?(module), do: is_atom(module)
306306

307307
{:error, _} ->
308308
defp bootstrapped?(module), do: :code.ensure_loaded(module) == {:module, module}
@@ -3646,7 +3646,7 @@ defmodule Kernel do
36463646
:ok
36473647

36483648
true ->
3649-
pos = :elixir_locals.cache_env(__CALLER__)
3649+
pos = :elixir_module.cache_env(__CALLER__)
36503650
%{line: line, file: file, module: module} = __CALLER__
36513651

36523652
quote do
@@ -5323,7 +5323,7 @@ defmodule Kernel do
53235323
key
53245324
end
53255325

5326-
pos = :elixir_locals.cache_env(env)
5326+
pos = :elixir_module.cache_env(env)
53275327

53285328
quote do
53295329
:elixir_def.store_definition(unquote(kind), unquote(store), unquote(pos))

lib/elixir/lib/kernel/cli.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ defmodule Kernel.CLI do
196196
end
197197

198198
@elixir_internals [:elixir, :elixir_aliases, :elixir_expand, :elixir_compiler, :elixir_module] ++
199-
[:elixir_clauses, :elixir_lexical, :elixir_def, :elixir_map, :elixir_locals] ++
199+
[:elixir_clauses, :elixir_lexical, :elixir_def, :elixir_map] ++
200200
[:elixir_erl, :elixir_erl_clauses, :elixir_erl_compiler, :elixir_erl_pass] ++
201201
[Kernel.ErrorHandler, Module.ParallelChecker]
202202

lib/elixir/lib/kernel/typespec.ex

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ defmodule Kernel.Typespec do
138138
case type_to_signature(expr) do
139139
{name, arity} = signature when signature in @reserved_signatures ->
140140
compile_error(
141-
:elixir_locals.get_cached_env(pos),
141+
:elixir_module.get_cached_env(pos),
142142
"type #{name}/#{arity} is a reserved type and it cannot be defined"
143143
)
144144

@@ -247,7 +247,7 @@ defmodule Kernel.Typespec do
247247

248248
defp collect_defined_type_pairs(type_typespecs) do
249249
fun = fn {_kind, expr, pos}, type_pairs ->
250-
%{file: file, line: line} = env = :elixir_locals.get_cached_env(pos)
250+
%{file: file, line: line} = env = :elixir_module.get_cached_env(pos)
251251

252252
case type_to_signature(expr) do
253253
{name, arity} = type_pair ->
@@ -292,7 +292,7 @@ defmodule Kernel.Typespec do
292292

293293
defp translate_type({kind, {:"::", _, [{name, meta, args}, definition]}, pos}, state)
294294
when is_list(meta) do
295-
caller = :elixir_locals.get_cached_env(pos)
295+
caller = :elixir_module.get_cached_env(pos)
296296
state = clean_local_state(state)
297297

298298
args =
@@ -349,12 +349,12 @@ defmodule Kernel.Typespec do
349349
defp underspecified?(_kind, _arity, _spec), do: false
350350

351351
defp translate_spec({kind, {:when, _meta, [spec, guard]}, pos}, state) do
352-
caller = :elixir_locals.get_cached_env(pos)
352+
caller = :elixir_module.get_cached_env(pos)
353353
translate_spec(kind, spec, guard, caller, state)
354354
end
355355

356356
defp translate_spec({kind, spec, pos}, state) do
357-
caller = :elixir_locals.get_cached_env(pos)
357+
caller = :elixir_module.get_cached_env(pos)
358358
translate_spec(kind, spec, [], caller, state)
359359
end
360360

lib/elixir/lib/module.ex

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,15 +1415,7 @@ defmodule Module do
14151415
def delete_definition(module, {name, arity})
14161416
when is_atom(module) and is_atom(name) and is_integer(arity) do
14171417
assert_not_readonly!(__ENV__.function, module)
1418-
1419-
case :elixir_def.take_definition(module, {name, arity}) do
1420-
false ->
1421-
false
1422-
1423-
_ ->
1424-
:elixir_locals.yank({name, arity}, module)
1425-
true
1426-
end
1418+
:elixir_def.take_definition(module, {name, arity}) != false
14271419
end
14281420

14291421
@doc """
@@ -1452,8 +1444,7 @@ defmodule Module do
14521444
"overridable because it was not defined"
14531445

14541446
clause ->
1455-
neighbours = :elixir_locals.yank(tuple, module)
1456-
:elixir_overridable.record_overridable(module, tuple, clause, neighbours)
1447+
:elixir_overridable.record_overridable(module, tuple, clause)
14571448
end
14581449

14591450
other ->

0 commit comments

Comments
 (0)