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:
parent
a132f5502a
commit
e83f27e6a0
5 changed files with 47 additions and 3 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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
38
lib/std/outparams.nim
Normal 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()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue