@@ -107,7 +107,7 @@ function construct_callable(@nospecialize(func::Type))
107107 # for callables such as `(::Returns{Int})(args...)` where using `Returns{Int}`
108108 # would give us code for the constructor, not for the callable object.
109109 throw (ArgumentError (" If a function type is explicitly provided, it must be a singleton whose only instance is the callable object.
110- To alleviate this restriction, the reflection macro may use `use_signature_tuple = true` from `gen_call_with_extracted_types`." ))
110+ To alleviate this restriction, the reflection macro may set `use_signature_tuple = true` if using `gen_call_with_extracted_types`." ))
111111end
112112
113113function separate_kwargs (exs:: Vector{Any} )
@@ -196,9 +196,21 @@ function merge_namedtuple_types(nt::Type{<:NamedTuple}, nts::Type{<:NamedTuple}.
196196end
197197
198198function gen_call (fcn, args, where_params, kws; use_signature_tuple:: Bool )
199- use_signature_tuple && return :($ fcn ($ (esc (typesof_expr (args, where_params))); $ (kws... )))
200199 f, args... = args
201- return :($ fcn ($ (esc (extract_farg (f))), $ (esc (typesof_expr (args, where_params))); $ (kws... )))
200+ args = collect (Any, args)
201+ ! use_signature_tuple && return :($ fcn ($ (esc (extract_farg (f))), $ (esc (typesof_expr (args, where_params))); $ (kws... )))
202+ # We use a signature tuple only if we are sure we won't get an opaque closure as first argument.
203+ # If we do get one, we have to use the 2-argument form.
204+ with_signature_tuple = :($ fcn ($ (esc (typesof_expr (Any[f, args... ], where_params))); $ (kws... )))
205+ isexpr (f, :(:: )) && return with_signature_tuple # we have a type, not a value, so not an OpaqueClosure
206+ return quote
207+ f = $ (esc (f))
208+ if isa (f, Core. OpaqueClosure)
209+ $ fcn (f, $ (esc (typesof_expr (args, where_params))); $ (kws... ))
210+ else
211+ $ with_signature_tuple
212+ end
213+ end
202214end
203215
204216is_code_macro (fcn) = startswith (string (fcn), " code_" )
0 commit comments