Skip to content

Compiler bug with @ccall and parametric types #57023

Closed
@mattsignorelli

Description

@mattsignorelli

Following from this discussion on the discourse

A summary of the problem is:

# The following works fine:
mt = MyType{Int32,CTable(16)}() 
# Define convenience ctor:
MyType{T}() where {T} = MyType{T,CTable(16)}()
# This throws a weird error:
MType{Int32}() 

Here is a full minimal working example of the problem:

struct CTable 
  t::Ptr{Float64} 

  function CTable(n)
    # In practice t is received from the C program
    t = @ccall malloc(n::Csize_t)::Ptr{Float64}
    return new(t)
  end
end

mutable struct MyType{T,Table}
  arr::Ptr{T}

  function MyType{T,Table}() where {T,Table}
    arr = @ccall jl_malloc(10::Csize_t)::Ptr{T}
    m = new{T,Table}(arr)
    f(m) = @ccall jl_free(m.arr::Ptr{Cvoid})::Cvoid
    finalizer(f, m)
    return m
  end
end

# The following works fine:
mt = MyType{Int32,CTable(16)}() 

# However this convenience constructor breaks the code:
MyType{T}() where {T} = MyType{T,CTable(16)}()

MyType{Int32}() # Error!!!
#=
ERROR: ccall return type Ptr should have an element type (not Ptr{<:T})
Stacktrace:
 [1] MyType
   @ ./REPL[2]:5 [inlined]
 [2] (MyType{Int32})()
   @ Main ./REPL[4]:1
 [3] top-level scope
   @ REPL[6]:1
=#

Note that this works fine if one of the following:

  1. The type is defined without a second parametric type Table
  2. The "convenience ctor" is fully defined separately without calling the inner ctor
  3. @ccall specifies a return type Ptr{Cvoid}, and then unsafe_converts to Ptr{T}

The underlying problem was then found by @Seelengrab as discussed at the end of the discourse post

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIndicates an unexpected problem or unintended behaviorcompiler:optimizerOptimization passes (mostly in base/compiler/ssair/)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions