diff --git a/src/gf.c b/src/gf.c index 3fc75f862500a..af841930fb99e 100644 --- a/src/gf.c +++ b/src/gf.c @@ -1946,7 +1946,8 @@ jl_method_instance_t *jl_method_lookup(jl_value_t **args, size_t nargs, size_t w // full is a boolean indicating if that method fully covers the input // // lim is the max # of methods to return. if there are more, returns jl_false. -// -1 for no limit. +// Negative values stand for no limit. +// Unless lim == -1, remove matches that are unambiguously covered by earler ones JL_DLLEXPORT jl_value_t *jl_matching_methods(jl_tupletype_t *types, jl_value_t *mt, int lim, int include_ambiguous, size_t world, size_t *min_valid, size_t *max_valid, int *ambig) { @@ -3036,7 +3037,7 @@ static jl_value_t *ml_matches(jl_methtable_t *mt, if (!subt2 && subt) break; if (subt == subt2) { - if (lim >= 0) { + if (lim != -1) { if (subt || !jl_has_empty_intersection(m->sig, m2->sig)) if (!jl_type_morespecific((jl_value_t*)m->sig, (jl_value_t*)m2->sig)) break; @@ -3190,7 +3191,7 @@ static jl_value_t *ml_matches(jl_methtable_t *mt, } } // when limited, skip matches that are covered by earlier ones (and aren't perhaps ambiguous with them) - if (lim >= 0) { + if (lim != -1) { for (i = 0; i < len; i++) { if (skip[i]) continue; diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index 76482e96dd299..295fd5ae64229 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -530,14 +530,14 @@ end # Method completion on function call expression that look like :(max(1)) MAX_METHOD_COMPLETIONS::Int = 40 -function complete_methods(ex_org::Expr, context_module::Module=Main) +function complete_methods(ex_org::Expr, context_module::Module=Main, shift::Bool=false) out = Completion[] funct, found = get_type(ex_org.args[1], context_module)::Tuple{Any,Bool} !found && return out args_ex, kwargs_ex = complete_methods_args(ex_org.args[2:end], ex_org, context_module, true, true) push!(args_ex, Vararg{Any}) - complete_methods!(out, funct, args_ex, kwargs_ex, MAX_METHOD_COMPLETIONS) + complete_methods!(out, funct, args_ex, kwargs_ex, shift ? -2 : MAX_METHOD_COMPLETIONS) return out end @@ -626,7 +626,7 @@ function complete_methods!(out::Vector{Completion}, @nospecialize(funct), args_e m = Base._methods_by_ftype(t_in, nothing, max_method_completions, Base.get_world_counter(), #=ambig=# true, Ref(typemin(UInt)), Ref(typemax(UInt)), Ptr{Int32}(C_NULL)) if m === false - push!(out, TextCompletion(sprint(Base.show_signature_function, funct) * "( too many methods to show )")) + push!(out, TextCompletion(sprint(Base.show_signature_function, funct) * "( too many methods, use SHIFT-TAB to show )")) end m isa Vector || return for match in m @@ -835,9 +835,9 @@ function completions(string::String, pos::Int, context_module::Module=Main, shif if isa(ex, Expr) if ex.head === :call - return complete_methods(ex, context_module), first(frange):method_name_end, false + return complete_methods(ex, context_module, shift), first(frange):method_name_end, false elseif ex.head === :. && ex.args[2] isa Expr && (ex.args[2]::Expr).head === :tuple - return complete_methods(ex, context_module), first(frange):(method_name_end - 1), false + return complete_methods(ex, context_module, shift), first(frange):(method_name_end - 1), false end end elseif inc_tag === :comment diff --git a/stdlib/REPL/test/replcompletions.jl b/stdlib/REPL/test/replcompletions.jl index 6dc9d9b8b2883..f584569519c22 100644 --- a/stdlib/REPL/test/replcompletions.jl +++ b/stdlib/REPL/test/replcompletions.jl @@ -514,6 +514,17 @@ let s = """CompletionFoo.test4("\\"",""" @test length(c) == 2 end +# Test max method suggestions +let s = "convert(" + c, _, res = test_complete_noshift(s) + @test !res + @test only(c) == "convert( too many methods, use SHIFT-TAB to show )" + c2, _, res2 = test_complete(s) + @test !res2 + @test any(==(string(first(methods(convert)))), c2) + @test length(c2) > REPL.REPLCompletions.MAX_METHOD_COMPLETIONS +end + ########## Test where the current inference logic fails ######## # Fails due to inference fails to determine a concrete type for arg 1 # But it returns AbstractArray{T,N} and hence is able to remove test5(x::Float64) from the suggestions