Skip to content

Error within compiler/typeinfer.jl (from UB?) #56796

@tecosaur

Description

@tecosaur

Last night I made a type-stable Memoize.jl via a @generated function.

Along the way, I tried something that may well be considered undefined behavior, but was surprised to see a compiler/typeinfer.jl typeassert error regardless.

julia> @generated function ohnoes(::F, args...) where {F <: Function}
       Core.Compiler.return_type(F.instance, Tuple{args...}, Base.get_world_counter())
       end
ohnoes (generic function with 1 method)

julia> ohnoes(sum, [1,2,3])
ERROR: TypeError: in typeassert, expected Vector, got a value of type Nothing
Stacktrace:
 [1] return_type(interp::Core.Compiler.NativeInterpreter, t::DataType)
   @ Core.Compiler ./compiler/typeinfer.jl:1187
 [2] return_type(t::DataType, world::UInt64)
   @ Core.Compiler ./compiler/typeinfer.jl:1175
 [3] return_type(f::Any, t::DataType, world::UInt64)
   @ Core.Compiler ./compiler/typeinfer.jl:1165
 [4] #s1#11
   @ ./REPL[40]:2 [inlined]
 [5] var"#s1#11"(F::Any, ::Any, ::Any, args::Any)
   @ Main ./none:0
 [6] (::Core.GeneratedFunctionStub)(::UInt64, ::LineNumberNode, ::Any, ::Vararg{Any})
   @ Core ./boot.jl:707
 [7] top-level scope
   @ REPL[41]:1

I'm aware that doing word-age stuff within a @generated function is very much not-blessed (not sure if it's explicitly UB from the docs though), but I'm still surprised to see a typeassert error from the compiler.

If there's an invariant the compiler is assuming, I would have thought it would be explicitly checked for, rather than hitting a typeassert at some point.

The line in question is a _methods_by_ftype call, which ends up ccall-ing jl_matching_methods. The ccall itself is typed to return a Union{Vector{Any},Nothing}, but in 10 places (mostly reflection.jl, also bootstrap.jl and typeinfer.jl) a _methods_by_ftype call is asserted to be a Vector, discarding the Nothing case.

Perhaps there's something here that should be more explicitly checked for/errored?

Metadata

Metadata

Assignees

No one assigned

    Labels

    compiler:inferenceType inferencedocsThis change adds or pertains to documentationerror messagesBetter, more actionable error messagesobservabilitymetrics, timing, understandability, reflection, logging, ...

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions