So I ran into a funny problem today. Let me to illustrate with a contrived example: {.experimental.} type Vec2 = tuple[x, y: float] Kinetic = concept g g.pos is Vec2 g.vel is Vec2 IKinetic = object converter conToInter[T: Kinetic](x: var T): IKinetic = IKinetic() template `.`(x: IKinetic; field: untyped): untyped = 123 conToInter(5)
This seems to throw the compiler into an infinite loop (until it gives up). Here's my understanding of what's happening: the `conToInter` call triggers the `Kinetic` concept checks, which use the dot operator, so the compiler tries to find an applicable `.` implementation. In doing so, it runs into the one taking an `IKinetic`, so now it has to check if there's an applicable conversion, which leads it back to `conToInter`, triggering the concept checks again. The obvious way to fix this is to avoid the dot operator inside the concept body (which I don't mind, as it generates ugly and unhelpful errors when the checks fail), but what should I use instead? I suppose I could search the type's AST representation, but that seems like a slow and fragile way to do it. Are there any alternatives?