diff options
Diffstat (limited to 'compiler/semcall.nim')
-rw-r--r-- | compiler/semcall.nim | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/compiler/semcall.nim b/compiler/semcall.nim index df99d6c24..67fe99232 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -170,7 +170,7 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors): add(candidates, renderTree(err.sym.ast, {renderNoBody, renderNoComments, renderNoPragmas})) else: - add(candidates, err.sym.getProcHeader(prefer)) + add(candidates, getProcHeader(c.config, err.sym, prefer)) add(candidates, "\n") if err.firstMismatch != 0 and n.len > 1: let cond = n.len > 2 @@ -213,7 +213,7 @@ 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). - if errorOutputs == {}: + if c.config.m.errorOutputs == {}: # fail fast: globalError(c.config, n.info, "type mismatch") if errors.len == 0: @@ -293,7 +293,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode, orig.sons[0..1] = [nil, orig[1], f] template tryOp(x) = - let op = newIdentNode(getIdent(x), n.info) + let op = newIdentNode(getIdent(c.cache, x), n.info) n.sons[0] = op orig.sons[0] = op pickBest(op) @@ -306,17 +306,17 @@ proc resolveOverloads(c: PContext, n, orig: PNode, elif nfDotSetter in n.flags and f.kind == nkIdent and n.len == 3: # we need to strip away the trailing '=' here: - let calleeName = newIdentNode(getIdent(f.ident.s[0..f.ident.s.len-2]), n.info) - let callOp = newIdentNode(getIdent".=", n.info) + let calleeName = newIdentNode(getIdent(c.cache, f.ident.s[0..f.ident.s.len-2]), n.info) + let callOp = newIdentNode(getIdent(c.cache, ".="), n.info) n.sons[0..1] = [callOp, n[1], calleeName] orig.sons[0..1] = [callOp, orig[1], calleeName] pickBest(callOp) if overloadsState == csEmpty and result.state == csEmpty: if nfDotField in n.flags and nfExplicitCall notin n.flags: - localError(c.config, n.info, errUndeclaredField % considerQuotedIdent(c.config, f, n).s) + localError(c.config, n.info, errUndeclaredField % considerQuotedIdent(c, f, n).s) else: - localError(c.config, n.info, errUndeclaredRoutine % considerQuotedIdent(c.config, f, n).s) + localError(c.config, n.info, errUndeclaredRoutine % considerQuotedIdent(c, f, n).s) return elif result.state != csMatch: if nfExprCall in n.flags: @@ -333,7 +333,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode, internalAssert c.config, result.state == csMatch #writeMatches(result) #writeMatches(alt) - if errorOutputs == {}: + if c.config.m.errorOutputs == {}: # quick error message for performance of 'compiles' built-in: globalError(c.config, n.info, errGenerated, "ambiguous call") elif c.config.errorCounter == 0: @@ -345,7 +345,8 @@ proc resolveOverloads(c: PContext, n, orig: PNode, add(args, ")") localError(c.config, n.info, errAmbiguousCallXYZ % [ - getProcHeader(result.calleeSym), getProcHeader(alt.calleeSym), + getProcHeader(c.config, result.calleeSym), + getProcHeader(c.config, alt.calleeSym), args]) proc instGenericConvertersArg*(c: PContext, a: PNode, x: TCandidate) = @@ -390,7 +391,23 @@ proc inferWithMetatype(c: PContext, formal: PType, result = copyTree(arg) result.typ = formal -proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode = +proc updateDefaultParams(call: PNode) = + # In generic procs, the default parameter may be unique for each + # instantiation (see tlateboundgenericparams). + # After a call is resolved, we need to re-assign any default value + # that was used during sigmatch. sigmatch is responsible for marking + # the default params with `nfDefaultParam` and `instantiateProcType` + # computes correctly the default values for each instantiation. + let calleeParams = call[0].sym.typ.n + for i in countdown(call.len - 1, 1): + if nfDefaultParam notin call[i].flags: + return + let def = calleeParams[i].sym.ast + if nfDefaultRefsParam in def.flags: call.flags.incl nfDefaultRefsParam + call[i] = def + +proc semResolvedCall(c: PContext, x: TCandidate, + n: PNode, flags: TExprFlags): PNode = assert x.state == csMatch var finalCallee = x.calleeSym markUsed(c.config, n.sons[0].info, finalCallee, c.graph.usageSym) @@ -423,8 +440,9 @@ proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode = result = x.call instGenericConvertersSons(c, result, x) - result.sons[0] = newSymNode(finalCallee, result.sons[0].info) + result[0] = newSymNode(finalCallee, result[0].info) result.typ = finalCallee.typ.sons[0] + updateDefaultParams(result) proc canDeref(n: PNode): bool {.inline.} = result = n.len >= 2 and (let t = n[1].typ; @@ -446,7 +464,7 @@ proc semOverloadedCall(c: PContext, n, nOrig: PNode, message(c.config, n.info, hintUserRaw, "Non-matching candidates for " & renderTree(n) & "\n" & candidates) - result = semResolvedCall(c, n, r) + result = semResolvedCall(c, r, n, flags) elif implicitDeref in c.features and canDeref(n): # try to deref the first argument and then try overloading resolution again: # @@ -457,7 +475,7 @@ proc semOverloadedCall(c: PContext, n, nOrig: PNode, # n.sons[1] = n.sons[1].tryDeref var r = resolveOverloads(c, n, nOrig, filter, flags, errors, efExplain in flags) - if r.state == csMatch: result = semResolvedCall(c, n, r) + if r.state == csMatch: result = semResolvedCall(c, r, n, flags) else: # get rid of the deref again for a better error message: n.sons[1] = n.sons[1].sons[0] |