@@ -394,7 +394,7 @@ defmodule Protocol do
394394 end
395395
396396 defp assert_impl! ( protocol , base , extra ) do
397- impl = Module . concat ( protocol , base )
397+ impl = __concat__ ( protocol , base )
398398
399399 try do
400400 Code . ensure_compiled! ( impl )
@@ -684,14 +684,14 @@ defmodule Protocol do
684684 types
685685 |> List . delete ( Any )
686686 |> Enum . map ( fn impl ->
687- { [ Module.Types.Of . impl ( impl ) ] , Descr . atom ( [ Module . concat ( protocol , impl ) ] ) }
687+ { [ Module.Types.Of . impl ( impl ) ] , Descr . atom ( [ __concat__ ( protocol , impl ) ] ) }
688688 end )
689689
690690 { domain , impl_for , impl_for! } =
691691 case clauses do
692692 [ ] ->
693693 if Any in types do
694- clauses = [ { [ Descr . term ( ) ] , Descr . atom ( [ Module . concat ( protocol , Any ) ] ) } ]
694+ clauses = [ { [ Descr . term ( ) ] , Descr . atom ( [ __concat__ ( protocol , Any ) ] ) } ]
695695 { Descr . term ( ) , clauses , clauses }
696696 else
697697 { Descr . none ( ) , [ { [ Descr . term ( ) ] , Descr . atom ( [ nil ] ) } ] ,
@@ -707,7 +707,9 @@ defmodule Protocol do
707707 not_domain = Descr . negation ( domain )
708708
709709 if Any in types do
710- clauses = clauses ++ [ { [ not_domain ] , Descr . atom ( [ Module . concat ( protocol , Any ) ] ) } ]
710+ clauses =
711+ clauses ++ [ { [ not_domain ] , Descr . atom ( [ __concat__ ( protocol , Any ) ] ) } ]
712+
711713 { Descr . term ( ) , clauses , clauses }
712714 else
713715 { domain , clauses ++ [ { [ not_domain ] , Descr . atom ( [ nil ] ) } ] , clauses }
@@ -746,7 +748,7 @@ defmodule Protocol do
746748 end
747749
748750 defp change_impl_for ( { _name , _kind , meta , _clauses } , protocol , types ) do
749- fallback = if Any in types , do: load_impl ( protocol , Any )
751+ fallback = if Any in types , do: __concat__ ( protocol , Any )
750752 line = meta [ :line ]
751753
752754 clauses =
@@ -762,7 +764,7 @@ defmodule Protocol do
762764 end
763765
764766 defp change_struct_impl_for ( { _name , _kind , meta , _clauses } , protocol , types , structs ) do
765- fallback = if Any in types , do: load_impl ( protocol , Any )
767+ fallback = if Any in types , do: __concat__ ( protocol , Any )
766768 clauses = for struct <- structs , do: each_struct_clause_for ( struct , protocol , meta )
767769 clauses = clauses ++ [ fallback_clause_for ( fallback , protocol , meta ) ]
768770
@@ -772,7 +774,7 @@ defmodule Protocol do
772774 defp built_in_clause_for ( mod , guard , protocol , meta , line ) do
773775 x = { :x , [ line: line , version: - 1 ] , __MODULE__ }
774776 guard = quote ( line: line , do: :erlang . unquote ( guard ) ( unquote ( x ) ) )
775- body = load_impl ( protocol , mod )
777+ body = __concat__ ( protocol , mod )
776778 { meta , [ x ] , [ guard ] , body }
777779 end
778780
@@ -785,17 +787,13 @@ defmodule Protocol do
785787 end
786788
787789 defp each_struct_clause_for ( struct , protocol , meta ) do
788- { meta , [ struct ] , [ ] , load_impl ( protocol , struct ) }
790+ { meta , [ struct ] , [ ] , __concat__ ( protocol , struct ) }
789791 end
790792
791793 defp fallback_clause_for ( value , _protocol , meta ) do
792794 { meta , [ quote ( do: _ ) ] , [ ] , value }
793795 end
794796
795- defp load_impl ( protocol , for ) do
796- Module . concat ( protocol , for )
797- end
798-
799797 # Finally compile the module and emit its bytecode.
800798 defp compile ( definitions , signatures , { module_map , specs , docs_chunk } ) do
801799 # Protocols in precompiled archives may not have signatures, so we default to an empty map.
@@ -957,7 +955,7 @@ defmodule Protocol do
957955 # Define the implementation for built-ins
958956 :lists . foreach (
959957 fn { mod , guard } ->
960- target = Module . concat ( __MODULE__ , mod )
958+ target = Protocol . __concat__ ( __MODULE__ , mod )
961959
962960 Kernel . def impl_for ( data ) when :erlang . unquote ( guard ) ( data ) do
963961 case Code . ensure_compiled ( unquote ( target ) ) do
@@ -1001,7 +999,7 @@ defmodule Protocol do
1001999
10021000 # Internal handler for Structs
10031001 Kernel . defp struct_impl_for ( struct ) do
1004- case Code . ensure_compiled ( Module . concat ( __MODULE__ , struct ) ) do
1002+ case Code . ensure_compiled ( Protocol . __concat__ ( __MODULE__ , struct ) ) do
10051003 { :module , module } -> module
10061004 { :error , _ } -> unquote ( any_impl_for )
10071005 end
@@ -1074,7 +1072,7 @@ defmodule Protocol do
10741072 quote do
10751073 protocol = unquote ( protocol )
10761074 for = unquote ( for )
1077- name = Module . concat ( protocol , for )
1075+ name = Protocol . __concat__ ( protocol , for )
10781076
10791077 Protocol . assert_protocol! ( protocol )
10801078 Protocol . __impl__! ( protocol , for , __ENV__ )
@@ -1120,7 +1118,7 @@ defmodule Protocol do
11201118 else
11211119 # TODO: Deprecate this on Elixir v1.22+
11221120 assert_impl! ( protocol , Any , extra )
1123- { Module . concat ( protocol , Any ) , [ for , Macro . struct! ( for , env ) , opts ] }
1121+ { __concat__ ( protocol , Any ) , [ for , Macro . struct! ( for , env ) , opts ] }
11241122 end
11251123
11261124 # Clean up variables from eval context
@@ -1132,7 +1130,7 @@ defmodule Protocol do
11321130 else
11331131 __impl__! ( protocol , for , env )
11341132 assert_impl! ( protocol , Any , extra )
1135- impl = Module . concat ( protocol , Any )
1133+ impl = __concat__ ( protocol , Any )
11361134
11371135 funs =
11381136 for { fun , arity } <- protocol . __protocol__ ( :functions ) do
@@ -1157,7 +1155,7 @@ defmodule Protocol do
11571155 def __impl__ ( :for ) , do: unquote ( for )
11581156 end
11591157
1160- Module . create ( Module . concat ( protocol , for ) , [ quoted | funs ] , Macro.Env . location ( env ) )
1158+ Module . create ( __concat__ ( protocol , for ) , [ quoted | funs ] , Macro.Env . location ( env ) )
11611159 end
11621160 end )
11631161 end
@@ -1204,4 +1202,17 @@ defmodule Protocol do
12041202 { Reference , :is_reference }
12051203 ]
12061204 end
1205+
1206+ @ doc false
1207+ def __concat__ ( left , right ) do
1208+ String . to_atom (
1209+ ensure_prefix ( Atom . to_string ( left ) ) <> "." <> remove_prefix ( Atom . to_string ( right ) )
1210+ )
1211+ end
1212+
1213+ defp ensure_prefix ( "Elixir." <> _ = left ) , do: left
1214+ defp ensure_prefix ( left ) , do: "Elixir." <> left
1215+
1216+ defp remove_prefix ( "Elixir." <> right ) , do: right
1217+ defp remove_prefix ( right ) , do: right
12071218end
0 commit comments