Skip to content

Commit e83f27e

Browse files
authored
out parameters: enforce that 'out' is only used as a parameter (#20510)
* out parameters: enforce that 'out' is only used as a parameter * make tables.nim use 'out' parameters * better backwards compat
1 parent a132f55 commit e83f27e

File tree

5 files changed

+47
-3
lines changed

5 files changed

+47
-3
lines changed

compiler/typeallowed.nim

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
6565
elif t.kind == tyLent and ((kind != skResult and views notin c.features) or
6666
kind == skParam): # lent can't be used as parameters.
6767
result = t
68+
elif isOutParam(t) and kind != skParam:
69+
result = t
6870
else:
6971
var t2 = skipTypes(t[0], abstractInst-{tyTypeDesc, tySink})
7072
case t2.kind

lib/core/macros.nim

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ type
7575
nnkTupleTy, nnkTupleClassTy, nnkTypeClassTy, nnkStaticTy,
7676
nnkRecList, nnkRecCase, nnkRecWhen,
7777
nnkRefTy, nnkPtrTy, nnkVarTy,
78-
nnkConstTy, nnkMutableTy,
78+
nnkConstTy, nnkOutTy,
7979
nnkDistinctTy,
8080
nnkProcTy,
8181
nnkIteratorTy, # iterator type
@@ -125,6 +125,9 @@ type
125125

126126
TNimSymKinds* {.deprecated.} = set[NimSymKind]
127127

128+
const
129+
nnkMutableTy* {.deprecated.} = nnkOutTy
130+
128131
type
129132
NimIdent* {.deprecated.} = object of RootObj
130133
## Represents a Nim identifier in the AST. **Note**: This is only

lib/pure/collections/hashcommon.nim

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
when defined(nimPreviewSlimSystem):
1414
import std/assertions
1515

16+
import std / outparams
1617

1718
const
1819
growthFactor = 2
@@ -78,5 +79,5 @@ template rawGetImpl() {.dirty.} =
7879
genHashImpl(key, hc)
7980
rawGetKnownHCImpl()
8081
81-
proc rawGet[X, A](t: X, key: A, hc: var Hash): int {.inline.} =
82+
proc rawGet[X, A](t: X, key: A, hc: var Hash): int {.inline, outParamsAt: [3].} =
8283
rawGetImpl()

lib/pure/collections/tableimpl.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ template rawInsertImpl() {.dirty.} =
2323
data[h].val = val
2424
data[h].hcode = hc
2525

26-
proc rawGetDeep[X, A](t: X, key: A, hc: var Hash): int {.inline.} =
26+
proc rawGetDeep[X, A](t: X, key: A, hc: var Hash): int {.inline, outParamsAt: [3].} =
2727
rawGetDeepImpl()
2828

2929
proc rawInsert[X, A, B](t: var X, data: var KeyValuePairSeq[A, B],

lib/std/outparams.nim

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#
2+
#
3+
# Nim's Runtime Library
4+
# (c) Copyright 2022 Nim contributors
5+
#
6+
# See the file "copying.txt", included in this
7+
# distribution, for details about the copyright.
8+
#
9+
10+
## `outParamsAt` macro for easy writing code that works with both 2.0 and 1.x.
11+
12+
import macros
13+
14+
macro outParamsAt*(positions: static openArray[int]; n: untyped): untyped =
15+
## Use this macro to annotate `out` parameters in a portable way.
16+
runnableExamples:
17+
proc p(x: var int) {.outParamsAt: [1].} =
18+
discard "x is really an 'out int' if the Nim compiler supports 'out' parameters"
19+
20+
result = n
21+
when defined(nimHasOutParams):
22+
var p = n.params
23+
for po in positions:
24+
p[po][^2].expectKind nnkVarTy
25+
p[po][^2] = newTree(nnkOutTy, p[po][^2][0])
26+
27+
when isMainModule:
28+
{.experimental: "strictDefs".}
29+
30+
proc main(x: var int) {.outParamsAt: [1].} =
31+
x = 3
32+
33+
proc us =
34+
var x: int
35+
main x
36+
echo x
37+
38+
us()

0 commit comments

Comments
 (0)