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
This commit is contained in:
Andreas Rumpf 2022-10-07 22:26:53 +02:00 • committed by GitHub
commit e83f27e6a0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 47 additions and 3 deletions

View file

@ -65,6 +65,8 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
elif t.kind == tyLent and ((kind != skResult and views notin c.features) or elif t.kind == tyLent and ((kind != skResult and views notin c.features) or
kind == skParam): # lent can't be used as parameters. kind == skParam): # lent can't be used as parameters.
result = t result = t
elif isOutParam(t) and kind != skParam:
result = t
else: else:
var t2 = skipTypes(t[0], abstractInst-{tyTypeDesc, tySink}) var t2 = skipTypes(t[0], abstractInst-{tyTypeDesc, tySink})
case t2.kind case t2.kind

View file

@ -75,7 +75,7 @@ type
nnkTupleTy, nnkTupleClassTy, nnkTypeClassTy, nnkStaticTy, nnkTupleTy, nnkTupleClassTy, nnkTypeClassTy, nnkStaticTy,
nnkRecList, nnkRecCase, nnkRecWhen, nnkRecList, nnkRecCase, nnkRecWhen,
nnkRefTy, nnkPtrTy, nnkVarTy, nnkRefTy, nnkPtrTy, nnkVarTy,
nnkConstTy, nnkMutableTy, nnkConstTy, nnkOutTy,
nnkDistinctTy, nnkDistinctTy,
nnkProcTy, nnkProcTy,
nnkIteratorTy, # iterator type nnkIteratorTy, # iterator type
@ -125,6 +125,9 @@ type
TNimSymKinds* {.deprecated.} = set[NimSymKind] TNimSymKinds* {.deprecated.} = set[NimSymKind]
const
nnkMutableTy* {.deprecated.} = nnkOutTy
type type
NimIdent* {.deprecated.} = object of RootObj NimIdent* {.deprecated.} = object of RootObj
## Represents a Nim identifier in the AST. **Note**: This is only ## Represents a Nim identifier in the AST. **Note**: This is only

View file

@ -13,6 +13,7 @@
when defined(nimPreviewSlimSystem): when defined(nimPreviewSlimSystem):
import std/assertions import std/assertions
import std / outparams
const const
growthFactor = 2 growthFactor = 2
@ -78,5 +79,5 @@ template rawGetImpl() {.dirty.} =
genHashImpl(key, hc) genHashImpl(key, hc)
rawGetKnownHCImpl() rawGetKnownHCImpl()
proc rawGet[X, A](t: X, key: A, hc: var Hash): int {.inline.} = proc rawGet[X, A](t: X, key: A, hc: var Hash): int {.inline, outParamsAt: [3].} =
rawGetImpl() rawGetImpl()

View file

@ -23,7 +23,7 @@ template rawInsertImpl() {.dirty.} =
data[h].val = val data[h].val = val
data[h].hcode = hc data[h].hcode = hc
proc rawGetDeep[X, A](t: X, key: A, hc: var Hash): int {.inline.} = proc rawGetDeep[X, A](t: X, key: A, hc: var Hash): int {.inline, outParamsAt: [3].} =
rawGetDeepImpl() rawGetDeepImpl()
proc rawInsert[X, A, B](t: var X, data: var KeyValuePairSeq[A, B], proc rawInsert[X, A, B](t: var X, data: var KeyValuePairSeq[A, B],

38
lib/std/outparams.nim Normal file
View file

@ -0,0 +1,38 @@
#
#
# Nim's Runtime Library
# (c) Copyright 2022 Nim contributors
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## `outParamsAt` macro for easy writing code that works with both 2.0 and 1.x.
import macros
macro outParamsAt*(positions: static openArray[int]; n: untyped): untyped =
## Use this macro to annotate `out` parameters in a portable way.
runnableExamples:
proc p(x: var int) {.outParamsAt: [1].} =
discard "x is really an 'out int' if the Nim compiler supports 'out' parameters"
result = n
when defined(nimHasOutParams):
var p = n.params
for po in positions:
p[po][^2].expectKind nnkVarTy
p[po][^2] = newTree(nnkOutTy, p[po][^2][0])
when isMainModule:
{.experimental: "strictDefs".}
proc main(x: var int) {.outParamsAt: [1].} =
x = 3
proc us =
var x: int
main x
echo x
us()