summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/commands.nim1
-rw-r--r--compiler/options.nim1
-rw-r--r--compiler/pragmas.nim6
-rw-r--r--compiler/semtypes.nim6
-rw-r--r--tests/effects/teffects1.nim23
5 files changed, 32 insertions, 5 deletions
diff --git a/compiler/commands.nim b/compiler/commands.nim
index bc6fdde8f..024e6b417 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -877,6 +877,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
       # old behaviors go here:
       defineSymbol(conf.symbols, "nimOldRelativePathBehavior")
       ast.eqTypeFlags.excl {tfGcSafe, tfNoSideEffect}
+      conf.globalOptions.incl optNimV1Emulation
     else:
       localError(conf, info, "unknown Nim version; currently supported values are: {1.0}")
   of "benchmarkvm":
diff --git a/compiler/options.nim b/compiler/options.nim
index d906cd852..b38b5a6bc 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -91,6 +91,7 @@ type                          # please make sure we have under 32 options
     optBenchmarkVM            # Enables cpuTime() in the VM
     optProduceAsm             # produce assembler code
     optPanics                 # turn panics (sysFatal) into a process termination
+    optNimV1Emulation         # emulate Nim v1.0
 
   TGlobalOptions* = set[TGlobalOption]
 
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index 8196c1b4e..52df47ef0 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -42,7 +42,7 @@ const
     wTags, wLocks, wGcSafe}
   exprPragmas* = {wLine, wLocks, wNoRewrite, wGcSafe, wNoSideEffect}
   stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangeChecks,
-    wBoundChecks, wOverflowChecks, wNilChecks, wStaticBoundchecks, 
+    wBoundChecks, wOverflowChecks, wNilChecks, wStaticBoundchecks,
     wStyleChecks, wAssertions,
     wWarnings, wHints,
     wLineDir, wStackTrace, wLineTrace, wOptimization, wHint, wWarning, wError,
@@ -1029,7 +1029,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
       of wCodegenDecl: processCodegenDecl(c, it, sym)
       of wChecks, wObjChecks, wFieldChecks, wRangeChecks, wBoundChecks,
          wOverflowChecks, wNilChecks, wAssertions, wWarnings, wHints,
-         wLineDir, wOptimization, wStaticBoundchecks, wStyleChecks, 
+         wLineDir, wOptimization, wStaticBoundchecks, wStyleChecks,
          wCallconv, wDebugger, wProfiler,
          wFloatChecks, wNanChecks, wInfChecks, wPatterns, wTrMacros:
         processOption(c, it, c.config.options)
@@ -1147,7 +1147,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
         else: sym.flags.incl sfUsed
       of wLiftLocals: discard
       else: invalidPragma(c, it)
-    elif comesFromPush and whichKeyword(ident) in {wTags, wRaises}:
+    elif comesFromPush and whichKeyword(ident) != wInvalid:
       discard "ignore the .push pragma; it doesn't apply"
     else:
       if sym == nil or (sym.kind in {skVar, skLet, skParam,
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 867106b87..6e423181c 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -1580,6 +1580,12 @@ proc semProcTypeWithScope(c: PContext, n: PNode,
   if n[1].kind != nkEmpty and n[1].len > 0:
     pragma(c, s, n[1], procTypePragmas)
     when useEffectSystem: setEffectsForProcType(c.graph, result, n[1])
+  elif c.optionStack.len > 0 and optNimV1Emulation notin c.config.globalOptions:
+    # we construct a fake 'nkProcDef' for the 'mergePragmas' inside 'implicitPragmas'...
+    s.ast = newTree(nkProcDef, newNodeI(nkEmpty, n.info), newNodeI(nkEmpty, n.info),
+        newNodeI(nkEmpty, n.info), newNodeI(nkEmpty, n.info), newNodeI(nkEmpty, n.info))
+    implicitPragmas(c, s, n, {wTags, wRaises})
+    when useEffectSystem: setEffectsForProcType(c.graph, result, s.ast[pragmasPos])
   closeScope(c)
 
 proc symFromExpectedTypeNode(c: PContext, n: PNode): PSym =
diff --git a/tests/effects/teffects1.nim b/tests/effects/teffects1.nim
index 6ca24d53e..3bd19f4ab 100644
--- a/tests/effects/teffects1.nim
+++ b/tests/effects/teffects1.nim
@@ -1,7 +1,13 @@
 discard """
-  errormsg: "can raise an unlisted exception: ref IOError"
+  errormsg: "type mismatch: got <proc (x: int): string{.noSideEffect, gcsafe, locks: 0.}> but expected 'MyProcType = proc (x: int): string{.closure.}'"
   file: "teffects1.nim"
-  line: 17
+  line: 38
+  cmd: "nim check $file"
+  nimout: '''teffects1.nim(22, 28) template/generic instantiation from here
+teffects1.nim(23, 13) Error: can raise an unlisted exception: ref IOError
+teffects1.nim(22, 29) Hint: 'IO2Error' is declared but not used [XDeclaredButNotUsed]
+teffects1.nim(38, 21) Error: type mismatch: got <proc (x: int): string{.noSideEffect, gcsafe, locks: 0.}> but expected 'MyProcType = proc (x: int): string{.closure.}'
+.raise effects differ'''
 """
 
 type
@@ -18,3 +24,16 @@ proc lier(): int {.raises: [IO2Error].} =
 
 proc forw: int =
   raise newException(IOError, "arg")
+
+{.push raises: [Defect].}
+
+type
+  MyProcType* = proc(x: int): string #{.raises: [ValueError, Defect].}
+
+proc foo(x: int): string {.raises: [ValueError].} =
+  if x > 9:
+    raise newException(ValueError, "Use single digit")
+  $x
+
+var p: MyProcType = foo
+{.pop.}