mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-18 21:40:32 +00:00
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
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
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(124, 10) Hint: Non-matching candidates for e(10)
|
||||
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
|
||||
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(128, 20) Error: type mismatch: got <NonMatchingType>
|
||||
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
|
||||
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)
|
||||
'''
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
172
tests/errmsgs/tsigmatch.nim
Normal file
172
tests/errmsgs/tsigmatch.nim
Normal file
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]
|
||||
'''
|
||||
|
||||
@@ -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'''
|
||||
"""
|
||||
|
||||
@@ -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'''
|
||||
"""
|
||||
|
||||
@@ -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
|
||||
'''
|
||||
|
||||
Reference in New Issue
Block a user