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

Vararg behaves strangely in Core.Typeof #30995

Closed
timholy opened this issue Feb 7, 2019 · 6 comments · Fixed by #38136
Closed

Vararg behaves strangely in Core.Typeof #30995

timholy opened this issue Feb 7, 2019 · 6 comments · Fixed by #38136

Comments

@timholy
Copy link
Member

timholy commented Feb 7, 2019

julia> y = Array.body.body
Array{T,N}

julia> Type{y}
Type{Array{T,N}}

julia> x = Vararg.body.body
Vararg{T,N}

julia> Type{x}
ERROR: TypeError: in Type, in parameter, expected Type, got Vararg{T,N}
Stacktrace:
 [1] top-level scope at none:0
@JeffBezanson
Copy link
Member

Vararg isn't a valid type by itself, and you can't add methods to it. This error is intentional.

julia> Type{Vararg}
ERROR: TypeError: in Type, in parameter, expected Type, got Vararg

There's an explicit check for it here:

if (jl_is_vararg_type(v))

True, in this case the error "leaks":

julia> methods(Vararg)
ERROR: TypeError: in Type, in parameter, expected Type, got Vararg

and we could maybe use a better error.

How did this come up?

@timholy
Copy link
Member Author

timholy commented Feb 7, 2019

I wondered if that was the answer but didn't find that check, thanks!

How did this come up?

I'm stress-testing JuliaInterpreter and a forthcoming rewrite of Revise that will (hopefully) be based around lowered code. Goal is to use JuliaInterpreter to extract signatures for all methods in Base and link them to the expressions that defined them. (Revise kinda does this now, but it misses lots, like all the @evaled methods.) If it matters I can post a package-in-progress, but in very schematic terms it's

for (mod, file) in Base._included_files
    thunks = parse_and_lower_all_toplevel_exprs(mod, file)
    for thunk in thunks
        step_through_lines_and_intercept(stmt->isexpr(stmt, :method) || isexpr(:call_to_Core.eval, stmt), mod, thunk.args[1])
    end
end

I hit this specific issue when trying to interpret this line.

I can obviously work around it, and this is pretty esoteric, so I will close it. Don't be surprised if I open a number of other "weird" issues as I progress. I should also say that I'm aware the overall strategy is a little scary; what happens when you step through ccall((:initialize_library , lib_crashes_if_inited_twice))? So if you find the problem interesting and have suggestions, I am all ears...

@timholy timholy closed this as completed Feb 7, 2019
@vtjnash
Copy link
Member

vtjnash commented Feb 7, 2019

It does seem explicitly wrong:

julia> Core.Typeof(Vararg)
ERROR: TypeError: in Type, in parameter, expected Type, got Vararg
Stacktrace:
 [1] Typeof(::Any) at ./boot.jl:214
 [2] top-level scope at REPL[1]:1

@vtjnash vtjnash reopened this Feb 7, 2019
@JeffBezanson
Copy link
Member

I guess it should return UnionAll? Or what?

@vtjnash
Copy link
Member

vtjnash commented Feb 7, 2019

Probably. I'm guess that's how it is required to behave?

julia> tt(x::T) where {T} = T
tt (generic function with 1 method)

julia> tt(Vararg)
UnionAll

julia> @which tt(Vararg)
ERROR: TypeError: in Type, in parameter, expected Type, got Vararg
Stacktrace:
 [1] Typeof at ./boot.jl:214 [inlined]
 [2] typesof(::Type) at ./errorshow.jl:164
 [3] top-level scope at REPL[5]:1

@vtjnash
Copy link
Member

vtjnash commented Apr 24, 2019

Although I guess there's also:

julia> f(x::Type{T}) where {T} = T
f (generic function with 1 method)

julia> f(Vararg)
Vararg

Which "proves" that Type{Vararg} is internally also though to be valid.

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 a pull request may close this issue.

3 participants