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

[REPLCompletions] improve REPLInterpreter effects of dict operations #52347

Merged
merged 2 commits into from
Dec 7, 2023

Conversation

aviatesk
Copy link
Sponsor Member

This should allow more completions for cases involving dict operations.

@oscardssmith
Copy link
Member

I'm not sure this use of noub is valid since we're calling user defined hash functions

@aviatesk aviatesk added the status:DO NOT MERGE Do not merge this PR! label Dec 1, 2023
@aviatesk
Copy link
Sponsor Member Author

aviatesk commented Dec 1, 2023

Right. We can do a very much special-cased patch like

diff --git a/base/dict.jl b/base/dict.jl
index e7d4804b68..587c348989 100644
--- a/base/dict.jl
+++ b/base/dict.jl
@@ -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 :noub function ht_keyindex(h::Dict{K,V}, key) where V where K
+@assume_effects :terminates_locally function ht_keyindex(h::Dict{K,V}, key) where V where K
     isempty(h) && return -1
     sz = length(h.keys)
     iter = 0
@@ -294,6 +294,8 @@ end
     end
     # This line is unreachable
 end
+@assume_effects :noub ht_keyindex(h::Dict{Symbol,V}, key::Symbol) where V =
+    @invoke ht_keyindex(h::Dict{Symbol,V}, key::Any)
 
 # get (index, sh) for the key
 #     index - where a key is stored, or -pos if not present
@@ -505,10 +507,12 @@ function get!(default::Callable, h::Dict{K,V}, key::K) where V where K
     return v
 end
 
-@assume_effects :noub function getindex(h::Dict{K,V}, key) where V where K
+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
 end
+@assume_effects :noub getindex(h::Dict{Symbol,V}, key::Symbol) where V =
+    @invoke getindex(h::Dict{Symbol,V}, key::Any)
 
 """
     get(collection, key, default)

, which obviously only improves effects for Dict{Symbol, Any}.
Or, alternatively, we can implement call-site @assume_effects and do something like:

diff --git a/base/dict.jl b/base/dict.jl
index e7d4804b68..3dfde3d395 100644
--- a/base/dict.jl
+++ b/base/dict.jl
@@ -162,7 +162,7 @@ _shorthash7(hsh::UInt) = (hsh >> (8sizeof(UInt)-7))%UInt8 | 0x80
 # hashindex (key, sz) - computes optimal position and shorthash7
 #     idx - optimal position in the hash table
 #     sh::UInt8 - short hash (7 highest hash bits)
-function hashindex(key, sz)
+function hashindex(key, sz::Int)
     hsh = hash(key)::UInt
     idx = (((hsh % Int) & (sz-1)) + 1)::Int
     return idx, _shorthash7(hsh)
@@ -172,7 +172,7 @@ end
 @propagate_inbounds isslotfilled(h::Dict, i::Int) = (h.slots[i] & 0x80) != 0
 @propagate_inbounds isslotmissing(h::Dict, i::Int) = h.slots[i] == 0x7f
 
-@constprop :none function rehash!(h::Dict{K,V}, newsz = length(h.keys)) where V where K
+@constprop :none function rehash!(h::Dict{K,V}, newsz::Int = length(h.keys)) where V where K
     olds = h.slots
     oldk = h.keys
     oldv = h.vals
@@ -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 :noub function ht_keyindex(h::Dict{K,V}, key) where V where K
+@assume_effects :terminates_locally function ht_keyindex(h::Dict{K,V}, key) where V where K
     isempty(h) && return -1
     sz = length(h.keys)
     iter = 0
@@ -282,8 +282,8 @@ end
 
     @inbounds while true
         isslotempty(h,index) && return -1
-        if h.slots[index] == sh
-            k = keys[index]
+        if sh == @assume_effects :noub h.slots[index]
+            k = @assume_effects :noub keys[index]
             if (key ===  k || isequal(key, k))
                 return index
             end
@@ -505,9 +505,9 @@ function get!(default::Callable, h::Dict{K,V}, key::K) where V where K
     return v
 end
 
-@assume_effects :noub function getindex(h::Dict{K,V}, key) where V where K
+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
 
 """

while letting the compiler automatically prove :noub of the other parts of code including custom hash implementation.

@aviatesk aviatesk force-pushed the avi/replinterp-effects-for-dict branch 2 times, most recently from 72082a2 to 9984c6f Compare December 5, 2023 07:20
@aviatesk aviatesk changed the base branch from master to avi/callsite-assume_effects December 5, 2023 07:20
@aviatesk
Copy link
Sponsor Member Author

aviatesk commented Dec 5, 2023

Now this is based on #52400.

@aviatesk aviatesk removed the status:DO NOT MERGE Do not merge this PR! label Dec 5, 2023
@aviatesk aviatesk force-pushed the avi/replinterp-effects-for-dict branch from 9984c6f to 3fe726e Compare December 5, 2023 10:04
@aviatesk aviatesk force-pushed the avi/replinterp-effects-for-dict branch from 3fe726e to 805d2bc Compare December 6, 2023 02:41
@aviatesk aviatesk force-pushed the avi/replinterp-effects-for-dict branch from 805d2bc to e19f0a4 Compare December 6, 2023 05:04
@aviatesk aviatesk force-pushed the avi/replinterp-effects-for-dict branch from e19f0a4 to b35811c Compare December 6, 2023 09:07
Base automatically changed from avi/callsite-assume_effects to master December 6, 2023 22:06
@aviatesk aviatesk force-pushed the avi/replinterp-effects-for-dict branch from b35811c to 60b02fc Compare December 6, 2023 22:11
@aviatesk aviatesk merged commit 83abbcd into master Dec 7, 2023
4 of 7 checks passed
@aviatesk aviatesk deleted the avi/replinterp-effects-for-dict branch December 7, 2023 03:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants