mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-12 06:18:51 +00:00
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:
@@ -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
|
||||
kind == skParam): # lent can't be used as parameters.
|
||||
result = t
|
||||
elif isOutParam(t) and kind != skParam:
|
||||
result = t
|
||||
else:
|
||||
var t2 = skipTypes(t[0], abstractInst-{tyTypeDesc, tySink})
|
||||
case t2.kind
|
||||
|
||||
@@ -75,7 +75,7 @@ type
|
||||
nnkTupleTy, nnkTupleClassTy, nnkTypeClassTy, nnkStaticTy,
|
||||
nnkRecList, nnkRecCase, nnkRecWhen,
|
||||
nnkRefTy, nnkPtrTy, nnkVarTy,
|
||||
nnkConstTy, nnkMutableTy,
|
||||
nnkConstTy, nnkOutTy,
|
||||
nnkDistinctTy,
|
||||
nnkProcTy,
|
||||
nnkIteratorTy, # iterator type
|
||||
@@ -125,6 +125,9 @@ type
|
||||
|
||||
TNimSymKinds* {.deprecated.} = set[NimSymKind]
|
||||
|
||||
const
|
||||
nnkMutableTy* {.deprecated.} = nnkOutTy
|
||||
|
||||
type
|
||||
NimIdent* {.deprecated.} = object of RootObj
|
||||
## Represents a Nim identifier in the AST. **Note**: This is only
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
|
||||
import std / outparams
|
||||
|
||||
const
|
||||
growthFactor = 2
|
||||
@@ -78,5 +79,5 @@ template rawGetImpl() {.dirty.} =
|
||||
genHashImpl(key, hc)
|
||||
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()
|
||||
|
||||
@@ -23,7 +23,7 @@ template rawInsertImpl() {.dirty.} =
|
||||
data[h].val = val
|
||||
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()
|
||||
|
||||
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()
|
||||
Reference in New Issue
Block a user