Skip to content

Hard-coded Tuple(...) abstract inference result is unsound #56121

Open
@topolarity

Description

@topolarity

Noticed by @vtjnash in https://github.com/JuliaLang/julia/pull/56034/files#r1795500285

struct Foo end
Base.Tuple(x::Foo) = x
foo() = Tuple(Core.compilerbarrier(:type, Foo())::Union{Foo,Int64})

code_typed reports a return type of Tuple:

julia> code_typed(foo, ())
1-element Vector{Any}:
 CodeInfo(
1 ─ %1 = Core.compilerbarrier(:type, $(QuoteNode(Foo())))::Any
│        Core.typeassert(%1, Union{Foo, Int64})::Union{Foo, Int64}
│   %3 = π (%1, Union{Foo, Int64})
│   %4 = Main.Tuple(%3)::Tuple
└──      return %4
) => Tuple

but it's wrong:

julia> typeof(foo())
Foo

due to the hard-coded return type in:

elseif f === Tuple && la == 2
aty = argtypes[2]
ty = isvarargtype(aty) ? unwrapva(aty) : widenconst(aty)
if !isconcretetype(ty)
return Future(CallMeta(Tuple, Any, EFFECTS_UNKNOWN, NoCallInfo()))
end

The NoCallInfo also seems to have the unfortunate side-effect of blocking inlining for any user-declared functions of this kind (if the call is abstract)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIndicates an unexpected problem or unintended behaviorcompiler:inferenceType inference

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions