diff options
-rw-r--r-- | compiler/types.nim | 51 | ||||
-rw-r--r-- | tests/effects/teffects1.nim | 7 | ||||
-rw-r--r-- | tests/errmsgs/t2614.nim | 21 | ||||
-rw-r--r-- | tests/errmsgs/tproc_mismatch.nim | 21 |
4 files changed, 69 insertions, 31 deletions
diff --git a/compiler/types.nim b/compiler/types.nim index cd7d11b94..0d98becda 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1572,6 +1572,7 @@ proc getProcConvMismatch*(c: ConfigRef, f, a: PType, rel = isNone): (set[ProcCon of isInferred: result[1] = isInferredConvertible of isBothMetaConvertible: result[1] = isBothMetaConvertible elif result[1] != isNone: result[1] = isConvertible + else: result[0].incl pcmDifferentCallConv else: result[1] = isNone 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 ", " 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) = 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 " but expected '$1'" % x if verbose: msg.addDeclaredLoc(conf, formal) - - 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" + var a = formal + var b = actual + if formal.kind == tyArray and actual.kind == tyArray: + a = formal[1] + b = actual[1] + processPragmaAndCallConvMismatch(msg, a, b, conf) + elif formal.kind == tySequence and actual.kind == tySequence: + a = formal[0] + b = actual[0] + processPragmaAndCallConvMismatch(msg, a, b, conf) + else: + processPragmaAndCallConvMismatch(msg, a, b, conf) localError(conf, info, msg) proc isTupleRecursive(t: PType, cycleDetector: var IntSet): bool = diff --git a/tests/effects/teffects1.nim b/tests/effects/teffects1.nim index 3978d8cc2..ca9021999 100644 --- a/tests/effects/teffects1.nim +++ b/tests/effects/teffects1.nim @@ -1,5 +1,5 @@ discard """ - cmd: "nim check $file" + cmd: "nim check --hint:Conf:off --hint:XDeclaredButNotUsed:off $file" nimout: ''' teffects1.nim(17, 28) template/generic instantiation from here ''' @@ -27,14 +27,15 @@ proc forw: int = type 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: raise newException(ValueError, "Use single digit") $x 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 ]# {.pop.} diff --git a/tests/errmsgs/t2614.nim b/tests/errmsgs/t2614.nim new file mode 100644 index 000000000..4034249e7 --- /dev/null +++ b/tests/errmsgs/t2614.nim @@ -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] \ No newline at end of file diff --git a/tests/errmsgs/tproc_mismatch.nim b/tests/errmsgs/tproc_mismatch.nim index 4ddc7635e..f92589d96 100644 --- a/tests/errmsgs/tproc_mismatch.nim +++ b/tests/errmsgs/tproc_mismatch.nim @@ -3,9 +3,9 @@ discard """ cmd: '''nim check --hints:off $options $file''' nimoutFull: true 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.}'. -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: proc bar(a: proc ()) first type mismatch at position: 1 @@ -14,18 +14,21 @@ proc bar(a: proc ()) Calling convention mismatch: got '{.inline.}', but expected '{.closure.}'. 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.}'. -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.}'. -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(61, 9) Error: type mismatch: got <proc (a: int){.locks: 0.}> but expected 'proc (a: int){.closure, gcsafe.}' +tproc_mismatch.nim(55, 8) Error: type mismatch: got <proc (a: int){.noSideEffect, gcsafe, locks: 0.}> but expected 'proc (a: float){.closure.}' + 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.}'. -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.}'. -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.}'. -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.}'. lock levels differ ''' |