-
-
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
subtype <:
wrong inside function in some cases
#11327
Comments
The error is not in the |
So what would be the correct type for sig? Concerning tm.sig <: fm.sig # = true
fm.sig <: tm.sig # = true imply fm.sig == tm.sig # = true ? Or is that also part of the issue you refer to? |
Well if you want the tightest type for the field type I'm pretty sure you have to add a parameter like : immutable A{T}
sig :: Type{T}
end The reason why it is answering strange things in a function is because the I'll look at it this afternoon. |
Smaller repro : abstract A
abstract B <: A
f{T}(::Type{T},x::T) = x
Base.return_types(f, (Type{Type{A}}, Type{B})) # => Type{A}
f(Type{A},B) # => B in this issue the |
seems like a dispatch error caused by the parameter matching algo. I'm not too familiar with the current state of this so maybe its a dup of something. @timholy could you have a look since apparently you are having fun with this part of the codebase these days :-) |
I'll try to check it out later this week. |
Notes: - I'm not sure whether a tuple of traits should be an ordiary tuple or a Tuple{} - issue JuliaLang/julia#11327 causes some problems with find_tvars - Heisenbug of (see m3/heisenbug) disappeared
(The reference to this issue in my above commit should instead point to #10930) |
Partial progress (I have to abandon this for now due to other constraints): julia> abstract A
julia> abstract B <: A
julia> T = TypeVar(:T, true)
T
julia> typeintersect(Tuple{Type{T}, T}, Tuple{Type{A}, B})
Tuple{Type{A},_<:B} Setting a breakpoint in
|
julia> T = TypeVar(:T, true)
T
julia> typeintersect(Tuple{T,T},Tuple{Float64,FloatingPoint})
Tuple{Float64,Float64}
julia> typeintersect(Tuple{Type{T},T},Tuple{Type{Float64},FloatingPoint})
Tuple{Type{Float64},Float64}
julia> typeintersect(Tuple{Type{T},T},Tuple{Type{FloatingPoint},FloatingPoint})
Tuple{Type{FloatingPoint},_<:FloatingPoint}
julia> typeintersect(Tuple{Type{T},T},Tuple{Type{FloatingPoint},Float64})
Tuple{Type{FloatingPoint},Float64}
julia> typeintersect(Tuple{T,Type{T}},Tuple{Float64, Type{FloatingPoint}})
Tuple{Float64,Type{FloatingPoint}} Since |
Wow, this is looking like more of a rabbit hole than I expected. I can solve my @@ -1263,7 +1265,24 @@ static int solve_tvar_constraints(cenv_t *env, cenv_t *soln)
}
}
- // 3. given T, let S´ = intersect(all S s.t. (T=S) or (S=T) ∈ env). add (T=S´) to soln.
+ // 3. check compatibility of T==S && T<:R (requires S<:R)
+ for(int i=0; i < soln->n; i+=2) {
+ jl_value_t *tv = soln->data[i];
+ if (jl_is_typevar(tv)) {
+ jl_value_t *ts = soln->data[i+1];
+ for (int j=0; j < env->n; j+=2) {
+ jl_value_t *tvj = env->data[j];
+ if (tv == tvj)
+ if (!jl_subtype(ts, env->data[j+1], 0)) {
+ return 0;
+ }
+ }
+ }
+ }
+
+ // 4. given T, let S´ = intersect(all S s.t. (T=S) or (S=T) ∈ env). add (T=S´) to soln.
for(int i=0; i < env->n; i+=2) {
jl_value_t *T = env->data[i];
jl_value_t **pS = &env->data[i+1]; but then it turns out we've been depending on this behavior for things as simple as convert(Any, x) where diff --git a/base/essentials.jl b/base/essentials.jl
index 702dd82..5688a4b 100644
--- a/base/essentials.jl
+++ b/base/essentials.jl
@@ -43,6 +43,7 @@ call{T}(::Type{T}, arg) = convert(T, arg)::T
call{T}(::Type{T}, args...) = convert(T, args...)::T
convert{T}(::Type{T}, x::T) = x
+convert{T}(::Type{T}, x) = x # fallback
convert(::Type{Tuple{}}, ::Tuple{}) = ()
convert(::Type{Tuple}, x::Tuple) = x but in running the tests there turn out to be other such instances (e.g., |
For the original problem, one might also have to delete or modify this, because it converts |
I think this problem is specific to
is equivalent to
the first argument gives |
I could be wrong, but I worry it's not that specific to julia> abstract A
julia> abstract B <: A
julia> T = TypeVar(:T, true)
T
julia> typeintersect(Tuple{Ptr{T}, T}, Tuple{Ptr{A}, B})
Tuple{Ptr{A},_<:B} (EDIT: Presumably the result here should be |
No, that's correct: T=A, and everything that matches T is a subtype of it. One could dislike this behavior, but it's sound. The case with |
OK, good. Glad you're tackling this; I was going in entirely the wrong direction. |
it looks like the original issue was fixed by 9de38dc carnaval's followup (#11327 (comment)) appears to still be valid (may be a duplicate of #11015 however) |
Julia 0.4 gets subtype relation wrong inside a function scope with tuple types:
Note that it works fine if the type is declared as:
immutable FakeMethod sig end
The text was updated successfully, but these errors were encountered: