@@ -115,9 +115,20 @@ defmodule Module.Types.Expr do
115115
116116  # %{map | ...} 
117117  # TODO: Once we support typed structs, we need to type check them here. 
118-   def  of_expr ( { :%{} ,  _ ,  [ { :| ,  _ ,  [ map ,  args ] } ] } ,  stack ,  context )  do 
118+   def  of_expr ( { :%{} ,  meta ,  [ { :| ,  _ ,  [ map ,  args ] } ] }   =   expr ,  stack ,  context )  do 
119119    { map_type ,  context }  =  of_expr ( map ,  stack ,  context ) 
120-     Of . update_map ( map_type ,  args ,  stack ,  context ,  & of_expr / 3 ) 
120+ 
121+     Of . permutate_map ( args ,  stack ,  context ,  & of_expr / 3 ,  fn  _closed? ,  pairs  -> 
122+       # TODO: If closed? is false, we need to open up the map 
123+       Enum . reduce ( pairs ,  map_type ,  fn  { key ,  type } ,  acc  -> 
124+         case  map_put ( acc ,  key ,  type )  do 
125+           descr  when  is_descr ( descr )  ->  descr 
126+           :badmap  ->  throw ( { :badmap ,  map_type ,  expr ,  context } ) 
127+         end 
128+       end ) 
129+     end ) 
130+   catch 
131+     error  ->  { error_type ( ) ,  error ( __MODULE__ ,  error ,  meta ,  stack ,  context ) } 
121132  end 
122133
123134  # %Struct{map | ...} 
@@ -134,7 +145,7 @@ defmodule Module.Types.Expr do
134145    { map_type ,  context }  =  of_expr ( map ,  stack ,  context ) 
135146
136147    if  disjoint? ( struct_type ,  map_type )  do 
137-       warning  =  { :badupdate  ,   :struct ,  expr ,  struct_type ,  map_type ,  context } 
148+       warning  =  { :badstruct  ,  expr ,  struct_type ,  map_type ,  context } 
138149      { error_type ( ) ,  error ( __MODULE__ ,  warning ,  update_meta ,  stack ,  context ) } 
139150    else 
140151      map_type  =  map_put! ( map_type ,  :__struct__ ,  atom ( [ module ] ) ) 
@@ -500,15 +511,15 @@ defmodule Module.Types.Expr do
500511
501512  ## Warning formatting 
502513
503-   def  format_diagnostic ( { :badupdate  ,   type ,  expr ,  expected_type ,  actual_type ,  context } )  do 
514+   def  format_diagnostic ( { :badstruct  ,  expr ,  expected_type ,  actual_type ,  context } )  do 
504515    traces  =  collect_traces ( expr ,  context ) 
505516
506517    % { 
507518      details:  % { typing_traces:  traces } , 
508519      message: 
509520         IO . iodata_to_binary ( [ 
510521          """ 
511-           incompatible types in #{ type }   update: 
522+           incompatible types in struct  update: 
512523
513524              #{ expr_to_string ( expr )  |>  indent ( 4 ) }  
514525
@@ -525,6 +536,27 @@ defmodule Module.Types.Expr do
525536    } 
526537  end 
527538
539+   def  format_diagnostic ( { :badmap ,  type ,  expr ,  context } )  do 
540+     traces  =  collect_traces ( expr ,  context ) 
541+ 
542+     % { 
543+       details:  % { typing_traces:  traces } , 
544+       message: 
545+          IO . iodata_to_binary ( [ 
546+           """ 
547+           expected a map within map update syntax: 
548+ 
549+               #{ expr_to_string ( expr )  |>  indent ( 4 ) }  
550+ 
551+           but got type: 
552+ 
553+               #{ to_quoted_string ( type )  |>  indent ( 4 ) }  
554+           """ , 
555+           format_traces ( traces ) 
556+         ] ) 
557+     } 
558+   end 
559+ 
528560  def  format_diagnostic ( { :badbinary ,  type ,  expr ,  context } )  do 
529561    traces  =  collect_traces ( expr ,  context ) 
530562
0 commit comments