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

Inference resulting in where T<:Int64 #23278

Closed
Jutho opened this issue Aug 16, 2017 · 2 comments
Closed

Inference resulting in where T<:Int64 #23278

Jutho opened this issue Aug 16, 2017 · 2 comments
Assignees
Labels
compiler:inference Type inference

Comments

@Jutho
Copy link
Contributor

Jutho commented Aug 16, 2017

While there are already several issues regarding inference regression on master, I decided to file this issue as it also exists in Julia 0.6.

I noticed a problem where inference introduces a type parameter which is bound to be a leaf type. Noticeably, while the problem exists on julia 0.6 and 0.7-DEV, it pops up sooner on master, probably because of the interplay with other inference regressions with respect to tuples (#23277, #22513).

I also posted this example in #22513 as I first assumed it was another instance of that issue:

tpermute(t::NTuple{N,T}, p::NTuple{N,Int}) where {T,N} = _tpermute((), t, p)
_tpermute(tdst::NTuple{N,T}, tsrc::NTuple{N,T}, p::NTuple{N,Int}) where {T,N} = tdst
_tpermute(tdst::NTuple{M,T}, tsrc::NTuple{N,T}, p::NTuple{N,Int}) where {T,M,N} = _tpermute((tdst...,tsrc[p[M+1]]), tsrc, p)

On master, one obtains for any N>=2

julia> N=2;Base.return_types(tpermute,Tuple{NTuple{N,Int},NTuple{N,Int}})
1-element Array{Any,1}:
 Tuple{Vararg{T,2}} where T<:Int64

which seems like it would infer correctly if not making the mistake of introducing a type parameter for a leaf type. On Julia 0.6, this is correctly inferred up to tuples of length N=15, after which one obtains:

julia> N=16;Base.return_types(tpermute,Tuple{NTuple{N,Int},NTuple{N,Int}})
1-element Array{Any,1}:
 Union{Tuple{T,T,T,T,T,T,T,T,T,T,T,T,T,T,Vararg{T,2}} where T<:Int64, Tuple{Vararg{T,16}} where T<:Int64}

which has the same issue with the type parameter, and the additional issue of not identifying the two types in the Union.

A slightly different implementation for the same function:

tpermute(t::NTuple{N,T}, p::NTuple{N,Int}) where {T,N} = _tpermute((), t, p)
_tpermute(tdst::NTuple{N,T}, tsrc::NTuple{N,T}, p::Tuple{}) where {T,N} = tdst
_tpermute(tdst, tsrc, p) = _tpermute((tdst..., tsrc[p[1]]), tsrc, Base.tail(p))

has the same behavior on master, and only fixes the Union problem on Julia 0.6.

My apologies if this is another instance of an existing issue. I don't know how inference works and did not find any similar issue.

@Jutho Jutho added the compiler:inference Type inference label Aug 16, 2017
@mauro3
Copy link
Contributor

mauro3 commented Aug 16, 2017

On 0.5.2 the first example works fine but the N=16 errors:

julia> N=16;Base.return_types(tpermute,Tuple{NTuple{N,Int},NTuple{N,Int}})               
WARNING: An error occurred during inference. Type inference is now partially disabled.   
ErrorException("type too large")                                                         
rec_backtrace at ~/julia/julia-0.5/src/stackwalk.c:84                          
... (long)

vtjnash added a commit that referenced this issue Aug 16, 2017
The subtyping algorithm is unable to correctly handle the case where the UnionAll bounds and swapped with other covariant bounds
This works around that issue during construction.

Unfortunately, this often triggers the more serious subtyping design bug
referenced in subtype.c, causing frequent segfaults:

    873                 // TODO this is not strictly correct, but we don't yet have any other way for
    874                 // e.g. the argument `Int` to match a `::DataType` slot. Most correct would be:
    875                 // Int isa DataType, Int isa Type{Int}, Type{Int} more specific than DataType,
    876                 // !(Type{Int} <: DataType), !isleaftype(Type{Int}), because non-DataTypes can
    877                 // be type-equal to `Int`.

fix #23278
@vtjnash vtjnash self-assigned this Aug 16, 2017
@vtjnash
Copy link
Member

vtjnash commented Mar 12, 2020

julia> N=2^18;Base.return_types(tpermute,Tuple{NTuple{N,Int},NTuple{N,Int}})
1-element Array{Any,1}:
 NTuple{262144,Int64}

(for the first example anyways—the second tends to infer up to 2^10, then starts to stack-overflow the compiler around 2^11)

@vtjnash vtjnash closed this as completed Mar 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler:inference Type inference
Projects
None yet
Development

No branches or pull requests

3 participants