-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
Wrongly empty typeintersect if a TypeVar needs to fixed to a non-type #20869
Comments
Type intersection gets it wrong here: julia> typeintersect(Tuple{Base.Val{0}, Type{Base.Val{N}} where N}, Tuple{Base.Val{N}, Type{Base.Val{N}}} where N)
Union{} while of course julia> Tuple{Base.Val{0}, Type{Base.Val{0}}} <: Tuple{Base.Val{0}, Type{Base.Val{N}} where N}
true
julia> Tuple{Base.Val{0}, Type{Base.Val{0}}} <: Tuple{Base.Val{N}, Type{Base.Val{N}}} where N
true |
Actually, it seems it has nothing to do with julia> typeintersect(Tuple{Array{Int,0}, Array{Array{Int,N}} where N}, Tuple{Array{Int,N}, Array{Array{Int,N}}} where N)
Union{}
julia> typeintersect(Tuple{Array{Int,0}, Array{Array{T,0}} where T}, Tuple{Array{T,0}, Array{Array{T,0}}} where T)
Tuple{Array{Int64,0},Array{Array{Int64,0},N} where N} It seems sufficient that the julia> typeintersect(Tuple{Val{0}, Val{Val{N}}} where N, Tuple{Val{N}, Val{Val{N}}} where N)
Union{} # should be Tuple{Val{0},Val{Val{0}}}
julia> typeintersect(Tuple{Val{Int}, Val{Val{N}}} where N, Tuple{Val{N}, Val{Val{N}}} where N)
Tuple{Val{Int64},Val{Val{Int64}}} # ok
julia> typeintersect(Tuple{Val{0}, Val{N}} where N, Tuple{Val{N}, Val{N}} where N)
Tuple{Val{0},Val{0}} # ok |
After some time with gdb, I think I have an idea of what is going wrong. When calling
At this point, upper and lower bounds on |
This seems to fix it: --- a/src/subtype.c
+++ b/src/subtype.c
@@ -701,6 +701,8 @@ static int subtype(jl_value_t *x, jl_value_t *y, jl_stenv_t *e, int param)
if (x == y) return 1;
jl_varbinding_t *xx = lookup(e, (jl_tvar_t*)x);
jl_varbinding_t *yy = lookup(e, (jl_tvar_t*)y);
+ if (xx && yy && xx->ub == xx->lb && xx->lb == yy->ub && yy->ub == yy->lb)
+ return 1;
jl_value_t *xub = xx ? xx->ub : ((jl_tvar_t*)x)->ub;
jl_value_t *ylb = yy ? yy->lb : ((jl_tvar_t*)y)->lb;
if (e->intersection) { Bullshit or PR-worthy? |
Thanks for digging into this. It's great to have more people familiar with the subtyping code. That change looks safe to me; if it passes tests you should PR it. |
While safe, that fix also seems to be overly specific, as some very similar cases still fail: julia> typeintersect(Tuple{Val{0}, Val{Val{N}}} where N, Tuple{Val{N}, Val{Val{N}}} where N)
Tuple{Val{0},Val{Val{0}}} # fixed by patch above
julia> typeintersect(Tuple{Val{N}, Val{Val{N}}} where N, Tuple{Val{0}, Val{Val{N}}} where N)
Tuple{Val{0},Val{Val{0}}} # fixed by patch above
julia> typeintersect(Tuple{Val{N}, Val{Val{0}}} where N, Tuple{Val{N}, Val{Val{N}}} where N)
Union{}
julia> typeintersect(Tuple{Val{N}, Val{Val{N}}} where N, Tuple{Val{N}, Val{Val{0}}} where N)
Tuple{Val{0},Val{Val{0}}} # already works on master
julia> typeintersect(Tuple{Val{Val{0}}, Val{N}} where N, Tuple{Val{Val{N}}, Val{N}} where N)
Tuple{Val{Val{0}},Val{0}} # already works on master
julia> typeintersect(Tuple{Val{Val{N}}, Val{N}} where N, Tuple{Val{Val{0}}, Val{N}} where N)
Tuple{Val{Val{0}},Val{0}} # already works on master
julia> typeintersect(Tuple{Val{Val{N}}, Val{0}} where N, Tuple{Val{Val{N}}, Val{N}} where N)
Union{}
julia> typeintersect(Tuple{Val{Val{N}}, Val{N}} where N, Tuple{Val{Val{N}}, Val{0}} where N)
Tuple{Val{Val{0}},Val{0}} # fixed by patch above I'll try digging a little deeper and will open a PR if I get the two remaining cases to work, too. |
Fixed by #21010. |
but for
N==0
, the one method we have actually does match. This can lead inference astray:That should of course be
Union{Bool, String}
, but inference only sees the second method offoo
.This affects e.g.
ntuple
andrdims
:The text was updated successfully, but these errors were encountered: