diff --git a/base/experimental.jl b/base/experimental.jl index fd25ff1c0c0dc..232d2efd11d21 100644 --- a/base/experimental.jl +++ b/base/experimental.jl @@ -268,15 +268,21 @@ method tables (e.g., using [`Core.Compiler.OverlayMethodTable`](@ref)). """ macro overlay(mt, def) def = macroexpand(__module__, def) # to expand @inline, @generated, etc - if !isexpr(def, [:function, :(=)]) || !isexpr(def.args[1], :call) + if !isexpr(def, [:function, :(=)]) + error("@overlay requires a function Expr") + end + if isexpr(def.args[1], :call) + def.args[1].args[1] = Expr(:overlay, mt, def.args[1].args[1]) + elseif isexpr(def.args[1], :where) + def.args[1].args[1].args[1] = Expr(:overlay, mt, def.args[1].args[1].args[1]) + else error("@overlay requires a function Expr") end - def.args[1].args[1] = Expr(:overlay, mt, def.args[1].args[1]) esc(def) end let new_mt(name::Symbol, mod::Module) = begin - ccall(:jl_check_top_level_effect, Cvoid, (Any, Cstring), mod, name) + ccall(:jl_check_top_level_effect, Cvoid, (Any, Cstring), mod, "@MethodTable") ccall(:jl_new_method_table, Any, (Any, Any), name, mod) end @eval macro MethodTable(name::Symbol) diff --git a/src/toplevel.c b/src/toplevel.c index 01ea633d95488..c11dea57c8489 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -922,7 +922,7 @@ static void jl_check_open_for(jl_module_t *m, const char* funcname) } } -JL_DLLEXPORT void jl_check_top_level_effect(jl_value_t *m, char *fname) +JL_DLLEXPORT void jl_check_top_level_effect(jl_module_t *m, char *fname) { if (jl_current_task->ptls->in_pure_callback) jl_errorf("%s cannot be used in a generated function", fname); diff --git a/test/compiler/contextual.jl b/test/compiler/contextual.jl index dbd0c788e363a..5d97f4f6542b7 100644 --- a/test/compiler/contextual.jl +++ b/test/compiler/contextual.jl @@ -153,6 +153,9 @@ end # short function def @overlay mt cos(x::Float64) = 2 +# parametric function def +@overlay mt tan(x::T) where {T} = 3 + end methods = Base._methods_by_ftype(Tuple{typeof(sin), Float64}, nothing, 1, typemax(UInt))