@zahary I don't say that this is a perfect solution, but it catches some cases:
we could rerun the concept's body several times. Something like this:
if (this concept has no generics):
return check(body) #only once
else:
saved = snapshot(generics) # at this point K and V are metatypes, they
can be anything
if not check(body):
return false
# at this point K=int, V=int
while not (all types are defined in generics) and saved !=
snapshot(generics):
saved = snapshot(generics)
if not check(body):
return false
if not (all types are defined in generics):
return false # we don't let unbounded types, so I'll be happy
return check(body) # extra check at the end after all types are exactly
defined (in the example this fails with K=int, V=int)
The inner `while` loop is there, so it can resolve concepts where the order of
the expressions is mixed, e.g.,
type Abc[T,S] = concept c
T is S
S is int
and the `saved` variable is presented to prevent infinite loop.