improve the error messages regarding type mismatches in overloading resolution
This commit is contained in:
parent
b4eff82e62
commit
326b7dc556
4 changed files with 74 additions and 11 deletions
|
|
@ -106,6 +106,7 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode,
|
||||||
errors.safeAdd(CandidateError(
|
errors.safeAdd(CandidateError(
|
||||||
sym: sym,
|
sym: sym,
|
||||||
unmatchedVarParam: int z.mutabilityProblem,
|
unmatchedVarParam: int z.mutabilityProblem,
|
||||||
|
firstMismatch: z.firstMismatch,
|
||||||
diagnostics: z.diagnostics))
|
diagnostics: z.diagnostics))
|
||||||
else:
|
else:
|
||||||
# Symbol table has been modified. Restart and pre-calculate all syms
|
# Symbol table has been modified. Restart and pre-calculate all syms
|
||||||
|
|
@ -154,7 +155,20 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors):
|
||||||
else:
|
else:
|
||||||
add(candidates, err.sym.getProcHeader(prefer))
|
add(candidates, err.sym.getProcHeader(prefer))
|
||||||
add(candidates, "\n")
|
add(candidates, "\n")
|
||||||
if err.unmatchedVarParam != 0 and err.unmatchedVarParam < n.len:
|
if err.firstMismatch != 0 and n.len > 2:
|
||||||
|
add(candidates, "first type mismatch at position: " & $err.firstMismatch &
|
||||||
|
"\nrequired type: ")
|
||||||
|
if err.firstMismatch < err.sym.typ.len:
|
||||||
|
candidates.add typeToString(err.sym.typ.sons[err.firstMismatch])
|
||||||
|
else:
|
||||||
|
candidates.add "none"
|
||||||
|
if err.firstMismatch < n.len:
|
||||||
|
candidates.add "\nbut expression '"
|
||||||
|
candidates.add renderTree(n[err.firstMismatch])
|
||||||
|
candidates.add "' is of type: "
|
||||||
|
candidates.add typeToString(n[err.firstMismatch].typ)
|
||||||
|
candidates.add "\n"
|
||||||
|
elif err.unmatchedVarParam != 0 and err.unmatchedVarParam < n.len:
|
||||||
add(candidates, "for a 'var' type a variable needs to be passed, but '" &
|
add(candidates, "for a 'var' type a variable needs to be passed, but '" &
|
||||||
renderTree(n[err.unmatchedVarParam]) & "' is immutable\n")
|
renderTree(n[err.unmatchedVarParam]) & "' is immutable\n")
|
||||||
for diag in err.diagnostics:
|
for diag in err.diagnostics:
|
||||||
|
|
@ -189,7 +203,7 @@ proc bracketNotFoundError(c: PContext; n: PNode) =
|
||||||
while symx != nil:
|
while symx != nil:
|
||||||
if symx.kind in routineKinds:
|
if symx.kind in routineKinds:
|
||||||
errors.add(CandidateError(sym: symx,
|
errors.add(CandidateError(sym: symx,
|
||||||
unmatchedVarParam: 0,
|
unmatchedVarParam: 0, firstMismatch: 0,
|
||||||
diagnostics: nil))
|
diagnostics: nil))
|
||||||
symx = nextOverloadIter(o, c, headSymbol)
|
symx = nextOverloadIter(o, c, headSymbol)
|
||||||
if errors.len == 0:
|
if errors.len == 0:
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ type
|
||||||
|
|
||||||
CandidateError* = object
|
CandidateError* = object
|
||||||
sym*: PSym
|
sym*: PSym
|
||||||
unmatchedVarParam*: int
|
unmatchedVarParam*, firstMismatch*: int
|
||||||
diagnostics*: seq[string]
|
diagnostics*: seq[string]
|
||||||
|
|
||||||
CandidateErrors* = seq[CandidateError]
|
CandidateErrors* = seq[CandidateError]
|
||||||
|
|
@ -68,6 +68,8 @@ type
|
||||||
# triggered with an idetools command in the
|
# triggered with an idetools command in the
|
||||||
# future.
|
# future.
|
||||||
inheritancePenalty: int # to prefer closest father object type
|
inheritancePenalty: int # to prefer closest father object type
|
||||||
|
firstMismatch*: int # position of the first type mismatch for
|
||||||
|
# better error messages
|
||||||
|
|
||||||
TTypeRelFlag* = enum
|
TTypeRelFlag* = enum
|
||||||
trDontBind
|
trDontBind
|
||||||
|
|
@ -2249,6 +2251,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
|
||||||
n.sons[a], nOrig.sons[a])
|
n.sons[a], nOrig.sons[a])
|
||||||
if arg == nil:
|
if arg == nil:
|
||||||
m.state = csNoMatch
|
m.state = csNoMatch
|
||||||
|
m.firstMismatch = f
|
||||||
return
|
return
|
||||||
if m.baseTypeMatch:
|
if m.baseTypeMatch:
|
||||||
#assert(container == nil)
|
#assert(container == nil)
|
||||||
|
|
@ -2303,6 +2306,7 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
|
||||||
else:
|
else:
|
||||||
# no default value
|
# no default value
|
||||||
m.state = csNoMatch
|
m.state = csNoMatch
|
||||||
|
m.firstMismatch = f
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
# use default value:
|
# use default value:
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,48 @@
|
||||||
discard """
|
discard """
|
||||||
errormsg: "type mismatch: got (Bar[system.int])"
|
errormsg: "type mismatch: got (Bar[system.int])"
|
||||||
nimout: '''
|
nimout: '''
|
||||||
t3330.nim(40, 4) Error: type mismatch: got (Bar[system.int])
|
t3330.nim(63, 4) Error: type mismatch: got (Bar[system.int])
|
||||||
but expected one of:
|
but expected one of:
|
||||||
proc test(foo: Foo[int])
|
proc test(foo: Foo[int])
|
||||||
t3330.nim(25, 8) Hint: Non-matching candidates for add(k, string, T)
|
t3330.nim(48, 8) Hint: Non-matching candidates for add(k, string, T)
|
||||||
proc add(x: var string; y: string)
|
proc add(x: var string; y: string)
|
||||||
|
first type mismatch at position: 1
|
||||||
|
required type: var string
|
||||||
|
but expression 'k' is of type: Alias
|
||||||
proc add(x: var string; y: char)
|
proc add(x: var string; y: char)
|
||||||
|
first type mismatch at position: 1
|
||||||
|
required type: var string
|
||||||
|
but expression 'k' is of type: Alias
|
||||||
proc add(result: var string; x: int64)
|
proc add(result: var string; x: int64)
|
||||||
|
first type mismatch at position: 1
|
||||||
|
required type: var string
|
||||||
|
but expression 'k' is of type: Alias
|
||||||
proc add(result: var string; x: float)
|
proc add(result: var string; x: float)
|
||||||
|
first type mismatch at position: 1
|
||||||
|
required type: var string
|
||||||
|
but expression 'k' is of type: Alias
|
||||||
proc add(x: var string; y: cstring)
|
proc add(x: var string; y: cstring)
|
||||||
|
first type mismatch at position: 1
|
||||||
|
required type: var string
|
||||||
|
but expression 'k' is of type: Alias
|
||||||
proc add[T](x: var seq[T]; y: openArray[T])
|
proc add[T](x: var seq[T]; y: openArray[T])
|
||||||
|
first type mismatch at position: 1
|
||||||
|
required type: var seq[T]
|
||||||
|
but expression 'k' is of type: Alias
|
||||||
proc add[T](x: var seq[T]; y: T)
|
proc add[T](x: var seq[T]; y: T)
|
||||||
|
first type mismatch at position: 1
|
||||||
|
required type: var seq[T]
|
||||||
|
but expression 'k' is of type: Alias
|
||||||
|
|
||||||
t3330.nim(25, 8) template/generic instantiation from here
|
t3330.nim(48, 8) template/generic instantiation from here
|
||||||
t3330.nim(32, 6) Foo: 'bar.value' cannot be assigned to
|
t3330.nim(55, 6) Foo: 'bar.value' cannot be assigned to
|
||||||
t3330.nim(25, 8) template/generic instantiation from here
|
t3330.nim(48, 8) template/generic instantiation from here
|
||||||
t3330.nim(33, 6) Foo: 'bar.x' cannot be assigned to
|
t3330.nim(56, 6) Foo: 'bar.x' cannot be assigned to
|
||||||
'''
|
|
||||||
|
expression: test(bar)'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
Foo[T] = concept k
|
Foo[T] = concept k
|
||||||
add(k, string, T)
|
add(k, string, T)
|
||||||
|
|
|
||||||
22
tests/errmsgs/tdetailed_position.nim
Normal file
22
tests/errmsgs/tdetailed_position.nim
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
discard """
|
||||||
|
cmd: "nim check $file"
|
||||||
|
errormsg: "type mismatch: got (int literal(1), int literal(2), int literal(3))"
|
||||||
|
nimout: '''
|
||||||
|
but expected one of:
|
||||||
|
proc main(a, b, c: string)
|
||||||
|
first type mismatch at position: 1
|
||||||
|
required type: string
|
||||||
|
but expression '1' is of type: int literal(1)
|
||||||
|
|
||||||
|
expression: main(1, 2, 3)
|
||||||
|
'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
const
|
||||||
|
myconst = "abcdefghijklmnopqrstuvwxyz"
|
||||||
|
|
||||||
|
proc main(a, b, c: string) {.deprecated: "use foo " & "instead " & myconst.} =
|
||||||
|
return
|
||||||
|
|
||||||
|
main(1, 2, 3)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue