mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-07 12:24:19 +00:00
Fixes multiple bugs with sink arguments (#9802)
* fixes #9781 * fix spacing
This commit is contained in:
@@ -346,7 +346,7 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
|
||||
result.info = n.info
|
||||
result.typ = n.typ
|
||||
else:
|
||||
localError(c.config, n.info, "cannot evaluate 'sizeof' because its type is not defined completely")
|
||||
localError(c.config, n.info, "cannot evaluate 'sizeof' because its type is not defined completely, type: " & n[1].typ.typeToString)
|
||||
result = n
|
||||
of mAlignOf:
|
||||
result = newIntNode(nkIntLit, getAlign(c.config, n[1].typ))
|
||||
|
||||
@@ -432,7 +432,7 @@ proc handleFloatRange(f, a: PType): TTypeRelation =
|
||||
else: result = isNone
|
||||
|
||||
proc genericParamPut(c: var TCandidate; last, fGenericOrigin: PType) =
|
||||
if fGenericOrigin != nil and last.kind == tyGenericInst and
|
||||
if fGenericOrigin != nil and last.kind == tyGenericInst and
|
||||
last.len-1 == fGenericOrigin.len:
|
||||
for i in countup(1, sonsLen(fGenericOrigin) - 1):
|
||||
let x = PType(idTableGet(c.bindings, fGenericOrigin.sons[i]))
|
||||
@@ -1034,8 +1034,8 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
|
||||
|
||||
template doBind: bool = trDontBind notin flags
|
||||
|
||||
# var and static arguments match regular modifier-free types
|
||||
var a = maybeSkipDistinct(c, aOrig.skipTypes({tyStatic, tyVar, tyLent}), c.calleeSym)
|
||||
# var, sink and static arguments match regular modifier-free types
|
||||
var a = maybeSkipDistinct(c, aOrig.skipTypes({tyStatic, tyVar, tyLent, tySink}), c.calleeSym)
|
||||
# XXX: Theoretically, maybeSkipDistinct could be called before we even
|
||||
# start the param matching process. This could be done in `prepareOperand`
|
||||
# for example, but unfortunately `prepareOperand` is not called in certain
|
||||
@@ -1045,7 +1045,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
|
||||
return typeRel(c, f, lastSon(aOrig))
|
||||
|
||||
if a.kind == tyGenericInst and
|
||||
skipTypes(f, {tyVar, tyLent}).kind notin {
|
||||
skipTypes(f, {tyVar, tyLent, tySink}).kind notin {
|
||||
tyGenericBody, tyGenericInvocation,
|
||||
tyGenericInst, tyGenericParam} + tyTypeClasses:
|
||||
return typeRel(c, f, lastSon(a))
|
||||
|
||||
@@ -237,9 +237,9 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) =
|
||||
# recursive tuplers are not allowed and should be detected in the frontend
|
||||
if base.kind == tyTuple:
|
||||
computeSizeAlign(conf, base)
|
||||
if base.size == szIllegalRecursion:
|
||||
typ.size = szIllegalRecursion
|
||||
typ.align = szIllegalRecursion
|
||||
if base.size < 0:
|
||||
typ.size = base.size
|
||||
typ.align = base.align
|
||||
return
|
||||
|
||||
typ.align = int16(conf.target.ptrSize)
|
||||
@@ -379,7 +379,7 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) =
|
||||
typ.size = typ.lastSon.size
|
||||
typ.align = typ.lastSon.align
|
||||
|
||||
of tyGenericInst, tyDistinct, tyGenericBody, tyAlias:
|
||||
of tyGenericInst, tyDistinct, tyGenericBody, tyAlias, tySink:
|
||||
computeSizeAlign(conf, typ.lastSon)
|
||||
typ.size = typ.lastSon.size
|
||||
typ.align = typ.lastSon.align
|
||||
|
||||
@@ -8,6 +8,8 @@ allocating
|
||||
deallocating
|
||||
deallocating
|
||||
deallocating
|
||||
allocating
|
||||
deallocating
|
||||
'''
|
||||
cmd: '''nim c --newruntime $file'''
|
||||
"""
|
||||
@@ -23,8 +25,7 @@ template incRef(x) =
|
||||
|
||||
template decRef(x): untyped = atomicDec(x.refcount)
|
||||
|
||||
proc makeShared*[T](x: T): SharedPtr[T] =
|
||||
# XXX could benefit from 'sink' parameter.
|
||||
proc makeShared*[T](x: sink T): SharedPtr[T] =
|
||||
# XXX could benefit from a macro that generates it.
|
||||
result = cast[SharedPtr[T]](allocShared(sizeof(x)))
|
||||
result.x[] = x
|
||||
@@ -59,6 +60,9 @@ proc `=sink`*[T](dest: var SharedPtr[T]; src: SharedPtr[T]) =
|
||||
echo "deallocating"
|
||||
dest.x = src.x
|
||||
|
||||
proc get*[T](s: SharedPtr[T]): lent T =
|
||||
s.x[]
|
||||
|
||||
template `.`*[T](s: SharedPtr[T]; field: untyped): untyped =
|
||||
s.x.field
|
||||
|
||||
@@ -99,3 +103,47 @@ proc main =
|
||||
|
||||
main()
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------
|
||||
#bug #9781
|
||||
|
||||
type
|
||||
MySeq* [T] = object
|
||||
refcount: int
|
||||
len: int
|
||||
data: ptr UncheckedArray[T]
|
||||
|
||||
proc `=destroy`*[T](m: var MySeq[T]) {.inline.} =
|
||||
if m.data != nil:
|
||||
deallocShared(m.data)
|
||||
m.data = nil
|
||||
|
||||
proc `=`*[T](m: var MySeq[T], m2: MySeq[T]) =
|
||||
if m.data == m2.data: return
|
||||
if m.data != nil:
|
||||
`=destroy`(m)
|
||||
|
||||
m.len = m2.len
|
||||
let bytes = m.len.int * sizeof(float)
|
||||
if bytes > 0:
|
||||
m.data = cast[ptr UncheckedArray[T]](allocShared(bytes))
|
||||
copyMem(m.data, m2.data, bytes)
|
||||
|
||||
proc `=sink`*[T](m: var MySeq[T], m2: MySeq[T]) {.inline.} =
|
||||
if m.data != m2.data:
|
||||
if m.data != nil:
|
||||
`=destroy`(m)
|
||||
m.len = m2.len
|
||||
m.data = m2.data
|
||||
|
||||
proc len*[T](m: MySeq[T]): int {.inline.} = m.len
|
||||
|
||||
proc newMySeq*[T](size: int, initial_value: T): MySeq[T] =
|
||||
result.len = size
|
||||
if size > 0:
|
||||
result.data = cast[ptr UncheckedArray[T]](allocShared(sizeof(T) * size))
|
||||
|
||||
|
||||
let x = makeShared(newMySeq(10, 1.0))
|
||||
doAssert: x.get().len == 10
|
||||
|
||||
Reference in New Issue
Block a user