Skip to content

Commit

Permalink
[REPLCompletions] improve REPLInterpreter effects of dict operations (
Browse files Browse the repository at this point in the history
#52347)

This should allow more completions for cases involving dict operations.
  • Loading branch information
aviatesk authored Dec 7, 2023
1 parent c731edb commit 83abbcd
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 4 deletions.
8 changes: 4 additions & 4 deletions base/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ function empty!(h::Dict{K,V}) where V where K
end

# get the index where a key is stored, or -1 if not present
@assume_effects :terminates_locally function ht_keyindex(h::Dict{K,V}, key) where V where K
function ht_keyindex(h::Dict{K,V}, key) where V where K
isempty(h) && return -1
sz = length(h.keys)
iter = 0
Expand All @@ -280,9 +280,9 @@ end
index, sh = hashindex(key, sz)
keys = h.keys

@inbounds while true
@assume_effects :terminates_locally :noub @inbounds while true
isslotempty(h,index) && return -1
if h.slots[index] == sh
if sh == h.slots[index]
k = keys[index]
if (key === k || isequal(key, k))
return index
Expand Down Expand Up @@ -507,7 +507,7 @@ end

function getindex(h::Dict{K,V}, key) where V where K
index = ht_keyindex(h, key)
@inbounds return (index < 0) ? throw(KeyError(key)) : h.vals[index]::V
return index < 0 ? throw(KeyError(key)) : @assume_effects :noub @inbounds h.vals[index]::V
end

"""
Expand Down
18 changes: 18 additions & 0 deletions stdlib/REPL/test/replcompletions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2156,3 +2156,21 @@ let t = REPLCompletions.repl_eval_ex(:(Base.PersistentDict(issue52099 => 3)), @_
@test length(t.val) == 1
end
end

# test REPLInterpreter effects for `getindex(::Dict, key)`
for (DictT, KeyT) = Any[(Dict{Symbol,Any}, Symbol),
(Dict{Int,Any}, Int),
(Dict{String,Any}, String)]
@testset let DictT=DictT, KeyT=KeyT
effects = Base.infer_effects(getindex, (DictT,KeyT); interp=REPL.REPLCompletions.REPLInterpreter())
@test Core.Compiler.is_effect_free(effects)
@test Core.Compiler.is_terminates(effects)
@test Core.Compiler.is_noub(effects)
effects = Base.infer_effects((DictT,KeyT); interp=REPL.REPLCompletions.REPLInterpreter()) do d, key
key in keys(d)
end
@test Core.Compiler.is_effect_free(effects)
@test Core.Compiler.is_terminates(effects)
@test Core.Compiler.is_noub(effects)
end
end

0 comments on commit 83abbcd

Please sign in to comment.