Skip to content

Commit

Permalink
fix overlapping definitions of Base.active_module and `REPL.active_…
Browse files Browse the repository at this point in the history
…module` (JuliaLang#55316)

also avoid calling `active_module` from low-level printing functions
fix JuliaLang#54888
  • Loading branch information
JeffBezanson authored and lazarusA committed Aug 17, 2024
1 parent 2e3f8b1 commit d38a442
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 40 deletions.
2 changes: 1 addition & 1 deletion base/Enums.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Base.print(io::IO, x::Enum) = print(io, _symbol(x))
function Base.show(io::IO, x::Enum)
sym = _symbol(x)
if !(get(io, :compact, false)::Bool)
from = get(io, :module, Base.active_module())
from = get(io, :module, Main)
def = parentmodule(typeof(x))
if from === nothing || !Base.isvisible(sym, def, from)
show(io, def)
Expand Down
44 changes: 18 additions & 26 deletions base/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -514,24 +514,16 @@ function _show_default(io::IO, @nospecialize(x))
end

function active_module()
REPL = REPL_MODULE_REF[]
REPL === Base && return Main
return invokelatest(REPL.active_module)::Module
if ccall(:jl_is_in_pure_context, Bool, ())
error("active_module() should not be called from a pure context")
end
if !@isdefined(active_repl) || active_repl === nothing
return Main
end
return invokelatest(active_module, active_repl)::Module
end

# Check if a particular symbol is exported from a standard library module
function is_exported_from_stdlib(name::Symbol, mod::Module)
!isdefined(mod, name) && return false
orig = getfield(mod, name)
while !(mod === Base || mod === Core)
activemod = active_module()
parent = parentmodule(mod)
if mod === activemod || mod === parent || parent === activemod
return false
end
mod = parent
end
return isexported(mod, name) && isdefined(mod, name) && !isdeprecated(mod, name) && getfield(mod, name) === orig
module UsesCoreAndBaseOnly
end

function show_function(io::IO, f::Function, compact::Bool, fallback::Function)
Expand All @@ -544,13 +536,13 @@ function show_function(io::IO, f::Function, compact::Bool, fallback::Function)
print(io, mt.name)
elseif isdefined(mt, :module) && isdefined(mt.module, mt.name) &&
getfield(mt.module, mt.name) === f
mod = active_module()
if is_exported_from_stdlib(mt.name, mt.module) || mt.module === mod
show_sym(io, mt.name)
else
# this used to call the removed internal function `is_exported_from_stdlib`, which effectively
# just checked for exports from Core and Base.
mod = get(io, :module, UsesCoreAndBaseOnly)
if !(isvisible(mt.name, mt.module, mod) || mt.module === mod)
print(io, mt.module, ".")
show_sym(io, mt.name)
end
show_sym(io, mt.name)
else
fallback(io, f)
end
Expand Down Expand Up @@ -737,9 +729,9 @@ end
function show_typealias(io::IO, name::GlobalRef, x::Type, env::SimpleVector, wheres::Vector)
if !(get(io, :compact, false)::Bool)
# Print module prefix unless alias is visible from module passed to
# IOContext. If :module is not set, default to Main (or current active module).
# IOContext. If :module is not set, default to Main.
# nothing can be used to force printing prefix.
from = get(io, :module, active_module())
from = get(io, :module, Main)
if (from === nothing || !isvisible(name.name, name.mod, from))
show(io, name.mod)
print(io, ".")
Expand Down Expand Up @@ -1053,9 +1045,9 @@ function show_type_name(io::IO, tn::Core.TypeName)
quo = false
if !(get(io, :compact, false)::Bool)
# Print module prefix unless type is visible from module passed to
# IOContext If :module is not set, default to Main (or current active module).
# IOContext If :module is not set, default to Main.
# nothing can be used to force printing prefix
from = get(io, :module, active_module())
from = get(io, :module, Main)
if isdefined(tn, :module) && (from === nothing || !isvisible(sym, tn.module, from::Module))
show(io, tn.module)
print(io, ".")
Expand Down Expand Up @@ -2535,7 +2527,7 @@ function show_signature_function(io::IO, @nospecialize(ft), demangle=false, farg
uw = unwrap_unionall(ft)
if ft <: Function && isa(uw, DataType) && isempty(uw.parameters) && _isself(uw)
uwmod = parentmodule(uw)
if qualified && !is_exported_from_stdlib(uw.name.mt.name, uwmod) && uwmod !== Main
if qualified && !isexported(uwmod, uw.name.mt.name) && uwmod !== Main
print_within_stacktrace(io, uwmod, '.', bold=true)
end
s = sprint(show_sym, (demangle ? demangle_function_name : identity)(uw.name.mt.name), context=io)
Expand Down
21 changes: 8 additions & 13 deletions stdlib/REPL/src/REPL.jl
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ function warn_on_non_owning_accesses(current_mod, ast)
end
return ast
end
warn_on_non_owning_accesses(ast) = warn_on_non_owning_accesses(REPL.active_module(), ast)
warn_on_non_owning_accesses(ast) = warn_on_non_owning_accesses(Base.active_module(), ast)

const repl_ast_transforms = Any[softscope, warn_on_non_owning_accesses] # defaults for new REPL backends

Expand Down Expand Up @@ -497,7 +497,7 @@ end
function display(d::REPLDisplay, mime::MIME"text/plain", x)
x = Ref{Any}(x)
with_repl_linfo(d.repl) do io
io = IOContext(io, :limit => true, :module => active_module(d)::Module)
io = IOContext(io, :limit => true, :module => Base.active_module(d)::Module)
if d.repl isa LineEditREPL
mistate = d.repl.mistate
mode = LineEdit.mode(mistate)
Expand Down Expand Up @@ -527,7 +527,7 @@ show_repl(io::IO, ::MIME"text/plain", ex::Expr) =
function print_response(repl::AbstractREPL, response, show_value::Bool, have_color::Bool)
repl.waserror = response[2]
with_repl_linfo(repl) do io
io = IOContext(io, :module => active_module(repl)::Module)
io = IOContext(io, :module => Base.active_module(repl)::Module)
print_response(io, response, show_value, have_color, specialdisplay(repl))
end
return nothing
Expand Down Expand Up @@ -628,7 +628,7 @@ function run_repl(repl::AbstractREPL, @nospecialize(consumer = x -> nothing); ba
Core.println(Core.stderr, e)
Core.println(Core.stderr, catch_backtrace())
end
get_module = () -> active_module(repl)
get_module = () -> Base.active_module(repl)
if backend_on_current_task
t = @async run_frontend(repl, backend_ref)
errormonitor(t)
Expand Down Expand Up @@ -760,14 +760,9 @@ REPLCompletionProvider() = REPLCompletionProvider(LineEdit.Modifiers())
mutable struct ShellCompletionProvider <: CompletionProvider end
struct LatexCompletions <: CompletionProvider end

function active_module() # this method is also called from Base
isdefined(Base, :active_repl) || return Main
Base.active_repl === nothing && return Main
return active_module(Base.active_repl::AbstractREPL)
end
active_module((; mistate)::LineEditREPL) = mistate === nothing ? Main : mistate.active_module
active_module(::AbstractREPL) = Main
active_module(d::REPLDisplay) = active_module(d.repl)
Base.active_module((; mistate)::LineEditREPL) = mistate === nothing ? Main : mistate.active_module
Base.active_module(::AbstractREPL) = Main
Base.active_module(d::REPLDisplay) = Base.active_module(d.repl)

setmodifiers!(c::CompletionProvider, m::LineEdit.Modifiers) = nothing

Expand Down Expand Up @@ -1206,7 +1201,7 @@ enable_promptpaste(v::Bool) = JL_PROMPT_PASTE[] = v

function contextual_prompt(repl::LineEditREPL, prompt::Union{String,Function})
function ()
mod = active_module(repl)
mod = Base.active_module(repl)
prefix = mod == Main ? "" : string('(', mod, ") ")
pr = prompt isa String ? prompt : prompt()
prefix * pr
Expand Down

0 comments on commit d38a442

Please sign in to comment.