diff options
Diffstat (limited to 'compiler/semcall.nim')
-rw-r--r-- | compiler/semcall.nim | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 5d77d8325..05bfae0df 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -221,7 +221,7 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors): candidates.add(diag & "\n") if skipped > 0: candidates.add($skipped & " other mismatching symbols have been " & - " suppressed; compile with --showAllMismatches:on to see them\n") + "suppressed; compile with --showAllMismatches:on to see them\n") result = (prefer, candidates) const @@ -288,7 +288,18 @@ proc getMsgDiagnostic(c: PContext, flags: TExprFlags, n, f: PNode): string = let ident = considerQuotedIdent(c, f, n).s if nfDotField in n.flags and nfExplicitCall notin n.flags: - result = errUndeclaredField % ident & result + let sym = n.sons[1].typ.sym + var typeHint = "" + if sym == nil: + # Perhaps we're in a `compiles(foo.bar)` expression, or + # in a concept, eg: + # ExplainedConcept {.explain.} = concept x + # x.foo is int + # We coudl use: `(c.config $ n.sons[1].info)` to get more context. + discard + else: + typeHint = " for type " & getProcHeader(c.config, sym) + result = errUndeclaredField % ident & typeHint & " " & result else: if result.len == 0: result = errUndeclaredRoutine % ident else: result = errBadRoutine % [ident, result] @@ -452,16 +463,23 @@ proc updateDefaultParams(call: PNode) = if nfDefaultRefsParam in def.flags: call.flags.incl nfDefaultRefsParam call[i] = def +proc getCallLineInfo(n: PNode): TLineInfo = + case n.kind + of nkAccQuoted, nkBracketExpr, nkCall, nkCommand: getCallLineInfo(n.sons[0]) + of nkDotExpr: getCallLineInfo(n.sons[1]) + else: n.info + 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) - onUse(n.sons[0].info, finalCallee) + let info = getCallLineInfo(n) + markUsed(c.config, info, finalCallee, c.graph.usageSym) + onUse(info, finalCallee) assert finalCallee.ast != nil if x.hasFauxMatch: result = x.call - result.sons[0] = newSymNode(finalCallee, result.sons[0].info) + result.sons[0] = newSymNode(finalCallee, getCallLineInfo(result.sons[0])) if containsGenericType(result.typ) or x.fauxMatch == tyUnknown: result.typ = newTypeS(x.fauxMatch, c) return @@ -486,7 +504,7 @@ proc semResolvedCall(c: PContext, x: TCandidate, result = x.call instGenericConvertersSons(c, result, x) - result[0] = newSymNode(finalCallee, result[0].info) + result[0] = newSymNode(finalCallee, getCallLineInfo(result[0])) result.typ = finalCallee.typ.sons[0] updateDefaultParams(result) @@ -541,7 +559,7 @@ proc semOverloadedCall(c: PContext, n, nOrig: PNode, notFoundError(c, n, errors) proc explicitGenericInstError(c: PContext; n: PNode): PNode = - localError(c.config, n.info, errCannotInstantiateX % renderTree(n)) + localError(c.config, getCallLineInfo(n), errCannotInstantiateX % renderTree(n)) result = n proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode = @@ -564,9 +582,10 @@ proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode = if tm in {isNone, isConvertible}: return nil var newInst = generateInstance(c, s, m.bindings, n.info) newInst.typ.flags.excl tfUnresolved - markUsed(c.config, n.info, s, c.graph.usageSym) - onUse(n.info, s) - result = newSymNode(newInst, n.info) + let info = getCallLineInfo(n) + markUsed(c.config, info, s, c.graph.usageSym) + onUse(info, s) + result = newSymNode(newInst, info) proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = assert n.kind == nkBracketExpr @@ -583,7 +602,7 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = # number of generic type parameters: if safeLen(s.ast.sons[genericParamsPos]) != n.len-1: let expected = safeLen(s.ast.sons[genericParamsPos]) - localError(c.config, n.info, errGenerated, "cannot instantiate: '" & renderTree(n) & + localError(c.config, getCallLineInfo(n), errGenerated, "cannot instantiate: '" & renderTree(n) & "'; got " & $(n.len-1) & " type(s) but expected " & $expected) return n result = explicitGenericSym(c, n, s) @@ -592,7 +611,7 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = # 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. - result = newNodeI(a.kind, n.info) + result = newNodeI(a.kind, getCallLineInfo(n)) for i in countup(0, len(a)-1): var candidate = a.sons[i].sym if candidate.kind in {skProc, skMethod, skConverter, |