diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2019-07-17 16:01:44 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-07-17 16:01:44 +0200 |
commit | e11494f1cf46052d9b81d0f3d799b57b2ebe04f2 (patch) | |
tree | f8ca697e35af77375681171f1e288d88f3240c3c | |
parent | 326860e84c6abdafbf5b5aef49a9f4f59d66162b (diff) | |
parent | 063ae96a66502484d2d1ec841b84cb37953c4adb (diff) | |
download | Nim-e11494f1cf46052d9b81d0f3d799b57b2ebe04f2.tar.gz |
Merge pull request #11680 from timotheecour/pr_fix_sigmatch_errmsg
fixes #8305; fixes #7808; fixes #10285; fixes #11061 + other bugs with type mismatch error msgs
-rw-r--r-- | compiler/semcall.nim | 62 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 57 | ||||
-rw-r--r-- | tests/concepts/t3330.nim | 42 | ||||
-rw-r--r-- | tests/concepts/texplain.nim | 126 | ||||
-rw-r--r-- | tests/destructor/tdont_return_unowned_from_owned.nim | 28 | ||||
-rw-r--r-- | tests/errmsgs/t8434.nim | 2 | ||||
-rw-r--r-- | tests/errmsgs/tdetailed_position.nim | 2 | ||||
-rw-r--r-- | tests/errmsgs/tgcsafety.nim | 2 | ||||
-rw-r--r-- | tests/errmsgs/tsigmatch.nim | 172 | ||||
-rw-r--r-- | tests/errmsgs/tunknown_named_parameter.nim | 4 | ||||
-rw-r--r-- | tests/errmsgs/twrong_at_operator.nim | 10 | ||||
-rw-r--r-- | tests/typerel/t7600_1.nim | 5 | ||||
-rw-r--r-- | tests/typerel/t7600_2.nim | 5 | ||||
-rw-r--r-- | tests/varres/tprevent_forloopvar_mutations.nim | 6 |
14 files changed, 396 insertions, 127 deletions
diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 232a350b8..805a29303 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -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) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 655ee83f0..4a6bf66e7 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -19,12 +19,22 @@ when (defined(booting) or defined(nimsuggest)) and not defined(leanCompiler): import docgen type + MismatchKind* = enum + kUnknown, kAlreadyGiven, kUnknownNamedParam, kTypeMismatch, kVarNeeded, + kMissingParam, kExtraArg + + MismatchInfo* = object + kind*: MismatchKind # reason for mismatch + arg*: int # position of provided arguments that mismatches + formal*: PSym # parameter that mismatches against provided argument + # its position can differ from `arg` because of varargs + TCandidateState* = enum csEmpty, csMatch, csNoMatch CandidateError* = object sym*: PSym - unmatchedVarParam*, firstMismatch*: int + firstMismatch*: MismatchInfo diagnostics*: seq[string] enabled*: bool @@ -56,7 +66,6 @@ type # a distrinct type typedescMatched*: bool isNoCall*: bool # misused for generic type instantiations C[T] - mutabilityProblem*: uint8 # tyVar mismatch inferredTypes: seq[PType] # inferred types during the current signature # matching. they will be reset if the matching # is not successful. may replace the bindings @@ -70,8 +79,7 @@ type # triggered with an idetools command in the # future. inheritancePenalty: int # to prefer closest father object type - firstMismatch*: int # position of the first type mismatch for - # better error messages + firstMismatch*: MismatchInfo # mismatch info for better error messages diagnosticsEnabled*: bool TTypeRelFlag* = enum @@ -112,6 +120,7 @@ proc initCandidateAux(ctx: PContext, c.intConvMatches = 0 c.genericMatches = 0 c.state = csEmpty + c.firstMismatch = MismatchInfo() c.callee = callee c.call = nil c.baseTypeMatch = false @@ -2280,6 +2289,17 @@ template isVarargsUntyped(x): untyped = proc matchesAux(c: PContext, n, nOrig: PNode, m: var TCandidate, marker: var IntSet) = + var + a = 1 # iterates over the actual given arguments + f = if m.callee.kind != tyGenericBody: 1 + else: 0 # iterates over formal parameters + arg: PNode # current prepared argument + formal: PSym # current routine parameter + + defer: + m.firstMismatch.arg = a + m.firstMismatch.formal = formal + template checkConstraint(n: untyped) {.dirty.} = if not formal.constraint.isNil: if matchNodeKinds(formal.constraint, n): @@ -2294,28 +2314,21 @@ proc matchesAux(c: PContext, n, nOrig: PNode, if argConverter.kind == nkHiddenCallConv: if argConverter.typ.kind != tyVar: m.state = csNoMatch - m.mutabilityProblem = uint8(f-1) + m.firstMismatch.kind = kVarNeeded return elif not n.isLValue: m.state = csNoMatch - m.mutabilityProblem = uint8(f-1) + m.firstMismatch.kind = kVarNeeded return - var - # iterates over formal parameters - f = if m.callee.kind != tyGenericBody: 1 - else: 0 - # iterates over the actual given arguments - a = 1 - arg: PNode # current prepared argument - m.state = csMatch # until proven otherwise + m.firstMismatch = MismatchInfo() m.call = newNodeI(n.kind, n.info) m.call.typ = base(m.callee) # may be nil var formalLen = m.callee.n.len addSon(m.call, copyTree(n.sons[0])) var container: PNode = nil # constructed container - var formal: PSym = if formalLen > 1: m.callee.n.sons[1].sym else: nil + formal = if formalLen > 1: m.callee.n.sons[1].sym else: nil while a < n.len: if a >= formalLen-1 and f < formalLen and m.callee.n[f].typ.isVarargsUntyped: @@ -2336,20 +2349,20 @@ proc matchesAux(c: PContext, n, nOrig: PNode, addSon(container, n.sons[a]) elif n.sons[a].kind == nkExprEqExpr: # named param + m.firstMismatch.kind = kUnknownNamedParam # check if m.callee has such a param: prepareNamedParam(n.sons[a], c) if n.sons[a].sons[0].kind != nkIdent: localError(c.config, n.sons[a].info, "named parameter has to be an identifier") m.state = csNoMatch - m.firstMismatch = -a return formal = getSymFromList(m.callee.n, n.sons[a].sons[0].ident, 1) if formal == nil: # no error message! m.state = csNoMatch - m.firstMismatch = -a return if containsOrIncl(marker, formal.position): + m.firstMismatch.kind = kAlreadyGiven # already in namedParams, so no match # we used to produce 'errCannotBindXTwice' here but see # bug #3836 of why that is not sound (other overload with @@ -2363,9 +2376,9 @@ proc matchesAux(c: PContext, n, nOrig: PNode, n.sons[a].typ = n.sons[a].sons[1].typ arg = paramTypesMatch(m, formal.typ, n.sons[a].typ, n.sons[a].sons[1], n.sons[a].sons[1]) + m.firstMismatch.kind = kTypeMismatch if arg == nil: m.state = csNoMatch - m.firstMismatch = a return checkConstraint(n.sons[a].sons[1]) if m.baseTypeMatch: @@ -2392,6 +2405,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, else: addSon(m.call, copyTree(n.sons[a])) elif formal != nil and formal.typ.kind == tyVarargs: + m.firstMismatch.kind = kTypeMismatch # beware of the side-effects in 'prepareOperand'! So only do it for # varargs matching. See tests/metatype/tstatic_overloading. m.baseTypeMatch = false @@ -2408,6 +2422,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, m.state = csNoMatch return else: + m.firstMismatch.kind = kExtraArg m.state = csNoMatch return else: @@ -2415,7 +2430,9 @@ proc matchesAux(c: PContext, n, nOrig: PNode, internalError(c.config, n.sons[a].info, "matches") return formal = m.callee.n.sons[f].sym + m.firstMismatch.kind = kTypeMismatch if containsOrIncl(marker, formal.position) and container.isNil: + m.firstMismatch.kind = kAlreadyGiven # already in namedParams: (see above remark) when false: localError(n.sons[a].info, errCannotBindXTwice, formal.name.s) m.state = csNoMatch @@ -2436,7 +2453,6 @@ proc matchesAux(c: PContext, n, nOrig: PNode, n.sons[a], nOrig.sons[a]) if arg == nil: m.state = csNoMatch - m.firstMismatch = f return if m.baseTypeMatch: assert formal.typ.kind == tyVarargs @@ -2510,7 +2526,8 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) = else: # no default value m.state = csNoMatch - m.firstMismatch = f + m.firstMismatch.kind = kMissingParam + m.firstMismatch.formal = formal break else: if formal.ast.kind == nkEmpty: diff --git a/tests/concepts/t3330.nim b/tests/concepts/t3330.nim index a1ad96f2b..6bf52f3aa 100644 --- a/tests/concepts/t3330.nim +++ b/tests/concepts/t3330.nim @@ -1,49 +1,63 @@ discard """ errormsg: "type mismatch: got <Bar[system.int]>" -disabled: "true" +disabled: "32bit" nimout: ''' -t3330.nim(63, 4) Error: type mismatch: got <Bar[system.int]> +t3330.nim(78, 4) Error: type mismatch: got <Bar[system.int]> but expected one of: proc test(foo: Foo[int]) -t3330.nim(48, 8) Hint: Non-matching candidates for add(k, string, T) + first type mismatch at position: 1 + required type for foo: Foo[int] + but expression 'bar' is of type: Bar[system.int] +t3330.nim(63, 8) Hint: Non-matching candidates for add(k, string, T) proc add[T](x: var seq[T]; y: openArray[T]) first type mismatch at position: 1 - required type: var seq[T] + required type for x: var seq[T] but expression 'k' is of type: Alias proc add(result: var string; x: float) first type mismatch at position: 1 - required type: var string + required type for result: var string but expression 'k' is of type: Alias proc add(x: var string; y: string) first type mismatch at position: 1 - required type: var string + required type for x: var string but expression 'k' is of type: Alias proc add(x: var string; y: cstring) first type mismatch at position: 1 - required type: var string + required type for x: var string but expression 'k' is of type: Alias proc add[T](x: var seq[T]; y: T) first type mismatch at position: 1 - required type: var seq[T] + required type for x: var seq[T] but expression 'k' is of type: Alias proc add(result: var string; x: int64) first type mismatch at position: 1 - required type: var string + required type for result: var string but expression 'k' is of type: Alias proc add(x: var string; y: char) first type mismatch at position: 1 - required type: var string + required type for x: var string but expression 'k' is of type: Alias -t3330.nim(48, 8) template/generic instantiation of `add` from here -t3330.nim(55, 6) Foo: 'bar.value' cannot be assigned to -t3330.nim(48, 8) template/generic instantiation of `add` from here -t3330.nim(56, 6) Foo: 'bar.x' cannot be assigned to +t3330.nim(63, 8) template/generic instantiation of `add` from here +t3330.nim(70, 6) Foo: 'bar.value' cannot be assigned to +t3330.nim(63, 8) template/generic instantiation of `add` from here +t3330.nim(71, 6) Foo: 'bar.x' cannot be assigned to expression: test(bar)''' """ +# Note: currently disabled on 32bit because the candidates are presented in +# different order on travis with `NIM_COMPILE_TO_CPP=false CPU=i386`; +# a possible fix would be to sort the candidates by proc signature or +# declaration location + + + + + + +## line 60 type Foo[T] = concept k add(k, string, T) diff --git a/tests/concepts/texplain.nim b/tests/concepts/texplain.nim index 4ec848732..f3d70320f 100644 --- a/tests/concepts/texplain.nim +++ b/tests/concepts/texplain.nim @@ -2,69 +2,101 @@ discard """ cmd: "nim c --verbosity:0 --colors:off $file" nimout: ''' Hint: texplain [Processing] -texplain.nim(118, 10) Hint: Non-matching candidates for e(y) +texplain.nim(158, 10) Hint: Non-matching candidates for e(y) proc e(i: int): int + first type mismatch at position: 1 + required type for i: int + but expression 'y' is of type: MatchingType -texplain.nim(121, 7) Hint: Non-matching candidates for e(10) +texplain.nim(161, 7) Hint: Non-matching candidates for e(10) proc e(o: ExplainedConcept): int -texplain.nim(84, 6) ExplainedConcept: undeclared field: 'foo' -texplain.nim(84, 6) ExplainedConcept: undeclared field: '.' -texplain.nim(84, 6) ExplainedConcept: expression '.' cannot be called -texplain.nim(84, 5) ExplainedConcept: concept predicate failed -texplain.nim(85, 6) ExplainedConcept: undeclared field: 'bar' -texplain.nim(85, 6) ExplainedConcept: undeclared field: '.' -texplain.nim(85, 6) ExplainedConcept: expression '.' cannot be called -texplain.nim(84, 5) ExplainedConcept: concept predicate failed - -texplain.nim(124, 10) Hint: Non-matching candidates for e(10) + first type mismatch at position: 1 + required type for o: ExplainedConcept + but expression '10' is of type: int literal(10) +texplain.nim(124, 6) ExplainedConcept: undeclared field: 'foo' +texplain.nim(124, 6) ExplainedConcept: undeclared field: '.' +texplain.nim(124, 6) ExplainedConcept: expression '.' cannot be called +texplain.nim(124, 5) ExplainedConcept: concept predicate failed +texplain.nim(125, 6) ExplainedConcept: undeclared field: 'bar' +texplain.nim(125, 6) ExplainedConcept: undeclared field: '.' +texplain.nim(125, 6) ExplainedConcept: expression '.' cannot be called +texplain.nim(124, 5) ExplainedConcept: concept predicate failed + +texplain.nim(164, 10) Hint: Non-matching candidates for e(10) proc e(o: ExplainedConcept): int -texplain.nim(84, 6) ExplainedConcept: undeclared field: 'foo' -texplain.nim(84, 6) ExplainedConcept: undeclared field: '.' -texplain.nim(84, 6) ExplainedConcept: expression '.' cannot be called -texplain.nim(84, 5) ExplainedConcept: concept predicate failed -texplain.nim(85, 6) ExplainedConcept: undeclared field: 'bar' -texplain.nim(85, 6) ExplainedConcept: undeclared field: '.' -texplain.nim(85, 6) ExplainedConcept: expression '.' cannot be called -texplain.nim(84, 5) ExplainedConcept: concept predicate failed - -texplain.nim(128, 20) Error: type mismatch: got <NonMatchingType> + first type mismatch at position: 1 + required type for o: ExplainedConcept + but expression '10' is of type: int literal(10) +texplain.nim(124, 6) ExplainedConcept: undeclared field: 'foo' +texplain.nim(124, 6) ExplainedConcept: undeclared field: '.' +texplain.nim(124, 6) ExplainedConcept: expression '.' cannot be called +texplain.nim(124, 5) ExplainedConcept: concept predicate failed +texplain.nim(125, 6) ExplainedConcept: undeclared field: 'bar' +texplain.nim(125, 6) ExplainedConcept: undeclared field: '.' +texplain.nim(125, 6) ExplainedConcept: expression '.' cannot be called +texplain.nim(124, 5) ExplainedConcept: concept predicate failed + +texplain.nim(168, 20) Error: type mismatch: got <NonMatchingType> but expected one of: proc e(o: ExplainedConcept): int -texplain.nim(128, 9) template/generic instantiation of `assert` from here -texplain.nim(84, 5) ExplainedConcept: concept predicate failed + first type mismatch at position: 1 + required type for o: ExplainedConcept + but expression 'n' is of type: NonMatchingType +texplain.nim(168, 9) template/generic instantiation of `assert` from here +texplain.nim(124, 5) ExplainedConcept: concept predicate failed proc e(i: int): int + first type mismatch at position: 1 + required type for i: int + but expression 'n' is of type: NonMatchingType expression: e(n) -texplain.nim(129, 20) Error: type mismatch: got <NonMatchingType> +texplain.nim(169, 20) Error: type mismatch: got <NonMatchingType> but expected one of: proc r(o: RegularConcept): int -texplain.nim(129, 9) template/generic instantiation of `assert` from here -texplain.nim(88, 5) RegularConcept: concept predicate failed + first type mismatch at position: 1 + required type for o: RegularConcept + but expression 'n' is of type: NonMatchingType +texplain.nim(169, 9) template/generic instantiation of `assert` from here +texplain.nim(128, 5) RegularConcept: concept predicate failed proc r[T](a: SomeNumber; b: T; c: auto) + first type mismatch at position: 1 + required type for a: SomeNumber + but expression 'n' is of type: NonMatchingType proc r(i: string): int + first type mismatch at position: 1 + required type for i: string + but expression 'n' is of type: NonMatchingType expression: r(n) -texplain.nim(130, 20) Hint: Non-matching candidates for r(y) +texplain.nim(170, 20) Hint: Non-matching candidates for r(y) proc r[T](a: SomeNumber; b: T; c: auto) + first type mismatch at position: 1 + required type for a: SomeNumber + but expression 'y' is of type: MatchingType proc r(i: string): int + first type mismatch at position: 1 + required type for i: string + but expression 'y' is of type: MatchingType -texplain.nim(138, 2) Error: type mismatch: got <MatchingType> +texplain.nim(178, 2) Error: type mismatch: got <MatchingType> but expected one of: proc f(o: NestedConcept) -texplain.nim(88, 6) RegularConcept: undeclared field: 'foo' -texplain.nim(88, 6) RegularConcept: undeclared field: '.' -texplain.nim(88, 6) RegularConcept: expression '.' cannot be called -texplain.nim(88, 5) RegularConcept: concept predicate failed -texplain.nim(89, 6) RegularConcept: undeclared field: 'bar' -texplain.nim(89, 6) RegularConcept: undeclared field: '.' -texplain.nim(89, 6) RegularConcept: expression '.' cannot be called -texplain.nim(88, 5) RegularConcept: concept predicate failed -texplain.nim(92, 5) NestedConcept: concept predicate failed - -expression: f(y) -''' + first type mismatch at position: 1 + required type for o: NestedConcept + but expression 'y' is of type: MatchingType +texplain.nim(128, 6) RegularConcept: undeclared field: 'foo' +texplain.nim(128, 6) RegularConcept: undeclared field: '.' +texplain.nim(128, 6) RegularConcept: expression '.' cannot be called +texplain.nim(128, 5) RegularConcept: concept predicate failed +texplain.nim(129, 6) RegularConcept: undeclared field: 'bar' +texplain.nim(129, 6) RegularConcept: undeclared field: '.' +texplain.nim(129, 6) RegularConcept: expression '.' cannot be called +texplain.nim(128, 5) RegularConcept: concept predicate failed +texplain.nim(132, 5) NestedConcept: concept predicate failed + +expression: f(y)''' errormsg: "type mismatch: got <MatchingType>" - line: 138 + line: 178 disabled: 32bit """ @@ -77,7 +109,15 @@ expression: f(y) -# line 80 HERE + + + + + + + + +# line 120 HERE type ExplainedConcept {.explain.} = concept o diff --git a/tests/destructor/tdont_return_unowned_from_owned.nim b/tests/destructor/tdont_return_unowned_from_owned.nim index 5794dec1d..a726960c6 100644 --- a/tests/destructor/tdont_return_unowned_from_owned.nim +++ b/tests/destructor/tdont_return_unowned_from_owned.nim @@ -1,21 +1,33 @@ discard """ cmd: "nim check --newruntime --hints:off $file" - nimout: '''tdont_return_unowned_from_owned.nim(24, 10) Error: cannot return an owned pointer as an unowned pointer; use 'owned(Obj)' as the return type -tdont_return_unowned_from_owned.nim(27, 10) Error: cannot return an owned pointer as an unowned pointer; use 'owned(Obj)' as the return type -tdont_return_unowned_from_owned.nim(30, 6) Error: type mismatch: got <Obj> + nimout: '''tdont_return_unowned_from_owned.nim(36, 10) Error: cannot return an owned pointer as an unowned pointer; use 'owned(Obj)' as the return type +tdont_return_unowned_from_owned.nim(39, 10) Error: cannot return an owned pointer as an unowned pointer; use 'owned(Obj)' as the return type +tdont_return_unowned_from_owned.nim(42, 6) Error: type mismatch: got <Obj> but expected one of: proc new[T](a: var ref T; finalizer: proc (x: ref T) {.nimcall.}) + first type mismatch at position: 2 + missing parameter: finalizer 2 other mismatching symbols have been suppressed; compile with --showAllMismatches:on to see them expression: new(result) -tdont_return_unowned_from_owned.nim(30, 6) Error: illformed AST: -tdont_return_unowned_from_owned.nim(38, 13) Error: assignment produces a dangling ref: the unowned ref lives longer than the owned ref -tdont_return_unowned_from_owned.nim(39, 13) Error: assignment produces a dangling ref: the unowned ref lives longer than the owned ref -tdont_return_unowned_from_owned.nim(43, 10) Error: cannot return an owned pointer as an unowned pointer; use 'owned(RootRef)' as the return type +tdont_return_unowned_from_owned.nim(42, 6) Error: illformed AST: +tdont_return_unowned_from_owned.nim(50, 13) Error: assignment produces a dangling ref: the unowned ref lives longer than the owned ref +tdont_return_unowned_from_owned.nim(51, 13) Error: assignment produces a dangling ref: the unowned ref lives longer than the owned ref +tdont_return_unowned_from_owned.nim(55, 10) Error: cannot return an owned pointer as an unowned pointer; use 'owned(RootRef)' as the return type ''' errormsg: "cannot return an owned pointer as an unowned pointer; use 'owned(RootRef)' as the return type" - line: 43 + line: 55 """ + + + + + + + + + +## line 30 # bug #11073 type Obj = ref object diff --git a/tests/errmsgs/t8434.nim b/tests/errmsgs/t8434.nim index b37468111..ada38e9c0 100644 --- a/tests/errmsgs/t8434.nim +++ b/tests/errmsgs/t8434.nim @@ -4,7 +4,7 @@ discard """ proc fun0[T1: int | float | object | array | seq](a1: T1; a2: int) first type mismatch at position: 1 - required type: T1: int or float or object or array or seq[T] + required type for a1: T1: int or float or object or array or seq[T] but expression 'byte(1)' is of type: byte expression: fun0(byte(1), 0) diff --git a/tests/errmsgs/tdetailed_position.nim b/tests/errmsgs/tdetailed_position.nim index ce5b18bbd..ecece7972 100644 --- a/tests/errmsgs/tdetailed_position.nim +++ b/tests/errmsgs/tdetailed_position.nim @@ -6,7 +6,7 @@ nimout: ''' but expected one of: proc main(a, b, c: string) first type mismatch at position: 1 - required type: string + required type for a: string but expression '1' is of type: int literal(1) expression: main(1, 2, 3) diff --git a/tests/errmsgs/tgcsafety.nim b/tests/errmsgs/tgcsafety.nim index 0ae60f200..e6a62204e 100644 --- a/tests/errmsgs/tgcsafety.nim +++ b/tests/errmsgs/tgcsafety.nim @@ -8,7 +8,7 @@ proc serve(server: AsyncHttpServer; port: Port; callback: proc (request: Request): Future[void] {.closure, gcsafe.}; address = ""): owned(Future[void]) first type mismatch at position: 3 - required type: proc (request: Request): Future[system.void]{.closure, gcsafe.} + required type for callback: proc (request: Request): Future[system.void]{.closure, gcsafe.} but expression 'cb' is of type: proc (req: Request): Future[system.void]{.locks: <unknown>.} This expression is not GC-safe. Annotate the proc with {.gcsafe.} to get extended error information. diff --git a/tests/errmsgs/tsigmatch.nim b/tests/errmsgs/tsigmatch.nim new file mode 100644 index 000000000..42a98a891 --- /dev/null +++ b/tests/errmsgs/tsigmatch.nim @@ -0,0 +1,172 @@ +discard """ + cmd: "nim check --showAllMismatches:on --hints:off $file" + nimout: ''' +tsigmatch.nim(111, 4) Error: type mismatch: got <A, string> +but expected one of: +proc f(b: B) + first type mismatch at position: 1 + required type for b: B + but expression 'A()' is of type: A +proc f(a: A) + first type mismatch at position: 2 + extra argument given + +expression: f(A(), "extra") +tsigmatch.nim(125, 6) Error: type mismatch: got <tuple of (string, proc (){.gcsafe, locks: 0.})> +but expected one of: +proc foo(x: (string, proc ())) + first type mismatch at position: 1 + required type for x: tuple of (string, proc (){.closure.}) + but expression '("foobar", proc () = echo(["Hello!"]))' is of type: tuple of (string, proc (){.gcsafe, locks: 0.}) + +expression: foo(("foobar", proc () = echo(["Hello!"]))) +tsigmatch.nim(132, 11) Error: type mismatch: got <proc (s: string): string{.noSideEffect, gcsafe, locks: 0.}> +but expected one of: +proc foo[T, S](op: proc (x: T): S {.cdecl.}): auto + first type mismatch at position: 1 + required type for op: proc (x: T): S{.cdecl.} + but expression 'fun' is of type: proc (s: string): string{.noSideEffect, gcsafe, locks: 0.} +proc foo[T, S](op: proc (x: T): S {.safecall.}): auto + first type mismatch at position: 1 + required type for op: proc (x: T): S{.safecall.} + but expression 'fun' is of type: proc (s: string): string{.noSideEffect, gcsafe, locks: 0.} + +expression: foo(fun) +tsigmatch.nim(143, 13) Error: type mismatch: got <array[0..0, proc (x: int){.gcsafe, locks: 0.}]> +but expected one of: +proc takesFuncs(fs: openArray[proc (x: int) {.gcsafe, locks: 0.}]) + first type mismatch at position: 1 + required type for fs: openarray[proc (x: int){.closure, gcsafe, locks: 0.}] + but expression '[proc (x: int) {.gcsafe, locks: 0.} = echo [x]]' is of type: array[0..0, proc (x: int){.gcsafe, locks: 0.}] + +expression: takesFuncs([proc (x: int) {.gcsafe, locks: 0.} = echo [x]]) +tsigmatch.nim(149, 4) Error: type mismatch: got <int literal(10), a0: int literal(5), string> +but expected one of: +proc f(a0: uint8; b: string) + first type mismatch at position: 2 + named param already provided: a0 + +expression: f(10, a0 = 5, "") +tsigmatch.nim(156, 4) Error: type mismatch: got <string, string, string, string, string, float64, string> +but expected one of: +proc f(a1: int) + first type mismatch at position: 1 + required type for a1: int + but expression '"asdf"' is of type: string +proc f(a1: string; a2: varargs[string]; a3: float; a4: var string) + first type mismatch at position: 7 + required type for a4: var string + but expression '"bad"' is immutable, not 'var' + +expression: f("asdf", "1", "2", "3", "4", 2.3, "bad") +tsigmatch.nim(164, 4) Error: type mismatch: got <string, a0: int literal(12)> +but expected one of: +proc f(x: string; a0: var int) + first type mismatch at position: 2 + required type for a0: var int + but expression 'a0 = 12' is immutable, not 'var' +proc f(x: string; a0: string) + first type mismatch at position: 2 + required type for a0: string + but expression 'a0 = 12' is of type: int literal(12) + +expression: f(foo, a0 = 12) +tsigmatch.nim(171, 7) Error: type mismatch: got <Mystring, string> +but expected one of: +proc fun1(a1: MyInt; a2: Mystring) + first type mismatch at position: 1 + required type for a1: MyInt + but expression 'default(Mystring)' is of type: Mystring +proc fun1(a1: float; a2: Mystring) + first type mismatch at position: 1 + required type for a1: float + but expression 'default(Mystring)' is of type: Mystring + +expression: fun1(default(Mystring), "asdf") +''' + errormsg: "type mismatch" +""" + + + + + + + + + + + +## line 100 +block: + # bug #11061 Type mismatch error "first type mismatch at" points to wrong argument/position + # Note: the error msg now gives correct position for mismatched argument + type + A = object of RootObj + B = object of A + + proc f(b: B) = discard + proc f(a: A) = discard + + f(A(), "extra") +#[ +this one is similar but error msg was even more misleading, since the user +would think float != float64 where in fact the issue is another param: +first type mismatch at position: 1; required type: float; but expression 'x = 1.2' is of type: float64 + proc f(x: string, a0 = 0, a1 = 0, a2 = 0) = discard + proc f(x: float, a0 = 0, a1 = 0, a2 = 0) = discard + f(x = float(1.2), a0 = 0, a0 = 0) +]# + +block: + # bug #7808 Passing tuple with proc leads to confusing errors + # Note: the error message now shows `closure` which helps debugging the issue + proc foo(x: (string, proc ())) = x[1]() + foo(("foobar", proc () = echo("Hello!"))) + +block: + # bug #8305 type mismatch error drops crucial pragma info when there's only 1 argument + proc fun(s: string): string {. .} = discard + proc foo[T, S](op: proc (x: T): S {. cdecl .}): auto = 1 + proc foo[T, S](op: proc (x: T): S {. safecall .}): auto = 1 + echo foo(fun) + +block: + # bug #10285 Function signature don't match when inside seq/array/openarray + # Note: the error message now shows `closure` which helps debugging the issue + # out why it doesn't match + proc takesFunc(f: proc (x: int) {.gcsafe, locks: 0.}) = + echo "takes single Func" + proc takesFuncs(fs: openarray[proc (x: int) {.gcsafe, locks: 0.}]) = + echo "takes multiple Func" + takesFunc(proc (x: int) {.gcsafe, locks: 0.} = echo x) # works + takesFuncs([proc (x: int) {.gcsafe, locks: 0.} = echo x]) # fails + +block: + # bug https://github.com/nim-lang/Nim/issues/11061#issuecomment-508970465 + # better fix for removal of `errCannotBindXTwice` due to #3836 + proc f(a0: uint8, b: string) = discard + f(10, a0 = 5, "") + +block: + # bug: https://github.com/nim-lang/Nim/issues/11061#issuecomment-508969796 + # sigmatch gets confused with param/arg position after varargs + proc f(a1: int) = discard + proc f(a1: string, a2: varargs[string], a3: float, a4: var string) = discard + f("asdf", "1", "2", "3", "4", 2.3, "bad") + +block: + # bug: https://github.com/nim-lang/Nim/issues/11061#issuecomment-508970046 + # err msg incorrectly said something is immutable + proc f(x: string, a0: var int) = discard + proc f(x: string, a0: string) = discard + var foo = "" + f(foo, a0 = 12) + +block: + type Mystring = string + type MyInt = int + proc fun1(a1: MyInt, a2: Mystring) = discard + proc fun1(a1: float, a2: Mystring) = discard + fun1(Mystring.default, "asdf") + diff --git a/tests/errmsgs/tunknown_named_parameter.nim b/tests/errmsgs/tunknown_named_parameter.nim index 3051787ea..e9be23068 100644 --- a/tests/errmsgs/tunknown_named_parameter.nim +++ b/tests/errmsgs/tunknown_named_parameter.nim @@ -4,14 +4,14 @@ errormsg: "type mismatch: got <string, set[char], maxsplits: int literal(1)>" nimout: ''' proc rsplit(s: string; sep: char; maxsplit: int = -1): seq[string] first type mismatch at position: 2 - required type: char + required type for sep: char but expression '{':'}' is of type: set[char] proc rsplit(s: string; seps: set[char] = Whitespace; maxsplit: int = -1): seq[string] first type mismatch at position: 3 unknown named parameter: maxsplits proc rsplit(s: string; sep: string; maxsplit: int = -1): seq[string] first type mismatch at position: 2 - required type: string + required type for sep: string but expression '{':'}' is of type: set[char] expression: rsplit("abc:def", {':'}, maxsplits = 1) diff --git a/tests/errmsgs/twrong_at_operator.nim b/tests/errmsgs/twrong_at_operator.nim index 5413515cb..7ce077003 100644 --- a/tests/errmsgs/twrong_at_operator.nim +++ b/tests/errmsgs/twrong_at_operator.nim @@ -1,11 +1,17 @@ discard """ errormsg: "type mismatch: got <array[0..0, type int]>" -line: 16 +line: 22 nimout: ''' -twrong_at_operator.nim(16, 30) Error: type mismatch: got <array[0..0, type int]> +twrong_at_operator.nim(22, 30) Error: type mismatch: got <array[0..0, type int]> but expected one of: proc `@`[T](a: openArray[T]): seq[T] + first type mismatch at position: 1 + required type for a: openarray[T] + but expression '[int]' is of type: array[0..0, type int] proc `@`[IDX, T](a: array[IDX, T]): seq[T] + first type mismatch at position: 1 + required type for a: array[IDX, T] + but expression '[int]' is of type: array[0..0, type int] expression: @[int] ''' diff --git a/tests/typerel/t7600_1.nim b/tests/typerel/t7600_1.nim index e3a5fefa2..e9d01bd0d 100644 --- a/tests/typerel/t7600_1.nim +++ b/tests/typerel/t7600_1.nim @@ -1,8 +1,11 @@ discard """ errormsg: "type mismatch: got <Thin[system.int]>" -nimout: '''t7600_1.nim(18, 6) Error: type mismatch: got <Thin[system.int]> +nimout: '''t7600_1.nim(21, 6) Error: type mismatch: got <Thin[system.int]> but expected one of: proc test[T](x: Paper[T]) + first type mismatch at position: 1 + required type for x: Paper[test.T] + but expression 'tn' is of type: Thin[system.int] expression: test tn''' """ diff --git a/tests/typerel/t7600_2.nim b/tests/typerel/t7600_2.nim index 7badb69cf..371707f4c 100644 --- a/tests/typerel/t7600_2.nim +++ b/tests/typerel/t7600_2.nim @@ -1,8 +1,11 @@ discard """ errormsg: "type mismatch: got <Thin>" -nimout: '''t7600_2.nim(17, 6) Error: type mismatch: got <Thin> +nimout: '''t7600_2.nim(20, 6) Error: type mismatch: got <Thin> but expected one of: proc test(x: Paper) + first type mismatch at position: 1 + required type for x: Paper + but expression 'tn' is of type: Thin expression: test tn''' """ diff --git a/tests/varres/tprevent_forloopvar_mutations.nim b/tests/varres/tprevent_forloopvar_mutations.nim index 43cc04f30..398191658 100644 --- a/tests/varres/tprevent_forloopvar_mutations.nim +++ b/tests/varres/tprevent_forloopvar_mutations.nim @@ -1,10 +1,12 @@ discard """ errmsg: "type mismatch: got <int>" - line: 15 + line: 17 nimout: '''type mismatch: got <int> but expected one of: proc inc[T: Ordinal | uint | uint64](x: var T; y = 1) - for a 'var' type a variable needs to be passed, but 'i' is immutable + first type mismatch at position: 1 + required type for x: var T: Ordinal or uint or uint64 + but expression 'i' is immutable, not 'var' expression: inc i ''' |