11defmodule  Module.Types  do 
22  @ moduledoc  false 
33
4-   alias  Module.Types . { Expr ,  Pattern } 
4+   alias  Module.Types . { Descr ,  Expr ,  Pattern } 
5+ 
6+   @ doc  false 
7+   def  infer ( module ,  file ,  defs ,  env )  do 
8+     context  =  context ( ) 
9+ 
10+     for  { { fun ,  arity } ,  :def ,  _meta ,  clauses }  <-  defs ,  into:  % { }  do 
11+       stack  =  stack ( :infer ,  file ,  module ,  { fun ,  arity } ,  :all ,  env ) 
12+       expected  =  List . duplicate ( Descr . dynamic ( ) ,  arity ) 
13+ 
14+       pair_types  = 
15+         Enum . map ( clauses ,  fn  { meta ,  args ,  guards ,  body }  -> 
16+           try  do 
17+             { args ,  context }  = 
18+               Pattern . of_head ( args ,  guards ,  expected ,  :default ,  meta ,  stack ,  context ) 
19+ 
20+             { return ,  _context }  =  Expr . of_expr ( body ,  stack ,  context ) 
21+             { args ,  return } 
22+           rescue 
23+             e  ->  internal_error! ( e ,  __STACKTRACE__ ,  :def ,  meta ,  module ,  fun ,  args ,  guards ,  body ) 
24+           end 
25+         end ) 
26+ 
27+       # TODO: Reuse context from patterns and guards 
28+       # TODO: Simplify pair types 
29+       # TODO: Handle local calls 
30+       { { fun ,  arity } ,  { :infer ,  pair_types } } 
31+     end 
32+   end 
533
634  @ doc  false 
735  def  warnings ( module ,  file ,  defs ,  no_warn_undefined ,  cache )  do 
836    context  =  context ( ) 
937
10-     Enum . flat_map ( defs ,  fn  { { fun ,  arity }  =  function ,  kind ,  meta ,  clauses }  -> 
11-       stack  = 
12-         stack ( :dynamic ,  with_file_meta ( meta ,  file ) ,  module ,  function ,  no_warn_undefined ,  cache ) 
38+     Enum . flat_map ( defs ,  fn  { { fun ,  arity } ,  kind ,  meta ,  clauses }  -> 
39+       file  =  with_file_meta ( meta ,  file ) 
40+       stack  =  stack ( :dynamic ,  file ,  module ,  { fun ,  arity } ,  no_warn_undefined ,  cache ) 
41+       expected  =  List . duplicate ( Descr . dynamic ( ) ,  arity ) 
1342
1443      Enum . flat_map ( clauses ,  fn  { meta ,  args ,  guards ,  body }  -> 
1544        try  do 
16-           warnings_from_clause ( meta ,  args ,  guards ,  body ,  stack ,  context ) 
45+           { _types ,  context }  = 
46+             Pattern . of_head ( args ,  guards ,  expected ,  :default ,  meta ,  stack ,  context ) 
47+ 
48+           { _type ,  context }  =  Expr . of_expr ( body ,  stack ,  context ) 
49+           context . warnings 
1750        rescue 
1851          e  -> 
19-             def_expr  =  { kind ,  meta ,  [ guards_to_expr ( guards ,  { fun ,  [ ] ,  args } ) ,  [ do:  body ] ] } 
20- 
21-             error  = 
22-               RuntimeError . exception ( """ 
23-               found error while checking types for #{ Exception . format_mfa ( module ,  fun ,  arity ) }  : 
24- 
25-               #{ Exception . format_banner ( :error ,  e ,  __STACKTRACE__ ) }  \ 
26- 
27-               The exception happened while checking this code: 
28- 
29-               #{ Macro . to_string ( def_expr ) }  
30- 
31-               Please report this bug at: https://github.com/elixir-lang/elixir/issues 
32-               """ ) 
33- 
34-             reraise  error ,  __STACKTRACE__ 
52+             internal_error! ( e ,  __STACKTRACE__ ,  kind ,  meta ,  module ,  fun ,  args ,  guards ,  body ) 
3553        end 
3654      end ) 
3755    end ) 
@@ -44,6 +62,25 @@ defmodule Module.Types do
4462    end 
4563  end 
4664
65+   defp  internal_error! ( e ,  stack ,  kind ,  meta ,  module ,  fun ,  args ,  guards ,  body )  do 
66+     def_expr  =  { kind ,  meta ,  [ guards_to_expr ( guards ,  { fun ,  [ ] ,  args } ) ,  [ do:  body ] ] } 
67+ 
68+     exception  = 
69+       RuntimeError . exception ( """ 
70+       found error while checking types for #{ Exception . format_mfa ( module ,  fun ,  length ( args ) ) }  : 
71+ 
72+       #{ Exception . format_banner ( :error ,  e ,  stack ) }  \ 
73+ 
74+       The exception happened while checking this code: 
75+ 
76+       #{ Macro . to_string ( def_expr ) }  
77+ 
78+       Please report this bug at: https://github.com/elixir-lang/elixir/issues 
79+       """ ) 
80+ 
81+     reraise  exception ,  stack 
82+   end 
83+ 
4784  defp  guards_to_expr ( [ ] ,  left )  do 
4885    left 
4986  end 
@@ -52,14 +89,6 @@ defmodule Module.Types do
5289    guards_to_expr ( guards ,  { :when ,  [ ] ,  [ left ,  guard ] } ) 
5390  end 
5491
55-   defp  warnings_from_clause ( meta ,  args ,  guards ,  body ,  stack ,  context )  do 
56-     dynamic  =  Module.Types.Descr . dynamic ( ) 
57-     expected  =  Enum . map ( args ,  fn  _  ->  dynamic  end ) 
58-     { _types ,  context }  =  Pattern . of_head ( args ,  guards ,  expected ,  :default ,  meta ,  stack ,  context ) 
59-     { _type ,  context }  =  Expr . of_expr ( body ,  stack ,  context ) 
60-     context . warnings 
61-   end 
62- 
6392  @ doc  false 
6493  def  stack ( mode ,  file ,  module ,  function ,  no_warn_undefined ,  cache ) 
6594      when  mode  in  [ :static ,  :dynamic ,  :infer ]  do 
@@ -72,9 +101,9 @@ defmodule Module.Types do
72101      module:  module , 
73102      # Current function 
74103      function:  function , 
75-       # List of calls to not warn on as undefined 
104+       # List of calls to not warn on as undefined or :all  
76105      no_warn_undefined:  no_warn_undefined , 
77-       # A list of cached modules received from the parallel compiler  
106+       # A tuple with cache information or a Macro.Env struct indicating no remote traversals  
78107      cache:  cache , 
79108      # The mode controls what happens on function application when 
80109      # there are gradual arguments. Non-gradual arguments always 
0 commit comments