fix #8305 #7808 #10285 #11061 + other bugs with type mismatch error msgs

This commit is contained in:
Timothee Cour 2019-07-06 17:46:57 -07:00
commit a6526695f0
2 changed files with 68 additions and 51 deletions

View file

@ -107,7 +107,6 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode,
elif errorsEnabled or z.diagnosticsEnabled:
errors.add(CandidateError(
sym: sym,
unmatchedVarParam: int z.mutabilityProblem,
firstMismatch: z.firstMismatch,
diagnostics: z.diagnostics))
else:
@ -173,14 +172,14 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors):
var filterOnlyFirst = false
if optShowAllMismatches notin c.config.globalOptions:
for err in errors:
if err.firstMismatch > 1:
if err.firstMismatch.arg > 1:
filterOnlyFirst = true
break
var candidates = ""
var skipped = 0
for err in errors:
if filterOnlyFirst and err.firstMismatch == 1:
if filterOnlyFirst and err.firstMismatch.arg == 1:
inc skipped
continue
if err.sym.kind in routineKinds and err.sym.ast != nil:
@ -189,34 +188,35 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors):
else:
add(candidates, getProcHeader(c.config, err.sym, prefer))
add(candidates, "\n")
if err.firstMismatch != 0 and n.len > 1:
let cond = n.len > 2
if cond:
candidates.add(" first type mismatch at position: " & $abs(err.firstMismatch))
if err.firstMismatch >= 0: candidates.add("\n required type: ")
else: candidates.add("\n unknown named parameter: " & $n[-err.firstMismatch][0])
var wanted, got: PType = nil
if err.firstMismatch < 0:
discard
elif err.firstMismatch < err.sym.typ.len:
wanted = err.sym.typ.sons[err.firstMismatch]
if cond: candidates.add typeToString(wanted)
else:
if cond: candidates.add "none"
if err.firstMismatch > 0 and err.firstMismatch < n.len:
if cond:
candidates.add "\n but expression '"
candidates.add renderTree(n[err.firstMismatch])
let nArg = if err.firstMismatch.arg < n.len: n[err.firstMismatch.arg] else: nil
let nameParam = if err.firstMismatch.formal != nil: err.firstMismatch.formal.name.s else: ""
if n.len > 1:
candidates.add(" first type mismatch at position: " & $err.firstMismatch.arg)
# candidates.add "\n reason: " & $err.firstMismatch.kind # for debugging
case err.firstMismatch.kind
of kUnknownNamedParam: candidates.add("\n unknown named parameter: " & $nArg[0])
of kAlreadyGiven: candidates.add("\n named param already provided: " & $nArg[0])
of kExtraArg: candidates.add("\n extra argument given")
of kMissingParam: candidates.add("\n missing parameter: " & nameParam)
of kTypeMismatch, kVarNeeded:
doAssert nArg != nil
var wanted = err.firstMismatch.formal.typ
doAssert err.firstMismatch.formal != nil
candidates.add("\n required type for " & nameParam & ": ")
candidates.add typeToString(wanted)
candidates.add "\n but expression '"
if err.firstMismatch.kind == kVarNeeded:
candidates.add renderNotLValue(nArg)
candidates.add "' is immutable, not 'var'"
else:
candidates.add renderTree(nArg)
candidates.add "' is of type: "
got = n[err.firstMismatch].typ
if cond: candidates.add typeToString(got)
if wanted != nil and got != nil:
effectProblem(wanted, got, candidates)
if cond: candidates.add "\n"
if err.unmatchedVarParam != 0 and err.unmatchedVarParam < n.len:
candidates.add(" for a 'var' type a variable needs to be passed, but '" &
renderNotLValue(n[err.unmatchedVarParam]) &
"' is immutable\n")
var got = nArg.typ
candidates.add typeToString(got)
doAssert wanted != nil
if got != nil: effectProblem(wanted, got, candidates)
of kUnknown: internalAssert(c.config, false)
candidates.add "\n"
for diag in err.diagnostics:
candidates.add(diag & "\n")
if skipped > 0:
@ -260,7 +260,7 @@ proc bracketNotFoundError(c: PContext; n: PNode) =
while symx != nil:
if symx.kind in routineKinds:
errors.add(CandidateError(sym: symx,
unmatchedVarParam: 0, firstMismatch: 0,
firstMismatch: MismatchInfo(),
diagnostics: @[],
enabled: false))
symx = nextOverloadIter(o, c, headSymbol)