Skip to content

Commit db3d297

Browse files
authored
fix #18886 crash on ambiguous proc cast (#20472)
* fix #18886 crash on ambiguous proc cast * follow suggestion
1 parent 0f2775a commit db3d297

File tree

3 files changed

+29
-2
lines changed

3 files changed

+29
-2
lines changed

compiler/lookups.nim

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,17 +488,24 @@ proc errorUseQualifier*(c: PContext; info: TLineInfo; s: PSym) =
488488
var amb: bool
489489
discard errorUseQualifier(c, info, s, amb)
490490

491-
proc errorUseQualifier(c: PContext; info: TLineInfo; candidates: seq[PSym]) =
491+
proc errorUseQualifier(c: PContext; info: TLineInfo; candidates: seq[PSym]; prefix = "use one of") =
492492
var err = "ambiguous identifier: '" & candidates[0].name.s & "'"
493493
var i = 0
494494
for candidate in candidates:
495-
if i == 0: err.add " -- use one of the following:\n"
495+
if i == 0: err.add " -- $1 the following:\n" % prefix
496496
else: err.add "\n"
497497
err.add " " & candidate.owner.name.s & "." & candidate.name.s
498498
err.add ": " & typeToString(candidate.typ)
499499
inc i
500500
localError(c.config, info, errGenerated, err)
501501

502+
proc errorUseQualifier*(c: PContext; info:TLineInfo; choices: PNode) =
503+
var candidates = newSeq[PSym](choices.len)
504+
let prefix = if choices[0].typ.kind != tyProc: "use one of" else: "you need a helper proc to disambiguate"
505+
for i, n in choices:
506+
candidates[i] = n.sym
507+
errorUseQualifier(c, info, candidates, prefix)
508+
502509
proc errorUndeclaredIdentifier*(c: PContext; info: TLineInfo; name: string, extra = "") =
503510
var err = "undeclared identifier: '" & name & "'" & extra
504511
if c.recursiveDep.len > 0:

compiler/semexprs.nim

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,8 @@ proc semCast(c: PContext, n: PNode): PNode =
371371
checkSonsLen(n, 2, c.config)
372372
let targetType = semTypeNode(c, n[0], nil)
373373
let castedExpr = semExprWithType(c, n[1])
374+
if castedExpr.kind == nkClosedSymChoice:
375+
errorUseQualifier(c, n[1].info, castedExpr)
374376
if tfHasMeta in targetType.flags:
375377
localError(c.config, n[0].info, "cannot cast to a non concrete type: '$1'" % $targetType)
376378
if not isCastable(c, targetType, castedExpr.typ, n.info):

tests/errmsgs/t18886.nim

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
discard """
2+
cmd: "nim check --hints:off $file"
3+
errormsg: ""
4+
nimout: '''
5+
t18886.nim(18, 24) Error: ambiguous identifier: 'bar' -- you need a helper proc to disambiguate the following:
6+
t18886.bar: proc (i: ptr int){.noSideEffect, gcsafe, locks: 0.}
7+
t18886.bar: proc (i: ptr char){.noSideEffect, gcsafe, locks: 0.}
8+
'''
9+
"""
10+
11+
type Foo = (proc(_: pointer): void)
12+
13+
14+
proc bar(i: ptr[int]) = discard
15+
proc bar(i: ptr[char]) = discard
16+
17+
18+
let fooBar = cast[Foo](bar)

0 commit comments

Comments
 (0)