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

Fix some vararg-related subtyping issues #31698

Merged
merged 13 commits into from
May 18, 2019
Merged

Fix some vararg-related subtyping issues #31698

merged 13 commits into from
May 18, 2019

Conversation

Keno
Copy link
Member

@Keno Keno commented Apr 12, 2019

This is a backport from (a local version of) #31681. Turns out the same subtyping issues I addressed there exist on master, but we just tend to not see those types a whole lot.

@JeffBezanson
Copy link
Member

Rebased on master to pick up the gc root fix.

@Keno
Copy link
Member Author

Keno commented Apr 12, 2019

I have more cases to fix that partially correct what's here, so let's do them all at once.

@Keno
Copy link
Member Author

Keno commented Apr 12, 2019

Current set of tests, I'm trying to fix, beyond what's in this PR:

let A = Tuple{Vararg{Val{N}, N} where N},
    B = Tuple{Vararg{Val{N}, N}} where N,
    C = Tuple{Val{2}, Val{2}}

    @test A == B
    @test issub(B, A)
    @test issub(C, A)
end
@test (Tuple{T, Vararg{T, 2}} where T<:Real) == (Tuple{Vararg{T, 3}} where T<: Real)

@JeffBezanson JeffBezanson added the types and dispatch Types, subtyping and method dispatch label Apr 12, 2019
@Keno Keno force-pushed the kf/varargsubtype branch 2 times, most recently from c67d1b5 to acec9b5 Compare April 16, 2019 23:52
@Keno
Copy link
Member Author

Keno commented Apr 16, 2019

Note to self: The following is still wrong on this branch:

(Tuple{Vararg{T, 10}} where T<:Real) <: Base.Any16

@Keno Keno force-pushed the kf/varargsubtype branch from acec9b5 to 5a8bdbf Compare April 17, 2019 20:21
@Keno
Copy link
Member Author

Keno commented Apr 18, 2019

Looks like I need to put the vararg subtyping check back for things like Type{Vararg} == Type{Vararg} which does get asked about when Vararg is used explicitly in the code.

@JeffBezanson
Copy link
Member

We should try to avoid that, since forming those types should not be allowed.

@Keno
Copy link
Member Author

Keno commented Apr 18, 2019

It comes up in situations like the following:

push!(Any[], Vararg)

for which the compiled signature is Tuple{typeof(push!), Vector{Any}, Type{Vararg}}. I guess we could disallow Vararg from Typeof.

@Keno Keno force-pushed the kf/varargsubtype branch from 5a8bdbf to 4be19a7 Compare April 18, 2019 20:21
@Keno
Copy link
Member Author

Keno commented Apr 18, 2019

@JeffBezanson This is ready for re-review.

@Keno
Copy link
Member Author

Keno commented Apr 20, 2019

Linking #30995 here for the Type{Vararg} issue. I guess the conclusion is that that isn't legal, so we should find out who forms it and fix it.

if (npx != npy || vx || vy) {
if (!vy) {
if (npx != npy || vx != JL_VARARG_NONE || vy) {
if ((vx == JL_VARARG_NONE || vx == JL_VARARG_UNBOUND) && !vy) {
Copy link
Member

@vtjnash vtjnash Apr 24, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think UNBOUND is computed incorrectly for subtyping's use (iirc, it was introduced for gf.c's heuristic type signature limiting), since it doesn't count number of uses. Consider Tuple{Vararg{NTuple{N}, N} where N}. To be conservative, just consider jl_is_long vs jl_is_typevar in this fast-path.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What the problem with that case? If the RHS is not a vararg, then if we have a unionall here it can't possibly be a subtype.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know. I just don't trust this code to do any counting of TypeVar uses.

test/subtype.jl Outdated Show resolved Hide resolved
src/subtype.c Outdated Show resolved Hide resolved
src/subtype.c Outdated Show resolved Hide resolved
@JeffBezanson
Copy link
Member

I think this fixes #31805? Would be good to add that test case.

@Keno Keno force-pushed the kf/varargsubtype branch from 7cf98bb to cf256fa Compare April 25, 2019 21:21
src/subtype.c Outdated
jl_vararg_kind_t vx = JL_VARARG_NONE;
jl_value_t *vxt = NULL;
int vy = 0;
int vnpx = npx;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vnpx seems like an odd (too long) mash of letters, since it appears to actually be the number of required (non-var) parameters (nfx for "n fields/fixed of x")

if (npx != npy || vx || vy) {
if (!vy) {
if (npx != npy || vx != JL_VARARG_NONE || vy) {
if ((vx == JL_VARARG_NONE || vx == JL_VARARG_UNBOUND) && !vy) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know. I just don't trust this code to do any counting of TypeVar uses.

return t # t isn't something new
else
ut = unwrap_unionall(t)
if isa(ut, DataType) && ut.name !== unwrap_unionall(Vararg).name && isa(c, Type) && c !== Union{} && c <: t
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can use Base._va_typename here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Core.Compiler.) _va_typename, but yes

@Keno
Copy link
Member Author

Keno commented May 16, 2019

PkgEval reveals the following incorrect intersection on this branch:

julia> typeintersect(Tuple{Array{Tuple{Vararg{Int64,N}},N},Tuple{Vararg{Array{Int64,1},N}}} where N, Tuple{Array{Tuple{Int64},1}, Tuple})
Union{}

(Tuple{Array{Tuple{Int64},1},Tuple{Array{Int64,1}}} is in the intersection).

Keno and others added 11 commits May 17, 2019 18:36
…ararg

Upon construction, we normalize `Vararg{T, N} where {T,N}` to `Vararg{T where T, N} where N`,
thus there can be at most one UnionAll wrapper around a Vararg. In subtyping we were already
assuming that there can be at most two such wrappers, so simply adjust that and add an
appropriate assertion to make sure we catch any cases where this ever goes wrong.
In subtyping proper, variables introduced on the left (i.e. forall
variables) don't have any equality constraints, because we have no
syntax for creating them. However, intersection does sometimes create
such environments, so we need to handle it in subtyping.
@Keno Keno force-pushed the kf/varargsubtype branch from 611b947 to a3db5f6 Compare May 17, 2019 22:36
@Keno
Copy link
Member Author

Keno commented May 18, 2019

PkgEval is clean now. Will merge.

@Keno
Copy link
Member Author

Keno commented Jul 20, 2019

Let's backport this to fix #32607

@KristofferC KristofferC mentioned this pull request Jul 20, 2019
14 tasks
Keno added a commit that referenced this pull request Jul 20, 2019
* Fix jl_obvious_subtype with INT vararg constraint

* Fix a vararg-related non-transitivity in subtyping

* Fix another vararg subtype issue

* Take advantage of their being at most one UnionAll wrapped around a Vararg

Upon construction, we normalize `Vararg{T, N} where {T,N}` to `Vararg{T where T, N} where N`,
thus there can be at most one UnionAll wrapper around a Vararg. In subtyping we were already
assuming that there can be at most two such wrappers, so simply adjust that and add an
appropriate assertion to make sure we catch any cases where this ever goes wrong.

* Rewrite subtype_tuple to fix extra cases

* Put back the case for naked varargs

* Update test/subtype.jl

Co-Authored-By: Keno <[email protected]>

* Add test for #31805

* Fix style review comments

* Rename variable

* In person review changes

* Fix bug

* Handle integer bounds on left arguments in the environment

In subtyping proper, variables introduced on the left (i.e. forall
variables) don't have any equality constraints, because we have no
syntax for creating them. However, intersection does sometimes create
such environments, so we need to handle it in subtyping.

(Cherry-picked from 4a38e79)
@ararslan
Copy link
Member

Running PkgEval with the backports branch suggests that this didn't fix the issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
types and dispatch Types, subtyping and method dispatch
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants