Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Group import hints #56753

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
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))
ararslan marked this conversation as resolved.
Show resolved Hide resolved
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)
ajwheeler marked this conversation as resolved.
Show resolved Hide resolved
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"
ajwheeler marked this conversation as resolved.
Show resolved Hide resolved
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