@@ -160,15 +160,7 @@ do_escape(BitString, _) when is_bitstring(BitString) ->
160160 end ;
161161
162162do_escape (Map , Q ) when is_map (Map ) ->
163- TT =
164- [if
165- ? OTP_RELEASE >= 28 , is_reference (V ) ->
166- argument_error (<<('Elixir.Kernel' :inspect (Map , []))/binary , " contains a reference (" ,
167- ('Elixir.Kernel' :inspect (V , []))/binary , " ) and therefore it cannot be escaped " ,
168- " (it must be defined within a function instead). " , (bad_escape_hint ())/binary >>);
169- true ->
170- {do_quote (K , Q ), do_quote (V , Q )}
171- end || {K , V } <- lists :sort (maps :to_list (Map ))],
163+ TT = [escape_map_key_value (K , V , Map , Q ) || {K , V } <- lists :sort (maps :to_list (Map ))],
172164 {'%{}' , [], TT };
173165
174166do_escape ([], _ ) ->
@@ -202,6 +194,29 @@ do_escape(Fun, _) when is_function(Fun) ->
202194do_escape (Other , _ ) ->
203195 bad_escape (Other ).
204196
197+ escape_map_key_value (K , V , Map , Q ) ->
198+ MaybeRef = if
199+ ? OTP_RELEASE < 28 -> nil ;
200+ is_reference (V ) -> V ;
201+ is_tuple (V ) -> find_tuple_ref (V , 1 );
202+ true -> nil
203+ end ,
204+ if
205+ is_reference (MaybeRef ) ->
206+ argument_error (<<('Elixir.Kernel' :inspect (Map , []))/binary , " contains a reference (" ,
207+ ('Elixir.Kernel' :inspect (MaybeRef , []))/binary , " ) and therefore it cannot be escaped " ,
208+ " (it must be defined within a function instead). " , (bad_escape_hint ())/binary >>);
209+ true ->
210+ {do_quote (K , Q ), do_quote (V , Q )}
211+ end .
212+
213+ find_tuple_ref (Tuple , Index ) when Index > tuple_size (Tuple ) -> nil ;
214+ find_tuple_ref (Tuple , Index ) ->
215+ case element (Index , Tuple ) of
216+ Ref when is_reference (Ref ) -> Ref ;
217+ _ -> find_tuple_ref (Tuple , Index + 1 )
218+ end .
219+
205220bad_escape (Arg ) ->
206221 argument_error (<<" cannot escape " , ('Elixir.Kernel' :inspect (Arg , []))/binary , " . " ,
207222 (bad_escape_hint ())/binary >>).
0 commit comments