Skip to content
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 52 additions & 22 deletions stdlib/REPL/src/REPL.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,37 +55,67 @@
else
scope = undef
end
if scope !== Base && !_UndefVarError_warnfor(io, Base, var)
warned = false
for m in Base.loaded_modules_order
m === Core && continue
m === Base && continue
m === Main && continue
m === scope && continue
warned |= _UndefVarError_warnfor(io, m, var)
if scope !== Base

Check warning on line 58 in stdlib/REPL/src/REPL.jl

View workflow job for this annotation

GitHub Actions / Check whitespace

Whitespace check

trailing whitespace
warned = _UndefVarError_warnfor(io, [Base], var)

if !warned
modules_to_check = (m for m in Base.loaded_modules_order
if m !== Core && m !== Base && m !== Main && m !== scope)
warned |= _UndefVarError_warnfor(io, modules_to_check, var)
end
warned ||
_UndefVarError_warnfor(io, Core, var) ||
_UndefVarError_warnfor(io, Main, var)

warned || _UndefVarError_warnfor(io, [Core, Main], var)
end
return nothing
end

function _UndefVarError_warnfor(io::IO, m::Module, var::Symbol)
Base.isbindingresolved(m, var) || return false
(Base.isexported(m, var) || Base.ispublic(m, var)) || return false
function _UndefVarError_warnfor(io::IO, modules, var::Symbol)
active_mod = Base.active_module()
print(io, "\nHint: ")
if isdefined(active_mod, Symbol(m))
print(io, "a global variable of this name also exists in $m.")
else
if Symbol(m) == var
print(io, "$m is loaded but not imported in the active module $active_mod.")

warned = false
# collect modules which export or make public the variable by

Check warning on line 76 in stdlib/REPL/src/REPL.jl

View workflow job for this annotation

GitHub Actions / Check whitespace

Whitespace check

trailing whitespace
# the parentmodule in which the variable is defined
to_warn_about = Dict{Module, Vector{Module}}()
for m in modules
# only warn if binding is resolved and exported or public

Check warning on line 80 in stdlib/REPL/src/REPL.jl

View workflow job for this annotation

GitHub Actions / Check whitespace

Whitespace check

trailing whitespace
if !Base.isbindingresolved(m, var) || (!Base.isexported(m, var) && !Base.ispublic(m, var))
continue
end
warned = true

# handle case where the undefined variable is the name of a loaded module
if Symbol(m) == var && !isdefined(active_mod, var)
print(io, "\nHint: $m is loaded but not imported in the active module $active_mod.")
continue
end

parent_m = parentmodule(getproperty(m, var))
if !haskey(to_warn_about, parent_m)
to_warn_about[parent_m] = [m]
else
print(io, "a global variable of this name may be made accessible by importing $m in the current active module $active_mod")
push!(to_warn_about[parent_m], m)
end
end

if !isempty(to_warn_about)
for (parent_m, modules) in pairs(to_warn_about)
print(io, "\nHint: a global variable of this name also exists in ", parent_m)
for m in modules
m == parent_m && continue
how_available = if Base.isexported(m, var)
"exported by"
elseif Base.ispublic(m, var)
"made available as public by"
end
print(io, "\n - Also $how_available $m")
if !isdefined(active_mod, Symbol(m))
print(io, " (loaded but not imported in $active_mod)")
end
print(io, ".")
end
end
end
return true
return warned
end

function __init__()
Expand Down
Loading