diff options
-rw-r--r-- | compiler/semmagic.nim | 2 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 8 | ||||
-rw-r--r-- | compiler/sizealignoffsetimpl.nim | 8 | ||||
-rw-r--r-- | tests/destructor/tatomicptrs.nim | 52 |
4 files changed, 59 insertions, 11 deletions
diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 2aae562f9..6ce6fc12e 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -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)) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 4adf0bed3..a9ea2f697 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -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)) diff --git a/compiler/sizealignoffsetimpl.nim b/compiler/sizealignoffsetimpl.nim index 4791788fa..f5ecc04b1 100644 --- a/compiler/sizealignoffsetimpl.nim +++ b/compiler/sizealignoffsetimpl.nim @@ -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 diff --git a/tests/destructor/tatomicptrs.nim b/tests/destructor/tatomicptrs.nim index d20596415..fd8fc34d9 100644 --- a/tests/destructor/tatomicptrs.nim +++ b/tests/destructor/tatomicptrs.nim @@ -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 |