Detailed explanation:
type FooFunc = proc(x: int)
echo FooFunc is proc(x: int) {.closure.} # true
proc foo(x: int) = echo "It works OK!!!"
echo foo is proc(x: int) {.nimcall.} # true
# Type of foo proc is different from FooFunc type as FooFunc is closure but
foo is nimcall.
echo foo is FooFunc # false
echo proc(x: int) is proc(x: int) {.nimcall.} # false
# They are different types but nimcall proc can be assigned to closure proc.
var
p: proc(x: int) {.closure.}
q: proc(x: int) {.nimcall.} = foo
p = q
p(1)
type
SomeGenericObj[T] = object
var
a, b: SomeGenericObj[proc(x:int){.closure.}]
x: SomeGenericObj[proc(x: int){.nimcall.}]
a = b
# Both assignments result in compile error because typeof(a) and typeof(x)
are different
#x = a
#a = x
var
c: int
d: int16
# int16 is implicity converted to int
c = d
var
i: SomeGenericObj[int]
j: SomeGenericObj[int16]
# i and j are different types and you cannot assign j to i.
#i = j
# If you want to assign one generic type value to another generic type
variable even if generic parameters are different.
type
ImplicitlyConvertible[T] = object
proc `<=`[T, U](a: var ImplicitlyConvertible[T]; b:
ImplicitlyConvertible[U]) =
when(compiles((var x: T; var y: U; x = y))):
discard
else:
{.error: "Wrong assignment".}
block:
var
a, b: ImplicitlyConvertible[proc(x:int){.closure.}]
x: ImplicitlyConvertible[proc(x: int){.nimcall.}]
a <= b
a <= x
# Compile error
#x <= a
var
i: ImplicitlyConvertible[int]
j: ImplicitlyConvertible[int16]
i <= j
#j <= i
Run