diff options
Diffstat (limited to 'rod/semcall.nim')
-rw-r--r-- | rod/semcall.nim | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/rod/semcall.nim b/rod/semcall.nim index 1b31558ca..294c0399b 100644 --- a/rod/semcall.nim +++ b/rod/semcall.nim @@ -79,20 +79,42 @@ proc semDirectCall(c: PContext, n: PNode, filter: TSymKinds): PNode = initialBinding = nil result = semDirectCallWithBinding(c, n, f, filter, initialBinding) -proc explictGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = +proc explicitGenericInstError(n: PNode): PNode = + LocalError(n.info, errCannotInstantiateX, renderTree(n)) + result = n + +proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = assert n.kind == nkBracketExpr for i in 1..sonsLen(n)-1: n.sons[i].typ = semTypeNode(c, n.sons[i], nil) - # we cannot check for the proper number of type parameters because in - # `f[a,b](x, y)` `f` is not resolved yet properly. - # XXX: BUG this should be checked somehow! - assert n.sons[0].kind == nkSym + var s = s + var a = n.sons[0] + if a.kind == nkSym: + # common case; check the only candidate has the right + # number of generic type parameters: + if safeLen(s.ast.sons[genericParamsPos]) != n.len-1: + return explicitGenericInstError(n) + elif a.kind == nkSymChoice: + # choose the generic proc with the proper number of type parameters. + # XXX I think this could be improved by reusing sigmatch.ParamTypesMatch. + # It's good enough for now. + var candidateCount = 0 + for i in countup(0, len(a)-1): + var candidate = a.sons[i].sym + if candidate.kind in {skProc, skMethod, skConverter, skIterator}: + # if suffices that the candidate has the proper number of generic + # type parameters: + if safeLen(candidate.ast.sons[genericParamsPos]) == n.len-1: + s = candidate + inc(candidateCount) + if candidateCount != 1: return explicitGenericInstError(n) + else: + assert false var x: TCandidate initCandidate(x, s, n) var newInst = generateInstance(c, s, x.bindings, n.info) markUsed(n, s) - result = newSymNode(newInst) - result.info = n.info + result = newSymNode(newInst, n.info) |