diff options
Diffstat (limited to 'compiler/semcall.nim')
-rw-r--r-- | compiler/semcall.nim | 46 |
1 files changed, 34 insertions, 12 deletions
diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 927b23cf2..3971b8ff5 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -1,6 +1,6 @@ # # -# The Nimrod Compiler +# The Nim Compiler # (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this @@ -39,7 +39,7 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode, initialBinding: PNode, filter: TSymKinds, best, alt: var TCandidate, - errors: var seq[string]) = + errors: var CandidateErrors) = var o: TOverloadIter var sym = initOverloadIter(o, c, headSymbol) var symScope = o.lastOverloadScope @@ -58,10 +58,10 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode, z.calleeSym = sym matches(c, n, orig, z) if errors != nil: - errors.safeAdd(getProcHeader(sym)) + errors.safeAdd(sym) if z.errors != nil: for err in z.errors: - errors[errors.len - 1].add("\n " & err) + errors.add(err) if z.state == csMatch: # little hack so that iterators are preferred over everything else: if sym.kind in skIterators: inc(z.exactMatches, 200) @@ -74,7 +74,7 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode, else: discard sym = nextOverloadIter(o, c, headSymbol) -proc notFoundError*(c: PContext, n: PNode, errors: seq[string]) = +proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) = # Gives a detailed error message; this is separated from semOverloadedCall, # as semOverlodedCall is already pretty slow (and we need this information # only in case of an error). @@ -83,18 +83,38 @@ proc notFoundError*(c: PContext, n: PNode, errors: seq[string]) = globalError(n.info, errTypeMismatch, "") if errors.len == 0: localError(n.info, errExprXCannotBeCalled, n[0].renderTree) + + # to avoid confusing errors like: + # got (SslPtr, SocketHandle) + # but expected one of: + # openssl.SSL_set_fd(ssl: SslPtr, fd: SocketHandle): cint + # we do a pre-analysis. If all types produce the same string, we will add + # module information. + let proto = describeArgs(c, n, 1, preferName) + + var prefer = preferName + for err in errors: + var errProto = "" + let n = err.typ.n + for i in countup(1, n.len - 1): + var p = n.sons[i] + if p.kind == nkSym: + add(errProto, typeToString(p.sym.typ, preferName)) + if i != n.len-1: add(errProto, ", ") + # else: ignore internal error as we're already in error handling mode + if errProto == proto: + prefer = preferModuleInfo + break + # now use the information stored in 'prefer' to produce a nice error message: var result = msgKindToString(errTypeMismatch) - add(result, describeArgs(c, n, 1)) + add(result, describeArgs(c, n, 1, prefer)) add(result, ')') - var candidates = "" for err in errors: - add(candidates, err) + add(candidates, err.getProcHeader(prefer)) add(candidates, "\n") - if candidates != "": add(result, "\n" & msgKindToString(errButExpected) & "\n" & candidates) - localError(n.info, errGenerated, result) proc gatherUsedSyms(c: PContext, usedSyms: var seq[PNode]) = @@ -114,7 +134,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode, else: initialBinding = nil - var errors: seq[string] + var errors: CandidateErrors var usedSyms: seq[PNode] template pickBest(headSymbol: expr) = @@ -254,6 +274,7 @@ proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode = assert x.state == csMatch var finalCallee = x.calleeSym markUsed(n.sons[0].info, finalCallee) + styleCheckUse(n.sons[0].info, finalCallee) if finalCallee.ast == nil: internalError(n.info, "calleeSym.ast is nil") # XXX: remove this check! if finalCallee.ast.sons[genericParamsPos].kind != nkEmpty: @@ -286,6 +307,7 @@ proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode = initCandidate(c, m, s, n) var newInst = generateInstance(c, s, m.bindings, n.info) markUsed(n.info, s) + styleCheckUse(n.info, s) result = newSymNode(newInst, n.info) proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = @@ -305,7 +327,7 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = result = explicitGenericSym(c, n, s) elif a.kind in {nkClosedSymChoice, nkOpenSymChoice}: # choose the generic proc with the proper number of type parameters. - # XXX I think this could be improved by reusing sigmatch.ParamTypesMatch. + # XXX I think this could be improved by reusing sigmatch.paramTypesMatch. # It's good enough for now. result = newNodeI(a.kind, n.info) for i in countup(0, len(a)-1): |