CGO Struct used as type parameter causes issue in Go 1.20

237 views
Skip to first unread message

Jan

unread,
Feb 16, 2023, 2:22:34 AM2/16/23
to golang-nuts
hi all,

In a project that requires CGO I wrote a little generic wrapper over my C structs (mostly for debugging):

```
type Wrapper[T any] struct {
P *T
destructor func(p *T)
}
```

And it was working fine. But with go 1.20 I started seeing errors of the type
`cannot use incomplete (or unallocatable) type as a type argument: ...` for all my C structures.

I went back to go 1.19.5 and things work just fine again.

Any thoughts ?

Maybe it's deliberate (but it seems to break compatibility) ? I saw the release note:

"Go 1.20 adds new Incomplete marker type. Code generated by cgo will use cgo.Incomplete to mark an incomplete C type."

But I'm not sure what that entails to my particular code.

Maybe I should use as type parameter the pointer to the C structure and write instead:

```
type Wrapper[T any] struct {
P T
destructor func(p T)
}
```
Any suggestions ?

cheers

Jan Mercl

unread,
Feb 16, 2023, 3:35:09 AM2/16/23
to Jan, golang-nuts
On Thu, Feb 16, 2023 at 8:22 AM Jan <pfe...@gmail.com> wrote:

> Any thoughts ?

A minimal, self-contained and runnable reproducer would be rather
useful in this case.

Jan

unread,
Feb 16, 2023, 5:38:34 AM2/16/23
to golang-nuts
Apologies, actually it was trickier than I thought, the issue happens in not fully defined C types only. So here is an example that runs in go 1.19.5, but fails in go 1.20

```
package main

/*
// Forward reference of C++ types.
struct SomeType;
typedef struct SomeType SomeType;

// Fully defined type.
typedef struct {
char C;
} FullyDefinedType;
*/
import "C"
import (
"fmt"
)


type Wrapper[T any] struct {
P *T
}

type SomeTypeHolder struct {
*Wrapper[C.SomeType]
}

type FullyDefinedTypeHolder struct {
*Wrapper[C.FullyDefinedType]
}

func main() {
//var p *C.SomeType
var x SomeTypeHolder
var y FullyDefinedTypeHolder
fmt.Printf("x.Wrapper=%x\n", x.Wrapper)
fmt.Printf("y.Wrapper=%x\n", y.Wrapper)
}
```

In go 1.19.5 it prints:

$ go run .
x.Wrapper=0
y.Wrapper=0

In go 1.20 it prints:

$ go run .
# ...
./main.go:22:3: cannot use incomplete (or unallocatable) type as a type argument: main._Ctype_struct_SomeType

THanks!

Ian Lance Taylor

unread,
Feb 16, 2023, 6:43:57 PM2/16/23
to Jan, golang-nuts
Giving an error here is https://go.dev/issue/54765. That is, fixing
that issue in 1.20 is what causes this program to not compile.

Ian

Jan Pfeifer

unread,
Feb 16, 2023, 11:33:54 PM2/16/23
to Ian Lance Taylor, golang-nuts
Indeed. 

But it feels like that an incomplete type as type parameter should be ok if we are never instantiating it, and only using pointers to it. From what I see this was not considered in https://go.dev/issue/54765.  

Should this be raised as an issue for 1.21 or a 1.20.1 ? Any thoughts ?


--
Jan Pfeifer
Research Engineer
Google Switzerland GmbH

Ian Lance Taylor

unread,
Feb 17, 2023, 12:07:43 AM2/17/23
to Jan Pfeifer, golang-nuts
On Thu, Feb 16, 2023 at 8:33 PM Jan Pfeifer <pfe...@gmail.com> wrote:
>
> Indeed.
>
> But it feels like that an incomplete type as type parameter should be ok if we are never instantiating it, and only using pointers to it. From what I see this was not considered in https://go.dev/issue/54765.
>
> Should this be raised as an issue for 1.21 or a 1.20.1 ? Any thoughts ?

I think it's very subtle to ensure that the type is only being used in
acceptable ways. I'd rather not attempt to do that unless it is very
important to be able to use that kind of type argument.

Ian
Reply all
Reply to author
Forward
0 new messages