# Types in \`:foreigncall\` nodes

**URL:** <https://discourse.julialang.org/t/types-in-foreigncall-nodes/101830>\
**Category:** Internals & Design\
**Tags:** question, compilation\
**Created:** [July 20, 2023, 11:06am UTC](https://discourse.julialang.org/t/types-in-foreigncall-nodes/101830 "2023-07-20T11:06:35Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![willtebbutt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/willtebbutt/32/6790_2.png) [@willtebbutt](https://discourse.julialang.org/u/willtebbutt)\
**Post date:** [July 20, 2023, 11:06am UTC](https://discourse.julialang.org/t/types-in-foreigncall-nodes/101830/1 "2023-07-20T11:06:35Z")

</div>

Consider:

```julia
julia> @code_warntype Base.unsafe_convert(Ptr{Float64}, randn(10))
MethodInstance for Base.unsafe_convert(::Type{Ptr{Float64}}, ::Vector{Float64})
  from unsafe_convert(::Type{Ptr{T}}, a::Array{T}) where T @ Base ~/.julia/juliaup/julia-1.9.2+0.x64.apple.darwin14/share/julia/base/pointer.jl:65
Static Parameters
  T = Float64
Arguments
  #self#::Core.Const(Base.unsafe_convert)
  _::Core.Const(Ptr{Float64})
  a::Vector{Float64}
Body::Ptr{Float64}
1 ─ %1 = $(Expr(:foreigncall, :(:jl_array_ptr), Ptr{T}, svec(Any), 0, :(:ccall), :(a)))::Ptr{Float64}
└── return %1

```

I’m specifically interested in the return type `Ptr{T}`. The presence of this as a single argument to the `:foreigncall` node surprised me, as my (clearly incomplete) mental model of lowered code would have expected something like the following to have been produced during lowering:

```julia
%1 = $(Expr(:static_parameter, 1)
%2 = Core.apply_type(Ptr, %1)
%3 = $(Expr(:foreigncall, :(:jl_array_ptr), %2, svec(Any), 0, :(:ccall), :(a)))

```

Could someone explain why this is lowered in this way, rather than expanded out?

For context, I’m interested because I’m trying to understand how Umlaut.jl might handle `:foreigncall` nodes, how JuliaInterpreter.jl currently handles them, and what the compiler currently does.

---

<div class="post-metadata">

**Author:** ![Keno](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/keno/32/285_2.png) [@Keno](https://discourse.julialang.org/u/Keno)\
**Post date:** [July 20, 2023, 5:53pm UTC](https://discourse.julialang.org/t/types-in-foreigncall-nodes/101830/2 "2023-07-20T17:53:25Z")

</div>

It’s a terrible special case hack where foreigncall is allowed to have something that’s not a type but references the typevars of the method signature by identity. I’ve been wanting to disallow it for the longest time.

---

<div class="post-metadata">

**Author:** ![willtebbutt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/willtebbutt/32/6790_2.png) [@willtebbutt](https://discourse.julialang.org/u/willtebbutt)\
**Post date:** [July 20, 2023, 6:45pm UTC](https://discourse.julialang.org/t/types-in-foreigncall-nodes/101830/3 "2023-07-20T18:45:35Z")

</div>

Good to know – thanks for the context. Were this to change at some point, would you anticipate literally just disallowing this special case and forcing the compiler to expand everything out (akin to what I thought would have happened in this situation), or are there other considerations?
