diff options
author | Timothee Cour <timothee.cour2@gmail.com> | 2018-10-13 16:16:04 -0700 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-10-14 01:16:04 +0200 |
commit | eb946f37a7c56fb64703357a67ed098ac8dfd936 (patch) | |
tree | 87c87454fad5a77a13b8db7d05a37222bdb030ec | |
parent | 8232bd04f9edc4b3accb114c9bd6e60190b68396 (diff) | |
download | Nim-eb946f37a7c56fb64703357a67ed098ac8dfd936.tar.gz |
fixes #8671; show helpful msg (lookup symbol, eg iterator) on 'attempting to call undeclared routine' error (#8786)
-rw-r--r-- | compiler/semcall.nim | 32 | ||||
-rw-r--r-- | tests/enum/tenumitems.nim | 2 | ||||
-rw-r--r-- | tests/errmsgs/undeclared_routime.nim | 13 | ||||
-rw-r--r-- | tests/errmsgs/undeclared_routime2.nim | 9 | ||||
-rw-r--r-- | tests/errmsgs/undeclared_routime3.nim | 13 | ||||
-rw-r--r-- | tests/errmsgs/undeclared_routime4.nim | 10 | ||||
-rw-r--r-- | tests/errmsgs/undeclared_routime5.nim | 9 | ||||
-rw-r--r-- | tests/errmsgs/undeclared_routime_compiles.nim | 11 | ||||
-rw-r--r-- | tests/misc/tissue710.nim | 2 | ||||
-rw-r--r-- | tests/misc/tnoop.nim | 7 |
10 files changed, 98 insertions, 10 deletions
diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 71a9197b7..61d6113dc 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -224,6 +224,7 @@ const errButExpected = "but expected one of: " errUndeclaredField = "undeclared field: '$1'" errUndeclaredRoutine = "attempting to call undeclared routine: '$1'" + errBadRoutine = "attempting to call routine: '$1'$2" errAmbiguousCallXYZ = "ambiguous call; both $1 and $2 match for: $3" proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) = @@ -262,6 +263,30 @@ proc bracketNotFoundError(c: PContext; n: PNode) = else: notFoundError(c, n, errors) +proc getMsgDiagnostic(c: PContext, flags: TExprFlags, n, f: PNode): string = + if c.compilesContextId > 0: + # we avoid running more diagnostic when inside a `compiles(expr)`, to + # errors while running diagnostic (see test D20180828T234921), and + # also avoid slowdowns in evaluating `compiles(expr)`. + discard + else: + var o: TOverloadIter + var sym = initOverloadIter(o, c, f) + while sym != nil: + proc toHumanStr(kind: TSymKind): string = + result = $kind + assert result.startsWith "sk" + result = result[2..^1].toLowerAscii + result &= "\n found '$1' of kind '$2'" % [getSymRepr(c.config, sym), sym.kind.toHumanStr] + sym = nextOverloadIter(o, c, n) + + let ident = considerQuotedIdent(c, f, n).s + if nfDotField in n.flags and nfExplicitCall notin n.flags: + result = errUndeclaredField % ident & result + else: + if result.len == 0: result = errUndeclaredRoutine % ident + else: result = errBadRoutine % [ident, result] + proc resolveOverloads(c: PContext, n, orig: PNode, filter: TSymKinds, flags: TExprFlags, errors: var CandidateErrors, @@ -330,11 +355,8 @@ proc resolveOverloads(c: PContext, n, orig: PNode, pickBest(callOp) if overloadsState == csEmpty and result.state == csEmpty: - if efNoUndeclared notin flags: - if nfDotField in n.flags and nfExplicitCall notin n.flags: - localError(c.config, n.info, errUndeclaredField % considerQuotedIdent(c, f, n).s) - else: - localError(c.config, n.info, errUndeclaredRoutine % considerQuotedIdent(c, f, n).s) + if efNoUndeclared notin flags: # for tests/pragmas/tcustom_pragma.nim + localError(c.config, n.info, getMsgDiagnostic(c, flags, n, f)) return elif result.state != csMatch: if nfExprCall in n.flags: diff --git a/tests/enum/tenumitems.nim b/tests/enum/tenumitems.nim index 38233aad7..6d13dd162 100644 --- a/tests/enum/tenumitems.nim +++ b/tests/enum/tenumitems.nim @@ -1,6 +1,6 @@ discard """ line: 7 - errormsg: "attempting to call undeclared routine: 'items'" + errormsg: "attempting to call routine: 'items'" """ type a = enum b,c,d diff --git a/tests/errmsgs/undeclared_routime.nim b/tests/errmsgs/undeclared_routime.nim new file mode 100644 index 000000000..426507652 --- /dev/null +++ b/tests/errmsgs/undeclared_routime.nim @@ -0,0 +1,13 @@ +discard """ +cmd: '''nim c --hints:off $file''' +errormsg: "attempting to call routine: 'myiter'" +nimout: '''undeclared_routime.nim(13, 15) Error: attempting to call routine: 'myiter' + found 'undeclared_routime.myiter(a: string)[declared in undeclared_routime.nim(10, 9)]' of kind 'iterator' + found 'undeclared_routime.myiter()[declared in undeclared_routime.nim(11, 9)]' of kind 'iterator' +''' +""" + +iterator myiter(a:string): int = discard +iterator myiter(): int = discard + +let a = myiter(1) diff --git a/tests/errmsgs/undeclared_routime2.nim b/tests/errmsgs/undeclared_routime2.nim new file mode 100644 index 000000000..3e48b48f4 --- /dev/null +++ b/tests/errmsgs/undeclared_routime2.nim @@ -0,0 +1,9 @@ +discard """ +cmd: '''nim c --hints:off $file''' +errormsg: "invalid pragma: myPragma" +""" + +proc myPragma():int=discard +iterator myPragma():int=discard +proc myfun(a:int): int {.myPragma.} = 1 +let a = myfun(1) diff --git a/tests/errmsgs/undeclared_routime3.nim b/tests/errmsgs/undeclared_routime3.nim new file mode 100644 index 000000000..052adfc08 --- /dev/null +++ b/tests/errmsgs/undeclared_routime3.nim @@ -0,0 +1,13 @@ +discard """ +cmd: '''nim c --hints:off $file''' +errormsg: "undeclared field: 'bar'" +nimout: '''undeclared_routime3.nim(13, 10) Error: undeclared field: 'bar' + found 'undeclared_routime3.bar()[declared in undeclared_routime3.nim(12, 9)]' of kind 'iterator' +''' +""" + + +type Foo = object +var a = Foo() +iterator bar():int=discard +let a = a.bar diff --git a/tests/errmsgs/undeclared_routime4.nim b/tests/errmsgs/undeclared_routime4.nim new file mode 100644 index 000000000..674caa421 --- /dev/null +++ b/tests/errmsgs/undeclared_routime4.nim @@ -0,0 +1,10 @@ +discard """ +cmd: '''nim c --hints:off $file''' +errormsg: "undeclared field: 'bar'" +nimout: '''undeclared_routime4.nim(10, 10) Error: undeclared field: 'bar' +''' +""" + +type Foo = object +var a = Foo() +let a = a.bar diff --git a/tests/errmsgs/undeclared_routime5.nim b/tests/errmsgs/undeclared_routime5.nim new file mode 100644 index 000000000..4394134ab --- /dev/null +++ b/tests/errmsgs/undeclared_routime5.nim @@ -0,0 +1,9 @@ +discard """ +cmd: '''nim c --hints:off $file''' +errormsg: "undeclared identifier: 'myfun'" +nimout: '''undeclared_routime5.nim(9, 9) Error: undeclared identifier: 'myfun' +''' +""" + + +let a = myfun(1) diff --git a/tests/errmsgs/undeclared_routime_compiles.nim b/tests/errmsgs/undeclared_routime_compiles.nim new file mode 100644 index 000000000..21daf82bf --- /dev/null +++ b/tests/errmsgs/undeclared_routime_compiles.nim @@ -0,0 +1,11 @@ +# D20180828T234921:here +template foo*(iter: untyped): untyped = + when compiles(iter.unexistingField): 0 + elif compiles(iter.len): 1 + else: 2 + +proc foo[A]()= + let a2 = @[10, 11] + let a3 = foo(pairs(a2)) + +foo[int]() diff --git a/tests/misc/tissue710.nim b/tests/misc/tissue710.nim index 3b6d3e5f3..e2cca0024 100644 --- a/tests/misc/tissue710.nim +++ b/tests/misc/tissue710.nim @@ -1,7 +1,7 @@ discard """ file: "tissue710.nim" line: 8 - errorMsg: "attempting to call undeclared routine: '||'" + errorMsg: "attempting to call routine: '||'" """ var sum = 0 for x in 3..1000: diff --git a/tests/misc/tnoop.nim b/tests/misc/tnoop.nim index 1e3fbe6cf..e1e25b44e 100644 --- a/tests/misc/tnoop.nim +++ b/tests/misc/tnoop.nim @@ -1,10 +1,11 @@ discard """ + nimout: ''' + found 'a' of kind 'var'''' file: "tnoop.nim" - line: 11 - errormsg: "attempting to call undeclared routine: 'a'" + line: 12 + errormsg: "attempting to call routine: 'a'" """ - var a: int |