diff --git a/compiler/lookups.nim b/compiler/lookups.nim index 0e576d765bcd..2a48f63491e5 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -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 diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 06dd09b69f11..b81bc2a63898 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -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 @@ -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 @@ -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: diff --git a/tests/enum/tpure_enums_conflict.nim b/tests/enum/tpure_enums_conflict.nim index 4411fd2a618d..3cf335440756 100644 --- a/tests/enum/tpure_enums_conflict.nim +++ b/tests/enum/tpure_enums_conflict.nim @@ -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 @@ -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]# diff --git a/tests/enum/tpure_enums_conflict_legacy.nim b/tests/enum/tpure_enums_conflict_legacy.nim new file mode 100644 index 000000000000..e592925bc7b9 --- /dev/null +++ b/tests/enum/tpure_enums_conflict_legacy.nim @@ -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 +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]# diff --git a/tests/errmsgs/mambparam1.nim b/tests/errmsgs/mambparam1.nim new file mode 100644 index 000000000000..1a5133c3cb9b --- /dev/null +++ b/tests/errmsgs/mambparam1.nim @@ -0,0 +1 @@ +const test* = "foo" diff --git a/tests/errmsgs/mambparam2.nim b/tests/errmsgs/mambparam2.nim new file mode 100644 index 000000000000..073e3f8c8a33 --- /dev/null +++ b/tests/errmsgs/mambparam2.nim @@ -0,0 +1,2 @@ +import mambparam1 +export test diff --git a/tests/errmsgs/mambparam3.nim b/tests/errmsgs/mambparam3.nim new file mode 100644 index 000000000000..5469244e2c7f --- /dev/null +++ b/tests/errmsgs/mambparam3.nim @@ -0,0 +1 @@ +const test* = "bar" diff --git a/tests/errmsgs/tambparam.nim b/tests/errmsgs/tambparam.nim new file mode 100644 index 000000000000..5b56a3fced7c --- /dev/null +++ b/tests/errmsgs/tambparam.nim @@ -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]# diff --git a/tests/errmsgs/tambparam_legacy.nim b/tests/errmsgs/tambparam_legacy.nim new file mode 100644 index 000000000000..bd99a3aac0c1 --- /dev/null +++ b/tests/errmsgs/tambparam_legacy.nim @@ -0,0 +1,14 @@ +import mambparam2, mambparam3 + +echo test #[tt.Error +^ type mismatch: got +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]#