diff --git a/stdlib/REPL/src/REPL.jl b/stdlib/REPL/src/REPL.jl index c5c45dee34a01..bb5915c192b6e 100644 --- a/stdlib/REPL/src/REPL.jl +++ b/stdlib/REPL/src/REPL.jl @@ -44,7 +44,16 @@ function UndefVarError_hint(io::IO, ex::UndefVarError) if C_NULL == owner # No global of this name exists in this module. # This is the common case, so do not print that information. - print(io, "\nSuggestion: check for spelling errors or missing imports.") + # It could be the binding was exported by two modules, which we can detect + # by the `usingfailed` flag in the binding: + if isdefined(bnd, :flags) && Bool(bnd.flags >> 4 & 1) # magic location of the `usingfailed` flag + print(io, "\nHint: It looks like two or more modules export different ", + "bindings with this name, resulting in ambiguity. Try explicitly ", + "importing it from a particular module, or qualifying the name ", + "with the module it should come from.") + else + print(io, "\nSuggestion: check for spelling errors or missing imports.") + end owner = bnd else owner = unsafe_pointer_to_objref(owner)::Core.Binding diff --git a/stdlib/REPL/test/repl.jl b/stdlib/REPL/test/repl.jl index 83df34a056578..12f3f8956122e 100644 --- a/stdlib/REPL/test/repl.jl +++ b/stdlib/REPL/test/repl.jl @@ -1696,6 +1696,35 @@ finally empty!(Base.Experimental._hint_handlers) end +try # test the functionality of `UndefVarError_hint` against import clashes + @assert isempty(Base.Experimental._hint_handlers) + Base.Experimental.register_error_hint(REPL.UndefVarError_hint, UndefVarError) + + @eval module X + + module A + export x + x = 1 + end # A + + module B + export x + x = 2 + end # B + + using .A, .B + + end # X + + expected_message = string("\nHint: It looks like two or more modules export different ", + "bindings with this name, resulting in ambiguity. Try explicitly ", + "importing it from a particular module, or qualifying the name ", + "with the module it should come from.") + @test_throws expected_message X.x +finally + empty!(Base.Experimental._hint_handlers) +end + # Hints for tab completes fake_repl() do stdin_write, stdout_read, repl