diff options
author | ringabout <43030857+ringabout@users.noreply.github.com> | 2022-12-29 03:54:15 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-28 20:54:15 +0100 |
commit | 761c5a0830a18cb0db721d27aff53a07ca30b1c3 (patch) | |
tree | bf788ce806cada9653959c8a5a9e3edc808e84e5 /compiler | |
parent | 646932b3f316d6b8e3ceb6b94b9d01232d5cdb33 (diff) | |
download | Nim-761c5a0830a18cb0db721d27aff53a07ca30b1c3.tar.gz |
less verbose type mismatch messages (#21191)
* less verbose type mismatch messages * Update compiler/types.nim * fixes i386 * fixes i386
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/options.nim | 1 | ||||
-rw-r--r-- | compiler/semcall.nim | 44 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 40 |
3 files changed, 58 insertions, 27 deletions
diff --git a/compiler/options.nim b/compiler/options.nim index 7e4f6898f..ded084ae4 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -231,6 +231,7 @@ type ## are not anymore. laxEffects ## Lax effects system prior to Nim 2.0. + verboseTypeMismatch SymbolFilesOption* = enum disabledSf, writeOnlySf, readOnlySf, v2Sf, stressTest diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 31b490781..2147a9645 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -10,7 +10,8 @@ ## This module implements semantic checking for calls. # included from sem.nim -from algorithm import sort +from std/algorithm import sort + proc sameMethodDispatcher(a, b: PSym): bool = result = false @@ -192,7 +193,7 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors): # argument in order to remove plenty of candidates. This is # comparable to what C# does and C# is doing fine. var filterOnlyFirst = false - if optShowAllMismatches notin c.config.globalOptions: + if optShowAllMismatches notin c.config.globalOptions and verboseTypeMismatch in c.config.legacyFeatures: for err in errors: if err.firstMismatch.arg > 1: filterOnlyFirst = true @@ -208,6 +209,10 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors): if filterOnlyFirst and err.firstMismatch.arg == 1: inc skipped continue + + if verboseTypeMismatch notin c.config.legacyFeatures: + candidates.add "[" & $err.firstMismatch.arg & "] " + if err.sym.kind in routineKinds and err.sym.ast != nil: candidates.add(renderTree(err.sym.ast, {renderNoBody, renderNoComments, renderNoPragmas})) @@ -217,7 +222,7 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors): candidates.add("\n") 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: + if n.len > 1 and verboseTypeMismatch in c.config.legacyFeatures: candidates.add(" first type mismatch at position: " & $err.firstMismatch.arg) # candidates.add "\n reason: " & $err.firstMismatch.kind # for debugging case err.firstMismatch.kind @@ -274,11 +279,28 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors): const errTypeMismatch = "type mismatch: got <" errButExpected = "but expected one of:" + errExpectedPosition = "Expected one of (first mismatch at position [#]):" errUndeclaredField = "undeclared field: '$1'" errUndeclaredRoutine = "attempting to call undeclared routine: '$1'" errBadRoutine = "attempting to call routine: '$1'$2" errAmbiguousCallXYZ = "ambiguous call; both $1 and $2 match for: $3" +proc describeParamList(c: PContext, n: PNode, startIdx = 1; prefer = preferName): string = + result = "Expression: " & $n + for i in startIdx..<n.len: + result.add "\n [" & $i & "] " & renderTree(n[i]) & ": " + result.add describeArg(c, n, i, startIdx, prefer) + result.add "\n" + +template legacynotFoundError(c: PContext, n: PNode, errors: CandidateErrors) = + let (prefer, candidates) = presentFailedCandidates(c, n, errors) + var result = errTypeMismatch + result.add(describeArgs(c, n, 1, prefer)) + result.add('>') + if candidates != "": + result.add("\n" & errButExpected & "\n" & candidates) + localError(c.config, n.info, result & "\nexpression: " & $n) + proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) = # Gives a detailed error message; this is separated from semOverloadedCall, # as semOverloadedCall is already pretty slow (and we need this information @@ -306,13 +328,15 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) = localError(c.config, n.info, "expression '$1' cannot be called" % n[0].renderTree) return - let (prefer, candidates) = presentFailedCandidates(c, n, errors) - var result = errTypeMismatch - result.add(describeArgs(c, n, 1, prefer)) - result.add('>') - if candidates != "": - result.add("\n" & errButExpected & "\n" & candidates) - localError(c.config, n.info, result & "\nexpression: " & $n) + if verboseTypeMismatch in c.config.legacyFeatures: + legacynotFoundError(c, n, errors) + else: + let (prefer, candidates) = presentFailedCandidates(c, n, errors) + var result = "type mismatch\n" + result.add describeParamList(c, n, 1, prefer) + if candidates != "": + result.add("\n" & errExpectedPosition & "\n" & candidates) + localError(c.config, n.info, result) proc bracketNotFoundError(c: PContext; n: PNode) = var errors: CandidateErrors = @[] diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 68068cd26..75e3e5428 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -322,26 +322,32 @@ proc argTypeToString(arg: PNode; prefer: TPreferedDesc): string = else: result = arg.typ.typeToString(prefer) +template describeArgImpl(c: PContext, n: PNode, i: int, startIdx = 1; prefer = preferName) = + var arg = n[i] + if n[i].kind == nkExprEqExpr: + result.add renderTree(n[i][0]) + result.add ": " + if arg.typ.isNil and arg.kind notin {nkStmtList, nkDo}: + # XXX we really need to 'tryExpr' here! + arg = c.semOperand(c, n[i][1]) + n[i].typ = arg.typ + n[i][1] = arg + else: + if arg.typ.isNil and arg.kind notin {nkStmtList, nkDo, nkElse, + nkOfBranch, nkElifBranch, + nkExceptBranch}: + arg = c.semOperand(c, n[i]) + n[i] = arg + if arg.typ != nil and arg.typ.kind == tyError: return + result.add argTypeToString(arg, prefer) + +proc describeArg*(c: PContext, n: PNode, i: int, startIdx = 1; prefer = preferName): string = + describeArgImpl(c, n, i, startIdx, prefer) + proc describeArgs*(c: PContext, n: PNode, startIdx = 1; prefer = preferName): string = result = "" for i in startIdx..<n.len: - var arg = n[i] - if n[i].kind == nkExprEqExpr: - result.add renderTree(n[i][0]) - result.add ": " - if arg.typ.isNil and arg.kind notin {nkStmtList, nkDo}: - # XXX we really need to 'tryExpr' here! - arg = c.semOperand(c, n[i][1]) - n[i].typ = arg.typ - n[i][1] = arg - else: - if arg.typ.isNil and arg.kind notin {nkStmtList, nkDo, nkElse, - nkOfBranch, nkElifBranch, - nkExceptBranch}: - arg = c.semOperand(c, n[i]) - n[i] = arg - if arg.typ != nil and arg.typ.kind == tyError: return - result.add argTypeToString(arg, prefer) + describeArgImpl(c, n, i, startIdx, prefer) if i != n.len - 1: result.add ", " proc concreteType(c: TCandidate, t: PType; f: PType = nil): PType = |