@@ -333,6 +333,14 @@ defmodule Module.Types.Of do
333333 { :binary , :copy , [ { [ binary ( ) , integer ( ) ] , binary ( ) } ] } ,
334334
335335 # :erlang
336+ { :erlang , :"/=" , [ { [ term ( ) , term ( ) ] , boolean ( ) } ] } ,
337+ { :erlang , :"=/=" , [ { [ term ( ) , term ( ) ] , boolean ( ) } ] } ,
338+ { :erlang , :< , [ { [ term ( ) , term ( ) ] , boolean ( ) } ] } ,
339+ { :erlang , :"=<" , [ { [ term ( ) , term ( ) ] , boolean ( ) } ] } ,
340+ { :erlang , :== , [ { [ term ( ) , term ( ) ] , boolean ( ) } ] } ,
341+ { :erlang , :"=:=" , [ { [ term ( ) , term ( ) ] , boolean ( ) } ] } ,
342+ { :erlang , :> , [ { [ term ( ) , term ( ) ] , boolean ( ) } ] } ,
343+ { :erlang , :>= , [ { [ term ( ) , term ( ) ] , boolean ( ) } ] } ,
336344 { :erlang , :atom_to_binary , [ { [ atom ( ) ] , binary ( ) } ] } ,
337345 { :erlang , :atom_to_list , [ { [ atom ( ) ] , list ( integer ( ) ) } ] } ,
338346 { :erlang , :band , [ { [ integer ( ) , integer ( ) ] , integer ( ) } ] } ,
@@ -492,38 +500,55 @@ defmodule Module.Types.Of do
492500
493501 def apply ( :erlang , name , [ left , right ] , expr , stack , context )
494502 when name in [ :>= , :"=<" , :> , :< , :min , :max ] do
495- result = if name in [ :min , :max ] , do: union ( left , right ) , else: boolean ( )
503+ context =
504+ cond do
505+ match? ( { false , _ } , map_fetch ( left , :__struct__ ) ) or
506+ match? ( { false , _ } , map_fetch ( right , :__struct__ ) ) ->
507+ warning = { :struct_comparison , expr , context }
508+ warn ( __MODULE__ , warning , elem ( expr , 1 ) , stack , context )
509+
510+ number_type? ( left ) and number_type? ( right ) ->
511+ context
496512
497- cond do
498- match? ( { false , _ } , map_fetch ( left , :__struct__ ) ) or
499- match? ( { false , _ } , map_fetch ( right , :__struct__ ) ) ->
500- warning = { :struct_comparison , expr , context }
501- { result , warn ( __MODULE__ , warning , elem ( expr , 1 ) , stack , context ) }
513+ disjoint? ( left , right ) ->
514+ warning = { :mismatched_comparison , expr , context }
515+ warn ( __MODULE__ , warning , elem ( expr , 1 ) , stack , context )
516+
517+ true ->
518+ context
519+ end
502520
503- number_type? ( left ) and number_type? ( right ) ->
504- { result , context }
521+ cond do
522+ name in [ :min , :max ] ->
523+ { union ( left , right ) , context }
505524
506- disjoint? ( left , right ) ->
507- warning = { :mismatched_comparison , expr , context }
508- { result , warn ( __MODULE__ , warning , elem ( expr , 1 ) , stack , context ) }
525+ gradual? ( left ) or gradual? ( right ) ->
526+ { dynamic ( boolean ( ) ) , context }
509527
510528 true ->
511- { result , context }
529+ { boolean ( ) , context }
512530 end
513531 end
514532
515533 def apply ( :erlang , name , [ left , right ] , expr , stack , context )
516534 when name in [ :== , :"/=" , :"=:=" , :"=/=" ] do
517- cond do
518- name in [ :== , :"/=" ] and number_type? ( left ) and number_type? ( right ) ->
519- { boolean ( ) , context }
535+ context =
536+ cond do
537+ name in [ :== , :"/=" ] and number_type? ( left ) and number_type? ( right ) ->
538+ context
520539
521- disjoint? ( left , right ) ->
522- warning = { :mismatched_comparison , expr , context }
523- { boolean ( ) , warn ( __MODULE__ , warning , elem ( expr , 1 ) , stack , context ) }
540+ disjoint? ( left , right ) ->
541+ warning = { :mismatched_comparison , expr , context }
542+ warn ( __MODULE__ , warning , elem ( expr , 1 ) , stack , context )
524543
525- true ->
526- { boolean ( ) , context }
544+ true ->
545+ context
546+ end
547+
548+ if gradual? ( left ) or gradual? ( right ) do
549+ { dynamic ( boolean ( ) ) , context }
550+ else
551+ { boolean ( ) , context }
527552 end
528553 end
529554
0 commit comments