Skip to content

Commit

Permalink
show symchoices as ambiguous in overload type mismatches
Browse files Browse the repository at this point in the history
  • Loading branch information
metagn committed Sep 9, 2024
1 parent 79a65da commit 2dad9a8
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 13 deletions.
28 changes: 19 additions & 9 deletions compiler/lookups.nim
Original file line number Diff line number Diff line change
Expand Up @@ -563,23 +563,33 @@ proc errorUseQualifier*(c: PContext; info: TLineInfo; s: PSym) =
var amb: bool = false
discard errorUseQualifier(c, info, s, amb)

proc errorUseQualifier*(c: PContext; info: TLineInfo; candidates: seq[PSym]; prefix = "use one of") =
var err = "ambiguous identifier: '" & candidates[0].name.s & "'"
proc ambiguousIdentifierMsg*(candidates: seq[PSym], prefix = "use one of", indent = 0): string =
result = ""
for i in 0 ..< indent:
result.add(' ')
result.add "ambiguous identifier: '" & candidates[0].name.s & "'"
var i = 0
for candidate in candidates:
if i == 0: err.add " -- $1 the following:\n" % prefix
else: err.add "\n"
err.add " " & candidate.owner.name.s & "." & candidate.name.s
err.add ": " & typeToString(candidate.typ)
if i == 0: result.add " -- $1 the following:\n" % prefix
else: result.add "\n"
for i in 0 ..< indent:
result.add(' ')
result.add " " & candidate.owner.name.s & "." & candidate.name.s
result.add ": " & typeToString(candidate.typ)
inc i
localError(c.config, info, errGenerated, err)

proc errorUseQualifier*(c: PContext; info:TLineInfo; choices: PNode) =
proc errorUseQualifier*(c: PContext; info: TLineInfo; candidates: seq[PSym]) =
localError(c.config, info, errGenerated, ambiguousIdentifierMsg(candidates))

proc ambiguousIdentifierMsg*(choices: PNode, indent = 0): string =
var candidates = newSeq[PSym](choices.len)
let prefix = if choices[0].typ.kind != tyProc: "use one of" else: "you need a helper proc to disambiguate"
for i, n in choices:
candidates[i] = n.sym
errorUseQualifier(c, info, candidates, prefix)
result = ambiguousIdentifierMsg(candidates, prefix, indent)

proc errorUseQualifier*(c: PContext; info:TLineInfo; choices: PNode) =
localError(c.config, info, errGenerated, ambiguousIdentifierMsg(choices))

proc errorUndeclaredIdentifier*(c: PContext; info: TLineInfo; name: string, extra = "") =
var err: string
Expand Down
8 changes: 8 additions & 0 deletions compiler/semcall.nim
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,8 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors):
candidates.add "\n"
of kTypeMismatch:
doAssert nArg != nil
if nArg.kind in nkSymChoices:
candidates.add ambiguousIdentifierMsg(nArg, indent = 2)
let wanted = err.firstMismatch.formal.typ
doAssert err.firstMismatch.formal != nil
doAssert wanted != nil
Expand Down Expand Up @@ -317,6 +319,9 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors):
candidates.add renderTree(arg)
candidates.add "' of type: "
candidates.addTypeDeclVerboseMaybe(c.config, got)
if nArg.kind in nkSymChoices:
candidates.add "\n"
candidates.add ambiguousIdentifierMsg(nArg, indent = 2)
if got != nil and got.kind == tyProc and wanted.kind == tyProc:
# These are proc mismatches so,
# add the extra explict detail of the mismatch
Expand Down Expand Up @@ -370,6 +375,9 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors):
candidates.add "' is of type: "
let got = arg.typ
candidates.addTypeDeclVerboseMaybe(c.config, got)
if arg.kind in nkSymChoices:
candidates.add "\n"
candidates.add ambiguousIdentifierMsg(arg, indent = 2)
doAssert wanted != nil
if got != nil:
if got.kind == tyProc and wanted.kind == tyProc:
Expand Down
15 changes: 11 additions & 4 deletions tests/enum/tpure_enums_conflict.nim
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
discard """
disabled: true # pure enums behave like overloaded enums on ambiguity now which gives a different error message
errormsg: "ambiguous identifier: 'amb'"
line: 19
matrix: "-d:testsConciseTypeMismatch"
"""

# bug #8066
Expand All @@ -17,4 +15,13 @@ when true:

echo valueA # MyEnum.valueA
echo MyEnum.amb # OK.
echo amb # Error: Unclear whether it's MyEnum.amb or OtherEnum.amb
echo amb #[tt.Error
^ type mismatch
Expression: echo amb
[1] amb: MyEnum | OtherEnum
Expected one of (first mismatch at [position]):
[1] proc echo(x: varargs[typed, `$$`])
ambiguous identifier: 'amb' -- use one of the following:
MyEnum.amb: MyEnum
OtherEnum.amb: OtherEnum]#
25 changes: 25 additions & 0 deletions tests/enum/tpure_enums_conflict_legacy.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# bug #8066

when true:
type
MyEnum {.pure.} = enum
valueA, valueB, valueC, valueD, amb

OtherEnum {.pure.} = enum
valueX, valueY, valueZ, amb


echo valueA # MyEnum.valueA
echo MyEnum.amb # OK.
echo amb #[tt.Error
^ type mismatch: got <MyEnum | OtherEnum>
but expected one of:
proc echo(x: varargs[typed, `$$`])
first type mismatch at position: 1
required type for x: varargs[typed]
but expression 'amb' is of type: None
ambiguous identifier: 'amb' -- use one of the following:
MyEnum.amb: MyEnum
OtherEnum.amb: OtherEnum
expression: echo amb]#
1 change: 1 addition & 0 deletions tests/errmsgs/mambparam1.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
const test* = "foo"
2 changes: 2 additions & 0 deletions tests/errmsgs/mambparam2.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import mambparam1
export test
1 change: 1 addition & 0 deletions tests/errmsgs/mambparam3.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
const test* = "bar"
16 changes: 16 additions & 0 deletions tests/errmsgs/tambparam.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
discard """
matrix: "-d:testsConciseTypeMismatch"
"""

import mambparam2, mambparam3

echo test #[tt.Error
^ type mismatch
Expression: echo test
[1] test: string | string
Expected one of (first mismatch at [position]):
[1] proc echo(x: varargs[typed, `$$`])
ambiguous identifier: 'test' -- use one of the following:
mambparam1.test: string
mambparam3.test: string]#
14 changes: 14 additions & 0 deletions tests/errmsgs/tambparam_legacy.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import mambparam2, mambparam3

echo test #[tt.Error
^ type mismatch: got <string | string>
but expected one of:
proc echo(x: varargs[typed, `$$`])
first type mismatch at position: 1
required type for x: varargs[typed]
but expression 'test' is of type: None
ambiguous identifier: 'test' -- use one of the following:
mambparam1.test: string
mambparam3.test: string
expression: echo test]#

0 comments on commit 2dad9a8

Please sign in to comment.