From 5337d5da79293729f554de6e59b7b47086da0c9a Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 26 Apr 2021 15:11:46 -0700 Subject: [PATCH 01/10] nim check: make error msgs less redundant with nkError --- compiler/semexprs.nim | 17 +++++------- compiler/semstmts.nim | 1 + tests/errmsgs/t16178_nimcheck_redundant.nim | 30 +++++++++++++++++++++ 3 files changed, 37 insertions(+), 11 deletions(-) create mode 100644 tests/errmsgs/t16178_nimcheck_redundant.nim diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index cf8d4777f102a..942222a7da2ca 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -67,17 +67,7 @@ proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = proc semExprCheck(c: PContext, n: PNode, flags: TExprFlags): PNode = rejectEmptyNode(n) result = semExpr(c, n, flags+{efWantValue}) - - let - isEmpty = result.kind == nkEmpty - isTypeError = result.typ != nil and result.typ.kind == tyError - - if isEmpty or isTypeError: - # bug #12741, redundant error messages are the lesser evil here: - localError(c.config, n.info, errExprXHasNoType % - renderTree(result, {renderNoComments})) - - if isEmpty: + if result.kind == nkEmpty or (result.typ != nil and result.typ.kind == tyError): # do not produce another redundant error message: result = errorNode(c, n) @@ -2808,6 +2798,11 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = of skProc, skFunc, skMethod, skConverter, skIterator: if s.magic == mNone: result = semDirectOp(c, n, flags) else: result = semMagic(c, n, s, flags) + of skUnknown: + # xxx: see also `errorSubNode`, `newError`; `errorNode` uses `skEmpty` + # which causes redundant errors in D20210426T153714 for `let a = nonexistant`, + # because nim can't distinguish with `let a {.importc:"foo".}` which is valid. + result = errorNode(c, n) else: #liMessage(n.info, warnUser, renderTree(n)); result = semIndirectOp(c, n, flags) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index d56c1c1bd989a..7b293fef7b84d 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -617,6 +617,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = checkNilable(c, v) # allow let to not be initialised if imported from C: if v.kind == skLet and sfImportc notin v.flags: + # D20210426T153714:here localError(c.config, a.info, errLetNeedsInit) if sfCompileTime in v.flags: var x = newNodeI(result.kind, v.info) diff --git a/tests/errmsgs/t16178_nimcheck_redundant.nim b/tests/errmsgs/t16178_nimcheck_redundant.nim new file mode 100644 index 0000000000000..996fabf561650 --- /dev/null +++ b/tests/errmsgs/t16178_nimcheck_redundant.nim @@ -0,0 +1,30 @@ +discard """ +cmd: '''nim check --hints:off $file''' +action: reject +# nimoutFull: true # pending https://github.com/nim-lang/Nim/pull/17865 +nimout: ''' +t16178_nimcheck_redundant.nim(22, 11) Error: undeclared identifier: 'bad5' +t16178_nimcheck_redundant.nim(22, 7) Error: 'let' symbol requires an initialization +t16178_nimcheck_redundant.nim(26, 7) Error: 'let' symbol requires an initialization +''' +""" + + + + +#[ +xxx the line `Error: 'let' symbol requires an initialization` is redundant and should not +be reported +]# + +# line 20 +block: + let a = bad5(1) + +block: # bug #12741 + macro foo = discard + let x = foo + +# block: # PRTEMP +# macro foo2 = discard +# discard foo2 From 5106056784e7177e0b82f52d8bbbe21f62d5dbc6 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Tue, 27 Apr 2021 19:57:18 -0700 Subject: [PATCH 02/10] _ --- tests/errmsgs/t16178_nimcheck_redundant.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/errmsgs/t16178_nimcheck_redundant.nim b/tests/errmsgs/t16178_nimcheck_redundant.nim index 996fabf561650..72f39327fb7ac 100644 --- a/tests/errmsgs/t16178_nimcheck_redundant.nim +++ b/tests/errmsgs/t16178_nimcheck_redundant.nim @@ -1,7 +1,7 @@ discard """ cmd: '''nim check --hints:off $file''' action: reject -# nimoutFull: true # pending https://github.com/nim-lang/Nim/pull/17865 +nimoutFull: true nimout: ''' t16178_nimcheck_redundant.nim(22, 11) Error: undeclared identifier: 'bad5' t16178_nimcheck_redundant.nim(22, 7) Error: 'let' symbol requires an initialization From 813f3295b96d80245d29261e94ab52064957213d Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Wed, 28 Apr 2021 10:24:08 -0700 Subject: [PATCH 03/10] PRTEMP --- compiler/ast.nim | 1 + compiler/errorhandling.nim | 2 -- compiler/hlo.nim | 7 +++++++ compiler/lookups.nim | 1 + compiler/sem.nim | 1 + compiler/semcall.nim | 6 ++++++ compiler/semexprs.nim | 21 +++++++++++++++------ compiler/sempass2.nim | 7 ++++++- compiler/semstmts.nim | 1 + compiler/sigmatch.nim | 1 + 10 files changed, 39 insertions(+), 9 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 7090bc7ee787e..04ed235cc73ab 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -495,6 +495,7 @@ type nfExecuteOnReload # A top-level statement that will be executed during reloads nfLastRead # this node is a last read nfFirstWrite# this node is a first write + nfErrorShown # error already shown TNodeFlags* = set[TNodeFlag] TTypeFlag* = enum # keep below 32 for efficiency reasons (now: ~40) diff --git a/compiler/errorhandling.nim b/compiler/errorhandling.nim index cda7ab3f4e1bf..7f65286148a5d 100644 --- a/compiler/errorhandling.nim +++ b/compiler/errorhandling.nim @@ -33,7 +33,6 @@ proc errorSubNode*(n: PNode): PNode = if result != nil: break proc newError*(wrongNode: PNode; k: ErrorKind; args: varargs[PNode]): PNode = - assert wrongNode.kind != nkError let innerError = errorSubNode(wrongNode) if innerError != nil: return innerError @@ -43,7 +42,6 @@ proc newError*(wrongNode: PNode; k: ErrorKind; args: varargs[PNode]): PNode = for a in args: result.add a proc newError*(wrongNode: PNode; msg: string): PNode = - assert wrongNode.kind != nkError let innerError = errorSubNode(wrongNode) if innerError != nil: return innerError diff --git a/compiler/hlo.nim b/compiler/hlo.nim index af54cabbbdbc5..2e3f506f8edcc 100644 --- a/compiler/hlo.nim +++ b/compiler/hlo.nim @@ -82,13 +82,20 @@ proc hlo(c: PContext, n: PNode): PNode = else: # perform type checking, so that the replacement still fits: if isEmptyType(n.typ) and isEmptyType(result.typ): + dbg n.typ, result.typ discard else: + dbg n.typ, c.config$n.info result = fitNode(c, n.typ, result, n.info) + dbg result.kind # optimization has been applied so check again: + dbg result.kind, c.config$n.info result = commonOptimizations(c.graph, c.idgen, c.module, result) + dbg result.kind result = hlo(c, result) + dbg result.kind result = commonOptimizations(c.graph, c.idgen, c.module, result) + dbg result.kind proc hloBody(c: PContext, n: PNode): PNode = # fast exit: diff --git a/compiler/lookups.nim b/compiler/lookups.nim index c4f506a68861f..a92a9cac9fa43 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -470,6 +470,7 @@ proc errorUndeclaredIdentifier*(c: PContext; info: TLineInfo; name: string, extr # prevent excessive errors for 'nim check' c.recursiveDep = "" localError(c.config, info, errGenerated, err) + # echo getStacktrace() proc errorUndeclaredIdentifierHint*(c: PContext; n: PNode, ident: PIdent): PSym = var extra = "" diff --git a/compiler/sem.nim b/compiler/sem.nim index b807953541a04..a2d102e265a06 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -84,6 +84,7 @@ proc fitNodePostMatch(c: PContext, formal: PType, arg: PNode): PNode = proc fitNode(c: PContext, formal: PType, arg: PNode; info: TLineInfo): PNode = + # dbg arg.typ, formal, arg.kind if arg.typ.isNil: localError(c.config, arg.info, "expression has no type: " & renderTree(arg, {renderNoComments})) diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 8f29bdf328f86..96ec12f9a9cb8 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -11,6 +11,7 @@ # included from sem.nim from algorithm import sort +import errorhandling proc sameMethodDispatcher(a, b: PSym): bool = result = false @@ -413,6 +414,8 @@ proc resolveOverloads(c: PContext, n, orig: PNode, if efNoUndeclared notin flags: # for tests/pragmas/tcustom_pragma.nim # xxx adapt/use errorUndeclaredIdentifierHint(c, n, f.ident) localError(c.config, n.info, getMsgDiagnostic(c, flags, n, f)) + result.errorNode = newError(n, "D20210428T023435") + result.errorNode.flags.incl nfErrorShown return elif result.state != csMatch: if nfExprCall in n.flags: @@ -568,6 +571,9 @@ proc semOverloadedCall(c: PContext, n, nOrig: PNode, filter: TSymKinds, flags: TExprFlags): PNode {.nosinks.} = var errors: CandidateErrors = @[] # if efExplain in flags: @[] else: nil var r = resolveOverloads(c, n, nOrig, filter, flags, errors, efExplain in flags) + if r.errorNode != nil: + assert r.errorNode.kind == nkError + return r.errorNode if r.state == csMatch: # this may be triggered, when the explain pragma is used if errors.len > 0: diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 942222a7da2ca..08d02aecbaedf 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -12,7 +12,7 @@ when defined(nimCompilerStackraceHints): import std/stackframes - +import errorhandling const errExprXHasNoType = "expression '$1' has no type (or is ambiguous)" errXExpectsTypeOrValue = "'$1' expects a type or value" @@ -68,14 +68,20 @@ proc semExprCheck(c: PContext, n: PNode, flags: TExprFlags): PNode = rejectEmptyNode(n) result = semExpr(c, n, flags+{efWantValue}) if result.kind == nkEmpty or (result.typ != nil and result.typ.kind == tyError): - # do not produce another redundant error message: - result = errorNode(c, n) + result = newError(result, "D20210427T212052.2") proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result = semExprCheck(c, n, flags) + # dbg result.typ, result.kind + # if result.typ != nil: + # dbg result.typ.kind if result.typ == nil and efInTypeof in flags: result.typ = c.voidType - elif result.typ == nil or result.typ == c.enforceVoidContext: + elif result.kind == nkError: + if nfErrorShown notin result.flags: + localError(c.config, n.info, errExprXHasNoType % renderTree(result, {renderNoComments})) + result.flags.incl nfErrorShown # PRTEMP FACTOR + elif result.typ == nil or result.typ == c.enforceVoidContext or result.kind == nkError: localError(c.config, n.info, errExprXHasNoType % renderTree(result, {renderNoComments})) result.typ = errorType(c) @@ -860,6 +866,7 @@ proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode, {skProc, skFunc, skMethod, skConverter, skMacro, skTemplate}, flags) if result != nil: + if result.kind == nkError: return result if result[0].kind != nkSym: internalError(c.config, "semOverloadedCallAnalyseEffects") return @@ -2799,10 +2806,12 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = if s.magic == mNone: result = semDirectOp(c, n, flags) else: result = semMagic(c, n, s, flags) of skUnknown: - # xxx: see also `errorSubNode`, `newError`; `errorNode` uses `skEmpty` + # `errorNode` uses `skEmpty` # which causes redundant errors in D20210426T153714 for `let a = nonexistant`, # because nim can't distinguish with `let a {.importc:"foo".}` which is valid. - result = errorNode(c, n) + result = newError(n, "D20210427T212052.1") + result.flags.incl nfErrorShown # hacky, instead `errorSym` should do this + dbg result.flags, cast[int](result) else: #liMessage(n.info, warnUser, renderTree(n)); result = semIndirectOp(c, n, flags) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index e66c9596a2165..f23da1e2487d0 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -1137,7 +1137,12 @@ proc track(tracked: PEffects, n: PNode) = for i in 1 ..< n.len: track(tracked, n[i]) inc tracked.leftPartOfAsgn of nkError: - localError(tracked.config, n.info, errorToString(tracked.config, n)) + dbg n.flags, tracked.config$n.info + # if nfErrorShown notin n.flags: + # localError(tracked.config, n.info, errorToString(tracked.config, n)) + # dbg cast[int](n), n.flags, tracked.config$n.info, n + # n.flags.incl nfErrorShown + # # echo getStacktrace() else: for i in 0.. Date: Wed, 28 Apr 2021 11:19:29 -0700 Subject: [PATCH 04/10] bootstrap works --- compiler/errorhandling.nim | 7 +++++ compiler/msgs.nim | 5 ++++ compiler/semexprs.nim | 55 +++++++++++++++++--------------------- 3 files changed, 37 insertions(+), 30 deletions(-) diff --git a/compiler/errorhandling.nim b/compiler/errorhandling.nim index 7f65286148a5d..7963e95b74e61 100644 --- a/compiler/errorhandling.nim +++ b/compiler/errorhandling.nim @@ -50,6 +50,13 @@ proc newError*(wrongNode: PNode; msg: string): PNode = result.add newIntNode(nkIntLit, ord(CustomError)) result.add newStrNode(msg, wrongNode.info) +proc newErrorShown*(wrongNode: PNode = nil): PNode = + if wrongNode == nil: + result = newNodeIT(nkError, PNode.default.info.type.default, newType(tyError, ItemId(module: -1, item: -1), nil)) + else: + result = newError(wrongNode, "already shown D20210428T104841") + result.flags.incl nfErrorShown + proc errorToString*(config: ConfigRef; n: PNode): string = assert n.kind == nkError assert n.len > 1 diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 3abbf9e697cea..3443e4363737b 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -10,6 +10,7 @@ import options, strutils, os, tables, ropes, terminal, macros, lineinfos, pathutils +import ast import std/private/miscdollars import strutils2 @@ -592,6 +593,10 @@ template localError*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg = "") template localError*(conf: ConfigRef; info: TLineInfo, arg: string) = liMessage(conf, info, errGenerated, arg, doNothing, instLoc()) +template localErrorShown*(conf: ConfigRef; info: TLineInfo, arg: string): PNode = + liMessage(conf, info, errGenerated, arg, doNothing, instLoc()) + newErrorShown(nil) + template message*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg = "") = liMessage(conf, info, msg, arg, doNothing, instLoc()) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 08d02aecbaedf..16ab8d300ae65 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -60,43 +60,37 @@ proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = elif {efWantStmt, efAllowStmt} * flags != {}: result.typ = newTypeS(tyVoid, c) else: - localError(c.config, n.info, errExprXHasNoType % + result = localErrorShown(c.config, n.info, errExprXHasNoType % renderTree(result, {renderNoComments})) - result.typ = errorType(c) proc semExprCheck(c: PContext, n: PNode, flags: TExprFlags): PNode = rejectEmptyNode(n) result = semExpr(c, n, flags+{efWantValue}) if result.kind == nkEmpty or (result.typ != nil and result.typ.kind == tyError): - result = newError(result, "D20210427T212052.2") + result = newError(result, "D20210428T103116") # PRTEMP + # result = newErrorShown(result) proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result = semExprCheck(c, n, flags) - # dbg result.typ, result.kind - # if result.typ != nil: - # dbg result.typ.kind if result.typ == nil and efInTypeof in flags: result.typ = c.voidType elif result.kind == nkError: if nfErrorShown notin result.flags: localError(c.config, n.info, errExprXHasNoType % renderTree(result, {renderNoComments})) result.flags.incl nfErrorShown # PRTEMP FACTOR - elif result.typ == nil or result.typ == c.enforceVoidContext or result.kind == nkError: - localError(c.config, n.info, errExprXHasNoType % + elif result.typ == nil or result.typ == c.enforceVoidContext: + result = localErrorShown(c.config, n.info, errExprXHasNoType % renderTree(result, {renderNoComments})) - result.typ = errorType(c) elif result.typ.kind == tyError: - # associates the type error to the current owner - result.typ = errorType(c) + doAssert false else: if result.typ.kind in {tyVar, tyLent}: result = newDeref(result) proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result = semExprCheck(c, n, flags) if result.typ == nil: - localError(c.config, n.info, errExprXHasNoType % + result = localErrorShown(c.config, n.info, errExprXHasNoType % renderTree(result, {renderNoComments})) - result.typ = errorType(c) proc semSymGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = result = symChoice(c, n, s, scClosed) @@ -104,8 +98,7 @@ proc semSymGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = proc inlineConst(c: PContext, n: PNode, s: PSym): PNode {.inline.} = result = copyTree(s.ast) if result.isNil: - localError(c.config, n.info, "constant of type '" & typeToString(s.typ) & "' has no value") - result = newSymNode(s) + result = localErrorShown(c.config, n.info, "constant of type '" & typeToString(s.typ) & "' has no value") else: result.typ = s.typ result.info = n.info @@ -256,8 +249,7 @@ proc isOwnedSym(c: PContext; n: PNode): bool = proc semConv(c: PContext, n: PNode): PNode = if n.len != 2: - localError(c.config, n.info, "a type conversion takes exactly one argument") - return n + result = localErrorShown(c.config, n.info, "a type conversion takes exactly one argument") result = newNodeI(nkConv, n.info) @@ -298,7 +290,7 @@ proc semConv(c: PContext, n: PNode): PNode = # special case to make MyObject(x = 3) produce a nicer error message: if n[1].kind == nkExprEqExpr and targetType.skipTypes(abstractPtrs).kind == tyObject: - localError(c.config, n.info, "object construction uses ':', not '='") + return localErrorShown(c.config, n.info, "object construction uses ':', not '='") var op = semExprWithType(c, n[1]) if targetType.kind != tyGenericParam and targetType.isMetaType: let final = inferWithMetatype(c, targetType, op, true) @@ -329,12 +321,12 @@ proc semConv(c: PContext, n: PNode): PNode = of convNotLegal: result = fitNode(c, result.typ, result[1], result.info) if result == nil: - localError(c.config, n.info, "illegal conversion from '$1' to '$2'" % + return localErrorShown(c.config, n.info, "illegal conversion from '$1' to '$2'" % [op.typ.typeToString, result.typ.typeToString]) of convNotInRange: let value = if op.kind in {nkCharLit..nkUInt64Lit}: $op.getInt else: $op.getFloat - localError(c.config, n.info, errGenerated, value & " can't be converted to " & + return localErrorShown(c.config, n.info, value & " can't be converted to " & result.typ.typeToString) else: for i in 0.. Date: Wed, 28 Apr 2021 11:21:59 -0700 Subject: [PATCH 05/10] fixup --- compiler/hlo.nim | 14 +++++++------- compiler/semexprs.nim | 2 +- compiler/sempass2.nim | 3 ++- compiler/semstmts.nim | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/compiler/hlo.nim b/compiler/hlo.nim index 2e3f506f8edcc..c5a8e442d679a 100644 --- a/compiler/hlo.nim +++ b/compiler/hlo.nim @@ -82,20 +82,20 @@ proc hlo(c: PContext, n: PNode): PNode = else: # perform type checking, so that the replacement still fits: if isEmptyType(n.typ) and isEmptyType(result.typ): - dbg n.typ, result.typ + # dbg n.typ, result.typ discard else: - dbg n.typ, c.config$n.info + # dbg n.typ, c.config$n.info result = fitNode(c, n.typ, result, n.info) - dbg result.kind + # dbg result.kind # optimization has been applied so check again: - dbg result.kind, c.config$n.info + # dbg result.kind, c.config$n.info result = commonOptimizations(c.graph, c.idgen, c.module, result) - dbg result.kind + # dbg result.kind result = hlo(c, result) - dbg result.kind + # dbg result.kind result = commonOptimizations(c.graph, c.idgen, c.module, result) - dbg result.kind + # dbg result.kind proc hloBody(c: PContext, n: PNode): PNode = # fast exit: diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 16ab8d300ae65..1d7f252bf2c6b 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -2806,7 +2806,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = # because nim can't distinguish with `let a {.importc:"foo".}` which is valid. result = newError(n, "D20210427T212052.1") result.flags.incl nfErrorShown # hacky, instead `errorSym` should do this - dbg result.flags, cast[int](result) + # dbg result.flags, cast[int](result) else: #liMessage(n.info, warnUser, renderTree(n)); result = semIndirectOp(c, n, flags) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index f23da1e2487d0..64069731694bf 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -1137,7 +1137,8 @@ proc track(tracked: PEffects, n: PNode) = for i in 1 ..< n.len: track(tracked, n[i]) inc tracked.leftPartOfAsgn of nkError: - dbg n.flags, tracked.config$n.info + echo "in nkError D20210428T112031" + # dbg n.flags, tracked.config$n.info # if nfErrorShown notin n.flags: # localError(tracked.config, n.info, errorToString(tracked.config, n)) # dbg cast[int](n), n.flags, tracked.config$n.info, n diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index f4c2bd803d9d2..d1da1c16fc634 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -618,7 +618,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = # allow let to not be initialised if imported from C: if v.kind == skLet and sfImportc notin v.flags: # D20210426T153714:here - dbg a.kind, v.kind, def, def.kind + # dbg a.kind, v.kind, def, def.kind localError(c.config, a.info, errLetNeedsInit) if sfCompileTime in v.flags: var x = newNodeI(result.kind, v.info) From 3b68231e32fd291655229bb4369d96223a8b3ff2 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Wed, 28 Apr 2021 11:59:39 -0700 Subject: [PATCH 06/10] fixup --- compiler/sempass2.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 64069731694bf..d936646130d65 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -1137,7 +1137,8 @@ proc track(tracked: PEffects, n: PNode) = for i in 1 ..< n.len: track(tracked, n[i]) inc tracked.leftPartOfAsgn of nkError: - echo "in nkError D20210428T112031" + discard + # echo "in nkError D20210428T112031" # PRTEMP # dbg n.flags, tracked.config$n.info # if nfErrorShown notin n.flags: # localError(tracked.config, n.info, errorToString(tracked.config, n)) From 684ab9c2aa2eb883f98d010995db1800b3c22392 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Wed, 28 Apr 2021 12:22:32 -0700 Subject: [PATCH 07/10] fix tests --- compiler/renderer.nim | 3 +- testament/testament.nim | 2 + tests/errmsgs/t16178_nimcheck_redundant.nim | 44 +++++++++++++++------ 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/compiler/renderer.nim b/compiler/renderer.nim index 8bc3c33066a34..d8b221837e30c 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -1694,7 +1694,8 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext, fromStmtList = false) = of nkError: putWithSpace(g, tkSymbol, "error") #gcomma(g, n, c) - gsub(g, n[0], c) + if n.len > 0: + gsub(g, n[0], c) else: #nkNone, nkExplicitTypeListCall: internalError(g.config, n.info, "rnimsyn.gsub(" & $n.kind & ')') diff --git a/testament/testament.nim b/testament/testament.nim index 9caa3f6b9beca..3e9f04bcc57ea 100644 --- a/testament/testament.nim +++ b/testament/testament.nim @@ -376,6 +376,8 @@ proc nimoutCheck(expected, given: TSpec): bool = result = true if expected.nimoutFull: if expected.nimout != given.nimout: + echo (expected.nimout,) + echo (given.nimout,) result = false elif expected.nimout.len > 0 and not greedyOrderedSubsetLines(expected.nimout, given.nimout): result = false diff --git a/tests/errmsgs/t16178_nimcheck_redundant.nim b/tests/errmsgs/t16178_nimcheck_redundant.nim index 72f39327fb7ac..44e52434c81e1 100644 --- a/tests/errmsgs/t16178_nimcheck_redundant.nim +++ b/tests/errmsgs/t16178_nimcheck_redundant.nim @@ -3,21 +3,31 @@ cmd: '''nim check --hints:off $file''' action: reject nimoutFull: true nimout: ''' -t16178_nimcheck_redundant.nim(22, 11) Error: undeclared identifier: 'bad5' -t16178_nimcheck_redundant.nim(22, 7) Error: 'let' symbol requires an initialization -t16178_nimcheck_redundant.nim(26, 7) Error: 'let' symbol requires an initialization +t16178_nimcheck_redundant.nim(32, 11) Error: undeclared identifier: 'bad5' +t16178_nimcheck_redundant.nim(36, 11) Error: expression 'error' has no type (or is ambiguous) +t16178_nimcheck_redundant.nim(40, 11) Error: expression 'error' has no type (or is ambiguous) +t16178_nimcheck_redundant.nim(44, 15) Error: expression 'error' has no type (or is ambiguous) +t16178_nimcheck_redundant.nim(49, 12) Error: undeclared field: 'f1' for type t16178_nimcheck_redundant.A [type declared in t16178_nimcheck_redundant.nim(47, 8)] +t16178_nimcheck_redundant.nim(49, 12) Error: expression 'error' has no type (or is ambiguous) +t16178_nimcheck_redundant.nim(50, 12) Error: undeclared field: 'f2' for type t16178_nimcheck_redundant.A [type declared in t16178_nimcheck_redundant.nim(47, 8)] +t16178_nimcheck_redundant.nim(50, 12) Error: expression 'error' has no type (or is ambiguous) +t16178_nimcheck_redundant.nim(51, 8) Error: attempting to call undeclared routine: 'f3=' +t16178_nimcheck_redundant.nim(52, 8) Error: attempting to call undeclared routine: 'f4=' ''' """ - - - #[ xxx the line `Error: 'let' symbol requires an initialization` is redundant and should not -be reported +be reported; likewise with `t16178_nimcheck_redundant.nim(22, 15) Error: expression '' has no type (or is ambiguous)` + +TODO: the trailing space `_redundant.nim(47, 8)] ` is bad ]# -# line 20 + + + + +# line 30 block: let a = bad5(1) @@ -25,6 +35,18 @@ block: # bug #12741 macro foo = discard let x = foo -# block: # PRTEMP -# macro foo2 = discard -# discard foo2 +block: + macro foo2 = discard + discard foo2 + +block: + macro foo3() = discard + discard foo3() + +block: + type A = object + var a = A() + discard a.f1 + discard a.f2 + a.f3 = 0 + a.f4 = 0 From 6f45f75bc8a1e11e008cc41f32f7797dd1b74312 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Wed, 28 Apr 2021 13:01:15 -0700 Subject: [PATCH 08/10] fix tests --- compiler/semcall.nim | 6 +++-- testament/testament.nim | 25 ++++++++++++++---- tests/concepts/texplain.nim | 38 +++++++++++++-------------- tests/errmsgs/tsigmatch2.nim | 3 +-- tests/errmsgs/tundeclared_routine.nim | 8 +++--- tests/objects/t17437.nim | 8 +++--- 6 files changed, 52 insertions(+), 36 deletions(-) diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 96ec12f9a9cb8..8236ecde2986d 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -269,7 +269,7 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors): const errTypeMismatch = "type mismatch: got <" - errButExpected = "but expected one of: " + errButExpected = "but expected one of:" errUndeclaredField = "undeclared field: '$1'" errUndeclaredRoutine = "attempting to call undeclared routine: '$1'" errBadRoutine = "attempting to call routine: '$1'$2" @@ -338,7 +338,9 @@ proc getMsgDiagnostic(c: PContext, flags: TExprFlags, n, f: PNode): string = discard else: typeHint = " for type " & getProcHeader(c.config, sym) - result = errUndeclaredField % ident & typeHint & " " & result + if result.len > 0: + result = " " & result + result = errUndeclaredField % ident & typeHint & result else: if result.len == 0: result = errUndeclaredRoutine % ident else: result = errBadRoutine % [ident, result] diff --git a/testament/testament.nim b/testament/testament.nim index 3e9f04bcc57ea..51d85eae862ff 100644 --- a/testament/testament.nim +++ b/testament/testament.nim @@ -263,6 +263,21 @@ Tests failed and allowed to fail: $3 / $1
Tests skipped: $4 / $1
""" % [$x.total, $x.passed, $x.failedButAllowed, $x.skipped] +import std/tempfiles +proc showDiff(a, b: string) = + # PRTEMP FACTOR MOVE std/private/gitutils.nim + let (fda, patha) = createTempFile("", "") + let (fdb, pathb) = createTempFile("", "") + defer: + close fda + removeFile(patha) + close fdb + removeFile(pathb) + writeFile(patha, a) + writeFile(pathb, b) + # discard execShellCmd("diff -uNdr $1 $2" % [patha.quoteShell, pathb.quoteShell]) + discard execShellCmd("git diff --no-index $1 $2" % [patha.quoteShell, pathb.quoteShell]) + proc addResult(r: var TResults, test: TTest, target: TTarget, expected, given: string, successOrig: TResultEnum, allowFailure = false) = # test.name is easier to find than test.name.extractFilename @@ -303,11 +318,11 @@ proc addResult(r: var TResults, test: TTest, target: TTarget, # expected is empty, no reason to print it. echo given else: - maybeStyledEcho fgYellow, "Expected:" - maybeStyledEcho styleBright, expected, "\n" - maybeStyledEcho fgYellow, "Gotten:" - maybeStyledEcho styleBright, given, "\n" - + # maybeStyledEcho fgYellow, "Expected:" + # maybeStyledEcho styleBright, expected, "\n" + # maybeStyledEcho fgYellow, "Gotten:" + # maybeStyledEcho styleBright, given, "\n" + showDiff(expected, given) if backendLogging and (isAppVeyor or isAzure): let (outcome, msg) = diff --git a/tests/concepts/texplain.nim b/tests/concepts/texplain.nim index 49eb8eb6b1e66..67f4d3ce3df13 100644 --- a/tests/concepts/texplain.nim +++ b/tests/concepts/texplain.nim @@ -13,14 +13,10 @@ proc e(o: ExplainedConcept): int required type for o: ExplainedConcept but expression '10' is of type: int literal(10) texplain.nim(128, 6) ExplainedConcept: undeclared field: 'foo' -texplain.nim(128, 6) ExplainedConcept: undeclared field: '.' -texplain.nim(128, 6) ExplainedConcept: expression '.' cannot be called -texplain.nim(128, 6) ExplainedConcept: expression '' has no type (or is ambiguous) +texplain.nim(128, 6) ExplainedConcept: expression 'error' has no type (or is ambiguous) texplain.nim(128, 5) ExplainedConcept: concept predicate failed texplain.nim(129, 6) ExplainedConcept: undeclared field: 'bar' -texplain.nim(129, 6) ExplainedConcept: undeclared field: '.' -texplain.nim(129, 6) ExplainedConcept: expression '.' cannot be called -texplain.nim(129, 6) ExplainedConcept: expression '' has no type (or is ambiguous) +texplain.nim(129, 6) ExplainedConcept: expression 'error' has no type (or is ambiguous) texplain.nim(128, 5) ExplainedConcept: concept predicate failed texplain.nim(168, 10) Hint: Non-matching candidates for e(10) @@ -29,14 +25,10 @@ proc e(o: ExplainedConcept): int required type for o: ExplainedConcept but expression '10' is of type: int literal(10) texplain.nim(128, 6) ExplainedConcept: undeclared field: 'foo' -texplain.nim(128, 6) ExplainedConcept: undeclared field: '.' -texplain.nim(128, 6) ExplainedConcept: expression '.' cannot be called -texplain.nim(128, 6) ExplainedConcept: expression '' has no type (or is ambiguous) +texplain.nim(128, 6) ExplainedConcept: expression 'error' has no type (or is ambiguous) texplain.nim(128, 5) ExplainedConcept: concept predicate failed texplain.nim(129, 6) ExplainedConcept: undeclared field: 'bar' -texplain.nim(129, 6) ExplainedConcept: undeclared field: '.' -texplain.nim(129, 6) ExplainedConcept: expression '.' cannot be called -texplain.nim(129, 6) ExplainedConcept: expression '' has no type (or is ambiguous) +texplain.nim(129, 6) ExplainedConcept: expression 'error' has no type (or is ambiguous) texplain.nim(128, 5) ExplainedConcept: concept predicate failed texplain.nim(172, 20) Error: type mismatch: got @@ -88,14 +80,10 @@ proc f(o: NestedConcept) required type for o: NestedConcept but expression 'y' is of type: MatchingType texplain.nim(132, 6) RegularConcept: undeclared field: 'foo' -texplain.nim(132, 6) RegularConcept: undeclared field: '.' -texplain.nim(132, 6) RegularConcept: expression '.' cannot be called -texplain.nim(132, 6) RegularConcept: expression '' has no type (or is ambiguous) +texplain.nim(132, 6) RegularConcept: expression 'error' has no type (or is ambiguous) texplain.nim(132, 5) RegularConcept: concept predicate failed texplain.nim(133, 6) RegularConcept: undeclared field: 'bar' -texplain.nim(133, 6) RegularConcept: undeclared field: '.' -texplain.nim(133, 6) RegularConcept: expression '.' cannot be called -texplain.nim(133, 6) RegularConcept: expression '' has no type (or is ambiguous) +texplain.nim(133, 6) RegularConcept: expression 'error' has no type (or is ambiguous) texplain.nim(132, 5) RegularConcept: concept predicate failed texplain.nim(136, 5) NestedConcept: concept predicate failed @@ -121,7 +109,19 @@ expression: f(y)''' -# line 120 HERE + + + + + + + + + + + + +# line 124 HERE type ExplainedConcept {.explain.} = concept o diff --git a/tests/errmsgs/tsigmatch2.nim b/tests/errmsgs/tsigmatch2.nim index 4996634c93e80..07819ce830bb6 100644 --- a/tests/errmsgs/tsigmatch2.nim +++ b/tests/errmsgs/tsigmatch2.nim @@ -13,7 +13,7 @@ proc foo(i: Foo): string but expression '1.2' is of type: float64 expression: foo(1.2) -tsigmatch2.nim(40, 14) Error: expression '' has no type (or is ambiguous) +tsigmatch2.nim(40, 14) Error: expression 'error' has no type (or is ambiguous) tsigmatch2.nim(46, 7) Error: type mismatch: got but expected one of: proc foo(args: varargs[string, myproc]) @@ -44,4 +44,3 @@ block: let temp = 12.isNil proc foo(args: varargs[string, myproc]) = discard foo 1 -static: echo "done" \ No newline at end of file diff --git a/tests/errmsgs/tundeclared_routine.nim b/tests/errmsgs/tundeclared_routine.nim index 2f1320fff51ab..0cca27681a4b5 100644 --- a/tests/errmsgs/tundeclared_routine.nim +++ b/tests/errmsgs/tundeclared_routine.nim @@ -5,18 +5,18 @@ nimout: ''' tundeclared_routine.nim(24, 17) Error: attempting to call routine: 'myiter' found tundeclared_routine.myiter(a: string) [iterator declared in tundeclared_routine.nim(22, 12)] found tundeclared_routine.myiter() [iterator declared in tundeclared_routine.nim(23, 12)] +tundeclared_routine.nim(24, 17) Error: expression 'error' has no type (or is ambiguous) tundeclared_routine.nim(29, 28) Error: invalid pragma: myPragma tundeclared_routine.nim(36, 13) Error: undeclared field: 'bar3' for type tundeclared_routine.Foo [type declared in tundeclared_routine.nim(33, 8)] found tundeclared_routine.bar3() [iterator declared in tundeclared_routine.nim(35, 12)] +tundeclared_routine.nim(36, 13) Error: expression 'error' has no type (or is ambiguous) tundeclared_routine.nim(41, 13) Error: undeclared field: 'bar4' for type tundeclared_routine.Foo [type declared in tundeclared_routine.nim(39, 8)] -tundeclared_routine.nim(44, 15) Error: attempting to call routine: 'bad5' +tundeclared_routine.nim(41, 13) Error: expression 'error' has no type (or is ambiguous) +tundeclared_routine.nim(44, 11) Error: undeclared identifier: 'bad5' ''' """ - - - # line 20 block: iterator myiter(a:string): int = discard diff --git a/tests/objects/t17437.nim b/tests/objects/t17437.nim index b5c0e0525405c..b825d97a5472f 100644 --- a/tests/objects/t17437.nim +++ b/tests/objects/t17437.nim @@ -1,12 +1,12 @@ discard """ - cmd: "nim check $file" + cmd: "nim check --hints:off $file" errormsg: "" nimout: ''' t17437.nim(20, 16) Error: undeclared identifier: 'x' -t17437.nim(20, 16) Error: expression 'x' has no type (or is ambiguous) +t17437.nim(20, 16) Error: expression 'error x' has no type (or is ambiguous) t17437.nim(20, 19) Error: incorrect object construction syntax t17437.nim(20, 19) Error: incorrect object construction syntax -t17437.nim(20, 12) Error: expression '' has no type (or is ambiguous) +t17437.nim(20, 12) Error: expression 'error' has no type (or is ambiguous) ''' """ @@ -17,6 +17,6 @@ type x, y: int proc m = - var v = V(x: x, y) + var v = V(x: x, y) # PRTEMP error x m() From ddc826789cea44756ddbcf956b45d87119687de6 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Wed, 28 Apr 2021 13:11:13 -0700 Subject: [PATCH 09/10] fix tests --- tests/errmsgs/t10734.nim | 8 ++++---- tests/errmsgs/t10735.nim | 20 ++++++++++++++------ tests/errmsgs/t16178_nimcheck_redundant.nim | 14 +++++++------- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/tests/errmsgs/t10734.nim b/tests/errmsgs/t10734.nim index 4e73db7cd093f..09703de99730b 100644 --- a/tests/errmsgs/t10734.nim +++ b/tests/errmsgs/t10734.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim check $file" + cmd: "nim check --hints:off $file" errormsg: "" nimout: ''' t10734.nim(19, 1) Error: invalid indentation @@ -7,12 +7,12 @@ t10734.nim(19, 6) Error: invalid indentation t10734.nim(20, 7) Error: expression expected, but found '[EOF]' t10734.nim(18, 5) Error: 'proc' is not a concrete type; for a callback without parameters use 'proc()' t10734.nim(19, 6) Error: undeclared identifier: 'p' -t10734.nim(19, 6) Error: expression 'p' has no type (or is ambiguous) -t10734.nim(19, 6) Error: 'p' cannot be assigned to -t10734.nim(17, 3) Hint: 'T' is declared but not used [XDeclaredButNotUsed] +t10734.nim(19, 6) Error: expression 'error p' has no type (or is ambiguous) +t10734.nim(19, 6) Error: 'error p' cannot be assigned to ''' """ + type T = object a: diff --git a/tests/errmsgs/t10735.nim b/tests/errmsgs/t10735.nim index 307acac2d45bb..bb7396fe8f5fe 100644 --- a/tests/errmsgs/t10735.nim +++ b/tests/errmsgs/t10735.nim @@ -1,10 +1,12 @@ discard """ - cmd: "nim check $file" + cmd: "nim check --hints:off $file" errormsg: "selector must be of an ordinal type, float or string" nimout: ''' -t10735.nim(38, 5) Error: 'let' symbol requires an initialization -t10735.nim(39, 10) Error: undeclared identifier: 'pos' -t10735.nim(39, 9) Error: type mismatch: got +t10735.nim(46, 5) Error: 'let' symbol requires an initialization +t10735.nim(47, 10) Error: undeclared identifier: 'pos' +t10735.nim(47, 10) Error: expression 'error pos' has no type (or is ambiguous) +t10735.nim(47, 10) Error: invalid expression: error pos +t10735.nim(47, 9) Error: type mismatch: got but expected one of: proc `[]`(s: string; i: BackwardsIndex): char first type mismatch at position: 0 @@ -29,12 +31,18 @@ proc `[]`[T](s: var openArray[T]; i: BackwardsIndex): var T template `[]`(s: string; i: int): char first type mismatch at position: 0 -expression: `[]`(buf, pos) -t10735.nim(39, 9) Error: selector must be of an ordinal type, float or string +expression: `[]`(buf, error pos) +t10735.nim(47, 9) Error: selector must be of an ordinal type, float or string ''' joinable: false """ +#[ +PRTEMP: fix: +expression: `[]`(buf, error pos) +]# + +# line 45 let buf: cstring case buf[pos] else: diff --git a/tests/errmsgs/t16178_nimcheck_redundant.nim b/tests/errmsgs/t16178_nimcheck_redundant.nim index 44e52434c81e1..881bb59ab7917 100644 --- a/tests/errmsgs/t16178_nimcheck_redundant.nim +++ b/tests/errmsgs/t16178_nimcheck_redundant.nim @@ -7,21 +7,21 @@ t16178_nimcheck_redundant.nim(32, 11) Error: undeclared identifier: 'bad5' t16178_nimcheck_redundant.nim(36, 11) Error: expression 'error' has no type (or is ambiguous) t16178_nimcheck_redundant.nim(40, 11) Error: expression 'error' has no type (or is ambiguous) t16178_nimcheck_redundant.nim(44, 15) Error: expression 'error' has no type (or is ambiguous) -t16178_nimcheck_redundant.nim(49, 12) Error: undeclared field: 'f1' for type t16178_nimcheck_redundant.A [type declared in t16178_nimcheck_redundant.nim(47, 8)] +t16178_nimcheck_redundant.nim(49, 12) Error: undeclared field: 'f1' for type t16178_nimcheck_redundant.A [type declared in t16178_nimcheck_redundant.nim(47, 8)] t16178_nimcheck_redundant.nim(49, 12) Error: expression 'error' has no type (or is ambiguous) -t16178_nimcheck_redundant.nim(50, 12) Error: undeclared field: 'f2' for type t16178_nimcheck_redundant.A [type declared in t16178_nimcheck_redundant.nim(47, 8)] +t16178_nimcheck_redundant.nim(50, 12) Error: undeclared field: 'f2' for type t16178_nimcheck_redundant.A [type declared in t16178_nimcheck_redundant.nim(47, 8)] t16178_nimcheck_redundant.nim(50, 12) Error: expression 'error' has no type (or is ambiguous) t16178_nimcheck_redundant.nim(51, 8) Error: attempting to call undeclared routine: 'f3=' t16178_nimcheck_redundant.nim(52, 8) Error: attempting to call undeclared routine: 'f4=' ''' """ -#[ -xxx the line `Error: 'let' symbol requires an initialization` is redundant and should not -be reported; likewise with `t16178_nimcheck_redundant.nim(22, 15) Error: expression '' has no type (or is ambiguous)` -TODO: the trailing space `_redundant.nim(47, 8)] ` is bad -]# + + + + + From c95d3821953f757b946ff08e6f19345bae731d39 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Thu, 29 Apr 2021 02:53:38 -0700 Subject: [PATCH 10/10] remove showDiff (moved to another PR) --- testament/testament.nim | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/testament/testament.nim b/testament/testament.nim index 51d85eae862ff..8cf4fdd53cc90 100644 --- a/testament/testament.nim +++ b/testament/testament.nim @@ -318,11 +318,10 @@ proc addResult(r: var TResults, test: TTest, target: TTarget, # expected is empty, no reason to print it. echo given else: - # maybeStyledEcho fgYellow, "Expected:" - # maybeStyledEcho styleBright, expected, "\n" - # maybeStyledEcho fgYellow, "Gotten:" - # maybeStyledEcho styleBright, given, "\n" - showDiff(expected, given) + maybeStyledEcho fgYellow, "Expected:" + maybeStyledEcho styleBright, expected, "\n" + maybeStyledEcho fgYellow, "Gotten:" + maybeStyledEcho styleBright, given, "\n" if backendLogging and (isAppVeyor or isAzure): let (outcome, msg) = @@ -391,8 +390,6 @@ proc nimoutCheck(expected, given: TSpec): bool = result = true if expected.nimoutFull: if expected.nimout != given.nimout: - echo (expected.nimout,) - echo (given.nimout,) result = false elif expected.nimout.len > 0 and not greedyOrderedSubsetLines(expected.nimout, given.nimout): result = false