From ed57eff6e591916bf051999e4762834b33158394 Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 10 Mar 2020 10:39:43 +0100 Subject: [PATCH] fixes #13519 --- changelog.md | 4 ++++ compiler/ast.nim | 7 +++++-- compiler/commands.nim | 6 ++++-- lib/pure/asyncdispatch.nim | 2 +- lib/pure/asyncmacro.nim | 2 +- lib/system/assertions.nim | 2 +- tests/generics/tarc_misc.nim | 21 +++++++++++++++++++++ 7 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 tests/generics/tarc_misc.nim diff --git a/changelog.md b/changelog.md index 49567e9298d82..9c03994638ca7 100644 --- a/changelog.md +++ b/changelog.md @@ -40,6 +40,10 @@ - The `{.dynlib.}` pragma is now required for exporting symbols when making shared objects on POSIX and macOS, which make it consistent with the behavior on Windows. +- The compiler is now more strict about type conversions concerning proc + types: Type conversions cannot be used to hide `.raise` effects or side + effects, instead a `cast` must be used. With the flag `--useVersion:1.0` the + old behaviour is emulated. ## Library additions diff --git a/compiler/ast.nim b/compiler/ast.nim index 43ea2b39c44fb..3b85840418045 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -592,8 +592,11 @@ const tfReturnsNew* = tfInheritable skError* = skUnknown - # type flags that are essential for type equality: - eqTypeFlags* = {tfIterator, tfNotNil, tfVarIsPtr} +var + eqTypeFlags* = {tfIterator, tfNotNil, tfVarIsPtr, tfGcSafe, tfNoSideEffect} + ## type flags that are essential for type equality. + ## This is now a variable because for emulation of version:1.0 we + ## might exclude {tfGcSafe, tfNoSideEffect}. type TMagic* = enum # symbols that require compiler magic: diff --git a/compiler/commands.nim b/compiler/commands.nim index 935d7e2be5f85..0c93654da2874 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -32,6 +32,7 @@ import pathutils, strtabs from incremental import nimIncremental +from ast import eqTypeFlags, tfGcSafe, tfNoSideEffect # but some have deps to imported modules. Yay. bootSwitch(usedTinyC, hasTinyCBackend, "-d:tinyc") @@ -869,10 +870,11 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; of "1.0": defineSymbol(conf.symbols, "NimMajor", "1") defineSymbol(conf.symbols, "NimMinor", "0") - # always be compatible with 1.0.2 for now: - defineSymbol(conf.symbols, "NimPatch", "2") + # always be compatible with 1.0.100: + defineSymbol(conf.symbols, "NimPatch", "100") # old behaviors go here: defineSymbol(conf.symbols, "nimOldRelativePathBehavior") + ast.eqTypeFlags.excl {tfGcSafe, tfNoSideEffect} else: localError(conf, info, "unknown Nim version; currently supported values are: {1.0}") of "benchmarkvm": diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index d724242d7170d..732381ccbfc7b 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -278,7 +278,7 @@ when defined(windows) or defined(nimdoc): result.ioPort = createIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 1) result.handles = initSet[AsyncFD]() result.timers.newHeapQueue() - result.callbacks = initDeque[proc ()](64) + result.callbacks = initDeque[proc () {.closure, gcsafe.}](64) var gDisp{.threadvar.}: owned PDispatcher ## Global dispatcher diff --git a/lib/pure/asyncmacro.nim b/lib/pure/asyncmacro.nim index 11eba427bd346..ce84491eb4f8d 100644 --- a/lib/pure/asyncmacro.nim +++ b/lib/pure/asyncmacro.nim @@ -46,7 +46,7 @@ template createCb(retFutureSym, iteratorNameSym, else: {.gcsafe.}: {.push hint[ConvFromXtoItselfNotNeeded]: off.} - next.callback = (proc() {.closure, gcsafe.})(identName) + next.callback = cast[proc() {.closure, gcsafe.}](identName) {.pop.} except: futureVarCompletions diff --git a/lib/system/assertions.nim b/lib/system/assertions.nim index b918729dc3393..5eb700f4c30ae 100644 --- a/lib/system/assertions.nim +++ b/lib/system/assertions.nim @@ -26,7 +26,7 @@ proc failedAssertImpl*(msg: string) {.raises: [], tags: [].} = # by ``assert``. type Hide = proc (msg: string) {.noinline, raises: [], noSideEffect, tags: [].} - Hide(raiseAssert)(msg) + cast[Hide](raiseAssert)(msg) template assertImpl(cond: bool, msg: string, expr: string, enabled: static[bool]) = when enabled: diff --git a/tests/generics/tarc_misc.nim b/tests/generics/tarc_misc.nim new file mode 100644 index 0000000000000..3e77625565925 --- /dev/null +++ b/tests/generics/tarc_misc.nim @@ -0,0 +1,21 @@ +discard """ + output: '''''' + cmd: "nim c --gc:arc $file" +""" + +# bug #13519 + +var unrelated: seq[proc() {.closure, gcsafe.}] + +unrelated.add proc () = + echo "gcsafe" + +import tables, sequtils +let t = newTable[int, proc()]() + +type + MyProc = proc() {.closure.} + +var result: seq[MyProc] = @[] +for x in t.values: + result.add(x)