fix #2614 improve error message when array of proc calling convention mismatch
This commit is contained in:
parent
f7f375f59d
commit
e13cd40e21
4 changed files with 69 additions and 31 deletions
|
|
@ -1572,6 +1572,7 @@ proc getProcConvMismatch*(c: ConfigRef, f, a: PType, rel = isNone): (set[ProcCon
|
||||||
of isInferred: result[1] = isInferredConvertible
|
of isInferred: result[1] = isInferredConvertible
|
||||||
of isBothMetaConvertible: result[1] = isBothMetaConvertible
|
of isBothMetaConvertible: result[1] = isBothMetaConvertible
|
||||||
elif result[1] != isNone: result[1] = isConvertible
|
elif result[1] != isNone: result[1] = isConvertible
|
||||||
|
else: result[0].incl pcmDifferentCallConv
|
||||||
else:
|
else:
|
||||||
result[1] = isNone
|
result[1] = isNone
|
||||||
result[0].incl pcmDifferentCallConv
|
result[0].incl pcmDifferentCallConv
|
||||||
|
|
@ -1607,6 +1608,25 @@ proc addPragmaAndCallConvMismatch*(message: var string, formal, actual: PType, c
|
||||||
expectedPragmas.setLen(max(0, expectedPragmas.len - 2)) # Remove ", "
|
expectedPragmas.setLen(max(0, expectedPragmas.len - 2)) # Remove ", "
|
||||||
message.add "\n Pragma mismatch: got '{.$1.}', but expected '{.$2.}'." % [gotPragmas, expectedPragmas]
|
message.add "\n Pragma mismatch: got '{.$1.}', but expected '{.$2.}'." % [gotPragmas, expectedPragmas]
|
||||||
|
|
||||||
|
proc processPragmaAndCallConvMismatch(msg: var string, formal, actual: PType, conf: ConfigRef) =
|
||||||
|
if formal.kind == tyProc and actual.kind == tyProc:
|
||||||
|
msg.addPragmaAndCallConvMismatch(formal, actual, conf)
|
||||||
|
case compatibleEffects(formal, actual)
|
||||||
|
of efCompat: discard
|
||||||
|
of efRaisesDiffer:
|
||||||
|
msg.add "\n.raise effects differ"
|
||||||
|
of efRaisesUnknown:
|
||||||
|
msg.add "\n.raise effect is 'can raise any'"
|
||||||
|
of efTagsDiffer:
|
||||||
|
msg.add "\n.tag effects differ"
|
||||||
|
of efTagsUnknown:
|
||||||
|
msg.add "\n.tag effect is 'any tag allowed'"
|
||||||
|
of efLockLevelsDiffer:
|
||||||
|
msg.add "\nlock levels differ"
|
||||||
|
of efEffectsDelayed:
|
||||||
|
msg.add "\n.effectsOf annotations differ"
|
||||||
|
of efTagsIllegal:
|
||||||
|
msg.add "\n.notTag catched an illegal effect"
|
||||||
|
|
||||||
proc typeMismatch*(conf: ConfigRef; info: TLineInfo, formal, actual: PType, n: PNode) =
|
proc typeMismatch*(conf: ConfigRef; info: TLineInfo, formal, actual: PType, n: PNode) =
|
||||||
if formal.kind != tyError and actual.kind != tyError:
|
if formal.kind != tyError and actual.kind != tyError:
|
||||||
|
|
@ -1626,25 +1646,18 @@ proc typeMismatch*(conf: ConfigRef; info: TLineInfo, formal, actual: PType, n: P
|
||||||
msg.add "\n"
|
msg.add "\n"
|
||||||
msg.add " but expected '$1'" % x
|
msg.add " but expected '$1'" % x
|
||||||
if verbose: msg.addDeclaredLoc(conf, formal)
|
if verbose: msg.addDeclaredLoc(conf, formal)
|
||||||
|
var a = formal
|
||||||
if formal.kind == tyProc and actual.kind == tyProc:
|
var b = actual
|
||||||
msg.addPragmaAndCallConvMismatch(formal, actual, conf)
|
if formal.kind == tyArray and actual.kind == tyArray:
|
||||||
case compatibleEffects(formal, actual)
|
a = formal[1]
|
||||||
of efCompat: discard
|
b = actual[1]
|
||||||
of efRaisesDiffer:
|
processPragmaAndCallConvMismatch(msg, a, b, conf)
|
||||||
msg.add "\n.raise effects differ"
|
elif formal.kind == tySequence and actual.kind == tySequence:
|
||||||
of efRaisesUnknown:
|
a = formal[0]
|
||||||
msg.add "\n.raise effect is 'can raise any'"
|
b = actual[0]
|
||||||
of efTagsDiffer:
|
processPragmaAndCallConvMismatch(msg, a, b, conf)
|
||||||
msg.add "\n.tag effects differ"
|
else:
|
||||||
of efTagsUnknown:
|
processPragmaAndCallConvMismatch(msg, a, b, conf)
|
||||||
msg.add "\n.tag effect is 'any tag allowed'"
|
|
||||||
of efLockLevelsDiffer:
|
|
||||||
msg.add "\nlock levels differ"
|
|
||||||
of efEffectsDelayed:
|
|
||||||
msg.add "\n.effectsOf annotations differ"
|
|
||||||
of efTagsIllegal:
|
|
||||||
msg.add "\n.notTag catched an illegal effect"
|
|
||||||
localError(conf, info, msg)
|
localError(conf, info, msg)
|
||||||
|
|
||||||
proc isTupleRecursive(t: PType, cycleDetector: var IntSet): bool =
|
proc isTupleRecursive(t: PType, cycleDetector: var IntSet): bool =
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
discard """
|
discard """
|
||||||
cmd: "nim check $file"
|
cmd: "nim check --hint:Conf:off --hint:XDeclaredButNotUsed:off $file"
|
||||||
nimout: '''
|
nimout: '''
|
||||||
teffects1.nim(17, 28) template/generic instantiation from here
|
teffects1.nim(17, 28) template/generic instantiation from here
|
||||||
'''
|
'''
|
||||||
|
|
@ -27,14 +27,15 @@ proc forw: int =
|
||||||
type
|
type
|
||||||
MyProcType* = proc(x: int): string #{.raises: [ValueError, Defect].}
|
MyProcType* = proc(x: int): string #{.raises: [ValueError, Defect].}
|
||||||
|
|
||||||
proc foo(x: int): string {.raises: [ValueError].} =
|
proc foo(x: int): string {.nimcall, raises: [ValueError].} =
|
||||||
if x > 9:
|
if x > 9:
|
||||||
raise newException(ValueError, "Use single digit")
|
raise newException(ValueError, "Use single digit")
|
||||||
$x
|
$x
|
||||||
|
|
||||||
var p: MyProcType = foo #[tt.Error
|
var p: MyProcType = foo #[tt.Error
|
||||||
^
|
^
|
||||||
type mismatch: got <proc (x: int): string{.noSideEffect, gcsafe, locks: 0.}> but expected 'MyProcType = proc (x: int): string{.closure.}'
|
type mismatch: got <proc (x: int): string{.nimcall, noSideEffect, gcsafe, locks: 0.}> but expected 'MyProcType = proc (x: int): string{.closure.}'
|
||||||
|
Calling convention mismatch: got '{.nimcall.}', but expected '{.closure.}'.
|
||||||
.raise effects differ
|
.raise effects differ
|
||||||
]#
|
]#
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
|
||||||
21
tests/errmsgs/t2614.nim
Normal file
21
tests/errmsgs/t2614.nim
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
discard """
|
||||||
|
cmd: "nim check $options --hints:off $file"
|
||||||
|
errormsg: ""
|
||||||
|
nimout: '''
|
||||||
|
t2614.nim(19, 27) Error: type mismatch: got <array[0..1, proc (){.locks: <unknown>.}]> but expected 'array[0..1, proc (){.closure.}]'
|
||||||
|
Calling convention mismatch: got '{.nimcall.}', but expected '{.closure.}'.
|
||||||
|
t2614.nim(21, 22) Error: type mismatch: got <seq[proc (){.locks: <unknown>.}]> but expected 'seq[proc (){.closure.}]'
|
||||||
|
Calling convention mismatch: got '{.nimcall.}', but expected '{.closure.}'.
|
||||||
|
'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
proc g
|
||||||
|
proc f =
|
||||||
|
if false: g()
|
||||||
|
proc g =
|
||||||
|
if false: f()
|
||||||
|
|
||||||
|
var a = [f, g] # This works
|
||||||
|
var b: array[2, proc()] = [f, g] # Error
|
||||||
|
|
||||||
|
var c: seq[proc()] = @[f, g]
|
||||||
|
|
@ -3,9 +3,9 @@ discard """
|
||||||
cmd: '''nim check --hints:off $options $file'''
|
cmd: '''nim check --hints:off $options $file'''
|
||||||
nimoutFull: true
|
nimoutFull: true
|
||||||
nimout: '''
|
nimout: '''
|
||||||
tproc_mismatch.nim(35, 52) Error: type mismatch: got <proc (a: int, c: float){.cdecl, noSideEffect, gcsafe, locks: 0.}> but expected 'proc (a: int, c: float){.closure, noSideEffect.}'
|
tproc_mismatch.nim(38, 52) Error: type mismatch: got <proc (a: int, c: float){.cdecl, noSideEffect, gcsafe, locks: 0.}> but expected 'proc (a: int, c: float){.closure, noSideEffect.}'
|
||||||
Calling convention mismatch: got '{.cdecl.}', but expected '{.closure.}'.
|
Calling convention mismatch: got '{.cdecl.}', but expected '{.closure.}'.
|
||||||
tproc_mismatch.nim(39, 6) Error: type mismatch: got <proc (){.inline, noSideEffect, gcsafe, locks: 0.}>
|
tproc_mismatch.nim(42, 6) Error: type mismatch: got <proc (){.inline, noSideEffect, gcsafe, locks: 0.}>
|
||||||
but expected one of:
|
but expected one of:
|
||||||
proc bar(a: proc ())
|
proc bar(a: proc ())
|
||||||
first type mismatch at position: 1
|
first type mismatch at position: 1
|
||||||
|
|
@ -14,18 +14,21 @@ proc bar(a: proc ())
|
||||||
Calling convention mismatch: got '{.inline.}', but expected '{.closure.}'.
|
Calling convention mismatch: got '{.inline.}', but expected '{.closure.}'.
|
||||||
|
|
||||||
expression: bar(fn1)
|
expression: bar(fn1)
|
||||||
tproc_mismatch.nim(43, 8) Error: type mismatch: got <proc (){.inline, noSideEffect, gcsafe, locks: 0.}> but expected 'proc (){.closure.}'
|
tproc_mismatch.nim(46, 8) Error: type mismatch: got <proc (){.inline, noSideEffect, gcsafe, locks: 0.}> but expected 'proc (){.closure.}'
|
||||||
Calling convention mismatch: got '{.inline.}', but expected '{.closure.}'.
|
Calling convention mismatch: got '{.inline.}', but expected '{.closure.}'.
|
||||||
tproc_mismatch.nim(48, 8) Error: type mismatch: got <proc (){.locks: 0.}> but expected 'proc (){.closure, noSideEffect.}'
|
tproc_mismatch.nim(51, 8) Error: type mismatch: got <proc (){.locks: 0.}> but expected 'proc (){.closure, noSideEffect.}'
|
||||||
|
Calling convention mismatch: got '{.nimcall.}', but expected '{.closure.}'.
|
||||||
Pragma mismatch: got '{..}', but expected '{.noSideEffect.}'.
|
Pragma mismatch: got '{..}', but expected '{.noSideEffect.}'.
|
||||||
tproc_mismatch.nim(52, 8) Error: type mismatch: got <proc (a: int){.noSideEffect, gcsafe, locks: 0.}> but expected 'proc (a: float){.closure.}'
|
tproc_mismatch.nim(55, 8) Error: type mismatch: got <proc (a: int){.noSideEffect, gcsafe, locks: 0.}> but expected 'proc (a: float){.closure.}'
|
||||||
tproc_mismatch.nim(61, 9) Error: type mismatch: got <proc (a: int){.locks: 0.}> but expected 'proc (a: int){.closure, gcsafe.}'
|
Calling convention mismatch: got '{.nimcall.}', but expected '{.closure.}'.
|
||||||
|
tproc_mismatch.nim(64, 9) Error: type mismatch: got <proc (a: int){.locks: 0.}> but expected 'proc (a: int){.closure, gcsafe.}'
|
||||||
|
Calling convention mismatch: got '{.nimcall.}', but expected '{.closure.}'.
|
||||||
Pragma mismatch: got '{..}', but expected '{.gcsafe.}'.
|
Pragma mismatch: got '{..}', but expected '{.gcsafe.}'.
|
||||||
tproc_mismatch.nim(69, 9) Error: type mismatch: got <proc (a: int): int{.nimcall.}> but expected 'proc (a: int): int{.cdecl.}'
|
tproc_mismatch.nim(72, 9) Error: type mismatch: got <proc (a: int): int{.nimcall.}> but expected 'proc (a: int): int{.cdecl.}'
|
||||||
Calling convention mismatch: got '{.nimcall.}', but expected '{.cdecl.}'.
|
Calling convention mismatch: got '{.nimcall.}', but expected '{.cdecl.}'.
|
||||||
tproc_mismatch.nim(70, 9) Error: type mismatch: got <proc (a: int): int{.cdecl.}> but expected 'proc (a: int): int{.nimcall.}'
|
tproc_mismatch.nim(73, 9) Error: type mismatch: got <proc (a: int): int{.cdecl.}> but expected 'proc (a: int): int{.nimcall.}'
|
||||||
Calling convention mismatch: got '{.cdecl.}', but expected '{.nimcall.}'.
|
Calling convention mismatch: got '{.cdecl.}', but expected '{.nimcall.}'.
|
||||||
tproc_mismatch.nim(74, 9) Error: type mismatch: got <proc (a: int){.closure, locks: 3.}> but expected 'proc (a: int){.closure, locks: 1.}'
|
tproc_mismatch.nim(77, 9) Error: type mismatch: got <proc (a: int){.closure, locks: 3.}> but expected 'proc (a: int){.closure, locks: 1.}'
|
||||||
Pragma mismatch: got '{.locks: 3.}', but expected '{.locks: 1.}'.
|
Pragma mismatch: got '{.locks: 3.}', but expected '{.locks: 1.}'.
|
||||||
lock levels differ
|
lock levels differ
|
||||||
'''
|
'''
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue