Values of two different defined pointer types may be indirectly converted to each other's type if the base types of the two types shares the same underlying type

Generally, the values of two pointer types may not be converted to each other if the underlying types of the two pointer types are different. For example, the 4 conversions in the following code are all illegal.

package main

type MyInt int
type IntPtr *int     // underlying type is *int
type MyIntPtr *MyInt // underlying type is *MyInt

func main() {
	var x IntPtr
	var y MyIntPtr
	x = IntPtr(y)       // error
	y = MyIntPtr(x)     // error
	var _ = (*int)(y)   // error
	var _ = (*MyInt)(x) // error
}

Although the above 4 conversions may not achieved directly, they may be achieved indirectly. This benefits from the fact that the following conversions are legal.

package main

type MyInt int

func main() {
	var x *int
	var y *MyInt
	x = (*int)(y)   // okay
	y = (*MyInt)(x) // okay
}

The reason why the above two conversions are legal is values of two non-defined (unnamed) pointers types may be converted to each other's type if the base types of the two types shares the same underlying type. In the above example, the base types of the types of x and y are int and MyInt, which share the same underlying type int, so x and y may be converted to each other's type.

Benefiting from the just mentioned fact, values of IntPtr and MyIntPtr may be also converted to each other's type, though such conversions must be indirectly, as shown in the following code.

package main 

type MyInt int
type IntPtr *int
type MyIntPtr *MyInt

func main() {
	var x IntPtr
	var y MyIntPtr
	x = IntPtr((*int)((*MyInt)(y)))     // okay
	y = MyIntPtr(((*MyInt))((*int)(x))) // okay
	var _ = (*int)((*MyInt)(y))         // okay
	var _ = (*MyInt)((*int)(x))         // okay
}