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?

Reply via email to