## Issue

Given these type definitions:

```
type N interface{ ~int | ~float32 | ~float64 }
type S[T any] struct {
t T
}
type myInt int
type pSpMyInt[T myInt] *S[*T]
type spMyInt[T *myInt,] S[T]
type spMyInt2[T myInt] S[*T]
```

I can create a var of `type pSpMyInt`

with

```
func createPS[T myInt]() pSpMyInt[T] {
var i T
s := S[*T]{t: &i}
return &s
}
```

But I can not figure out how to create vars of `spMyInt`

or `spMyInt2`

.

This

```
func createSP[T myInt]() spMyInt2[T] {
var i T
s := S[*T]{t: &i}
return s
}
```

fails to compile

`cannot use s (variable of type S[*T]) as type spMyInt2[T] in return statement`

.

## Solution

First of all, *do NOT use exact type parameter constraints*. It almost never makes sense. When you declare a function as `createPS[T myInt]()`

, the type parameter type set has cardinality 1, so it can effectively be instantiated **only** and **ever** by `myInt`

. You could rewrite the function like the following just as fine:

```
func createPS() pSpMyInt[myInt] {
var i myInt
s := S[*myInt]{t: &i}
return &s
}
```

With that out of the way:

The type `S[*T]`

**is just not the same** as `spMyInt2[T]`

. However, since `spMyInt2[T]`

‘s underlying type is `S[*T]`

, you can simply convert:

```
func createSP2[T myInt]() spMyInt2[T] {
var i T
s := S[*T]{t: &i}
return spMyInt2[T](s) // conversion
}
```

As for `type spMyInt[T *myInt,] S[T]`

(where the comma is not a typo but is needed to avoid a parsing ambiguity), the thing isn’t that simple.

The problem is that a type parameter **is not** its type constraint. Therefore type literals can’t be used to instantiate different unnamed type literals. To be clear:

```
// naive attempt that doesn't compile
func createSP1[T myInt]() spMyInt[*T] {
var i T
s := S[*T]{t: &i}
return spMyInt[*T](s)
}
```

You might think that `spMyInt[T *myInt]`

has a type parameter constrained to `*myInt`

and the function `T`

is constrained by the base type `myInt`

, *therefore* `*T`

should satisfy `T *myInt`

. This is not correct for the apparently unobvious reason that the type literal `*T`

is not equivalent to `*myInt`

. So actually you can’t write a generic constructor for `type spMyInt[T *myInt,] S[T]`

.

However you are in luck because the type constraint had cardinality one. So you can just remove the type parameter:

```
func createSP1() spMyInt[*myInt] {
var i myInt
s := S[*myInt]{t: &i}
return spMyInt[*myInt](s)
}
```

Answered By – blackgreen

Answer Checked By – Terry (GoLangFix Volunteer)