From b80562304ee6ae614f14cf5b8528af06c45fe9a6 Mon Sep 17 00:00:00 2001 From: zerbina <100542850+zerbina@users.noreply.github.com> Date: Tue, 28 Mar 2023 00:30:16 +0200 Subject: [PATCH] language: remove new-with-finalize Summary ======= The new-with-finalize (`new(x, finalizer)`) feature had unintuitive behaviour, worked different when using `--gc:arc|orc`, and was unsupported both in compile-time execution contexts and by the JavaScript and VM backend. Due to the amount of issues the feature had, and destructors being able to replace it in all valid use-cases, the feature is removed. Details ====== - remove the `mNewFinalize` magic and adjust all usage sites - replace finalizer usage with destructors for the `nre` and `re` module - remove tests for new-with-finalize feature - adjust tests that use new-with-finalize but don't depend on it --- compiler/ast/ast_query.nim | 2 +- compiler/ast/ast_types.nim | 2 +- compiler/ast/report_enums.nim | 1 - compiler/backend/ccgcalls.nim | 2 +- compiler/backend/ccgexprs.nim | 28 --------- compiler/backend/jsgen.nim | 2 +- compiler/front/cli_reporter.nim | 3 - compiler/mir/mirgen.nim | 9 ++- compiler/sem/dfa.nim | 2 +- compiler/sem/injectdestructors.nim | 2 +- compiler/sem/semexprs.nim | 2 +- compiler/sem/semmagic.nim | 60 -------------------- compiler/sem/sempass2.nim | 3 +- compiler/sem/semstmts.nim | 9 --- compiler/vm/vmgen.nim | 2 +- lib/impure/nre.nim | 6 +- lib/impure/re.nim | 13 +---- lib/system.nim | 14 ----- tests/arc/t14383.nim | 15 ----- tests/arc/tarcmisc.nim | 45 --------------- tests/errmsgs/t10376.nim | 31 ---------- tests/gc/closureleak.nim | 18 ++---- tests/gc/gctest.nim | 20 +++---- tests/gc/tregionleak.nim | 12 ++-- tests/gc/weakrefs.nim | 11 +--- tests/lang_objects/destructor/tfinalizer.nim | 31 ---------- tests/misc/tnew.nim | 4 +- 27 files changed, 44 insertions(+), 305 deletions(-) delete mode 100644 tests/errmsgs/t10376.nim delete mode 100644 tests/lang_objects/destructor/tfinalizer.nim diff --git a/compiler/ast/ast_query.nim b/compiler/ast/ast_query.nim index a337acdf0f079..4ab2ecdca26bc 100644 --- a/compiler/ast/ast_query.nim +++ b/compiler/ast/ast_query.nim @@ -120,7 +120,7 @@ const defaultAlignment* = -1 defaultOffset* = -1 - FakeVarParams* = {mNew, mNewFinalize, mInc, mDec, mIncl, mExcl, + FakeVarParams* = {mNew, mInc, mDec, mIncl, mExcl, mSetLengthStr, mSetLengthSeq, mAppendStrCh, mAppendStrStr, mSwap, mAppendSeqElem, mNewSeq, mReset, mShallowCopy, mDeepCopy, mMove, mWasMoved} diff --git a/compiler/ast/ast_types.nim b/compiler/ast/ast_types.nim index 42e25e989720a..0a676efeb5a73 100644 --- a/compiler/ast/ast_types.nim +++ b/compiler/ast/ast_types.nim @@ -725,7 +725,7 @@ type mPlugin, mEcho, mShallowCopy, mSlurp, mStaticExec, mStatic, mParseExprToAst, mParseStmtToAst, mExpandToAst, mQuoteAst, mInc, mDec, mOrd, - mNew, mNewFinalize, mNewSeq, mNewSeqOfCap, + mNew, mNewSeq, mNewSeqOfCap, mLengthOpenArray, mLengthStr, mLengthArray, mLengthSeq, mIncl, mExcl, mCard, mChr, mGCref, mGCunref, diff --git a/compiler/ast/report_enums.nim b/compiler/ast/report_enums.nim index 82c1e796a0b88..63ee9bbac77cf 100644 --- a/compiler/ast/report_enums.nim +++ b/compiler/ast/report_enums.nim @@ -591,7 +591,6 @@ type rsemOldTakesParameterName rsemOldDoesNotBelongTo rsemCannotFindPlugin - rsemExpectedProcReferenceForFinalizer rsemCannotIsolate rsemRecursiveDependencyIterator rsemIllegalNimvmContext diff --git a/compiler/backend/ccgcalls.nim b/compiler/backend/ccgcalls.nim index 9ec0816ffd7cf..62791e2578712 100644 --- a/compiler/backend/ccgcalls.nim +++ b/compiler/backend/ccgcalls.nim @@ -308,7 +308,7 @@ proc getPotentialWrites(n: PNode; mutate: bool; result: var seq[PNode]) = of nkCallKinds: case n.getMagic: of mIncl, mExcl, mInc, mDec, mAppendStrCh, mAppendStrStr, mAppendSeqElem, - mAddr, mNew, mNewFinalize, mWasMoved, mDestroy, mReset: + mAddr, mNew, mWasMoved, mDestroy, mReset: getPotentialWrites(n[1], true, result) for i in 2..finalizer = (void*)$2;$n", [ti, rdLoc(f)]) - b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", [ - getTypeDesc(p.module, refType), - ti, getTypeDesc(p.module, skipTypes(refType.lastSon, abstractRange))]) - genAssignment(p, a, b, {}) # set the object type: - bt = skipTypes(refType.lastSon, abstractRange) - genObjectInit(p, cpsStmts, bt, a, constructRefObj) - gcUsage(p.config, e) - proc genOfHelper(p: BProc; dest: PType; a: Rope; info: TLineInfo): Rope = if optTinyRtti in p.config.globalOptions: result = ropecg(p.module, "#isObj($1.m_type, $2)", @@ -2452,14 +2432,6 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = genRepr(p, e, d) of mOf: genOf(p, e, d) of mNew: genNew(p, e) - of mNewFinalize: - if optTinyRtti in p.config.globalOptions: - var a: TLoc - initLocExpr(p, e[1], a) - rawGenNew(p, a, "", needsInit = true) - gcUsage(p.config, e) - else: - genNewFinalize(p, e) of mNewSeq: if optSeqDestructors in p.config.globalOptions: e[1] = makeAddr(e[1], p.module.idgen) diff --git a/compiler/backend/jsgen.nim b/compiler/backend/jsgen.nim index 2fcf7045984a6..3c1d58082af2f 100644 --- a/compiler/backend/jsgen.nim +++ b/compiler/backend/jsgen.nim @@ -2064,7 +2064,7 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) = gen(p, n[1], x) r.res = "($# == null && $# === 0)" % [x.address, x.res] of mEnumToStr: genRepr(p, n, r) - of mNew, mNewFinalize: genNew(p, n) + of mNew: genNew(p, n) of mChr: gen(p, n[1], r) of mArrToSeq: # only array literals doesn't need copy diff --git a/compiler/front/cli_reporter.nim b/compiler/front/cli_reporter.nim index ceca66d9f49c0..707d6795c63c5 100644 --- a/compiler/front/cli_reporter.nim +++ b/compiler/front/cli_reporter.nim @@ -873,9 +873,6 @@ proc reportBody*(conf: ConfigRef, r: SemReport): string = of rsemCannotFindPlugin: result = "cannot find plugin " & r.symstr - of rsemExpectedProcReferenceForFinalizer: - result = "finalizer must be a direct reference to a proc" - of rsemUnsafeSetLen: result = "setLen can potentially expand the sequence, " & "but the element type '$1' doesn't have a valid default value" % diff --git a/compiler/mir/mirgen.nim b/compiler/mir/mirgen.nim index 093926eacba47..98382d631c7bc 100644 --- a/compiler/mir/mirgen.nim +++ b/compiler/mir/mirgen.nim @@ -987,17 +987,16 @@ proc genMagic(c: var TCtx, n: PNode; m: TMagic): EValue = of mDefault: # use the canonical form: genDefault(c, n.typ) - of mNew, mNewFinalize: - # ``new`` has 3 variants. The standard one with a single argument, the - # unsafe version that also takes a ``size`` argument, and the finalizer - # version + of mNew: + # ``new`` has 2 variants. The standard one with a single argument, and the + # unsafe version that also takes an extra ``size`` argument assert n.len == 3 or n.len == 2 argBlock(c.stmts): # the first argument is the location storing the ``ref``. A new value is # assigned to it by ``new``, so the 'out' tag is used chain: genArgExpression(c, n[0].typ[1], n[1]) => outOp(c) => name(c) if n.len == 3: - # the finalizer or size argument + # the size argument chain: genArgExpression(c, n[0].typ[2], n[2]) => arg(c) magicCall(c, m, typeOrVoid(c, n.typ)) diff --git a/compiler/sem/dfa.nim b/compiler/sem/dfa.nim index 0fd887829e3fc..41d8627598733 100644 --- a/compiler/sem/dfa.nim +++ b/compiler/sem/dfa.nim @@ -764,7 +764,7 @@ proc genCall(c: var Con; n: PNode) = proc genMagic(c: var Con; n: PNode; m: TMagic) = case m of mAnd, mOr: c.genAndOr(n) - of mNew, mNewFinalize: + of mNew: genDef(c, n[1]) for i in 2...field - proc transform(c: PContext; procSym: PSym; n: PNode; old, fresh: PType; oldParam, newParam: PSym): PNode = - result = shallowCopy(n) - if sameTypeOrNil(n.typ, old): - result.typ = fresh - if n.kind == nkSym: - if n.sym == oldParam: - result.sym = newParam - elif n.sym.owner == orig: - result.sym = copySym(n.sym, nextSymId c.idgen) - result.sym.owner = procSym - for i in 0 ..< safeLen(n): - result[i] = transform(c, procSym, n[i], old, fresh, oldParam, newParam) - #if n.kind == nkDerefExpr and sameType(n[0].typ, old): - # result = - - result = copySym(orig, nextSymId c.idgen) - result.info = info - result.flags.incl sfFromGeneric - result.owner = orig - let origParamType = orig.typ[1] - let newParamType = makeVarType(result, origParamType.skipTypes(abstractPtrs), c.idgen) - let oldParam = orig.typ.n[1].sym - let newParam = newSym(skParam, oldParam.name, nextSymId c.idgen, result, result.info) - newParam.typ = newParamType - # proc body: - result.ast = transform(c, result, orig.ast, origParamType, newParamType, oldParam, newParam) - # proc signature: - result.typ = newProcType(result.info, nextTypeId c.idgen, result) - result.typ.addParam newParam - proc semPrivateAccess(c: PContext, n: PNode): PNode = let t = n[1].typ[0].toObjectFromRefPtrGeneric c.currentScope.allowPrivateAccess.add t.sym @@ -448,31 +413,6 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, result = n else: result = plugin(c, n) - of mNewFinalize: - # Make sure the finalizer procedure refers to a procedure - if n[^1].kind == nkSym and n[^1].sym.kind notin {skProc, skFunc}: - localReport(c.config, n, reportSem rsemExpectedProcReferenceForFinalizer) - elif optTinyRtti in c.config.globalOptions: - let nfin = skipConvCastAndClosure(n[^1]) - let fin = case nfin.kind - of nkSym: nfin.sym - of nkLambda, nkDo: nfin[namePos].sym - else: - localReport(c.config, n, reportSem rsemExpectedProcReferenceForFinalizer) - nil - if fin != nil: - if fin.kind notin {skProc, skFunc}: - # calling convention is checked in codegen - localReport(c.config, n, reportSem rsemExpectedProcReferenceForFinalizer) - - # check if we converted this finalizer into a destructor already: - let t = whereToBindTypeHook(c, fin.typ[1].skipTypes(abstractInst+{tyRef})) - if t != nil and getAttachedOp(c.graph, t, attachedDestructor) != nil and - getAttachedOp(c.graph, t, attachedDestructor).owner == fin: - discard "already turned this one into a finalizer" - else: - bindTypeHook(c, turnFinalizerIntoDestructor(c, fin, n.info), n, attachedDestructor) - result = n of mDestroy: result = n let t = n[1].typ.skipTypes(abstractVar) diff --git a/compiler/sem/sempass2.nim b/compiler/sem/sempass2.nim index 423706ec6a246..d954df8557c2d 100644 --- a/compiler/sem/sempass2.nim +++ b/compiler/sem/sempass2.nim @@ -985,7 +985,7 @@ proc trackCall(tracked: PEffects; n: PNode) = if a.kind != nkSym or a.sym.magic notin {mFinished}: for i in 1.. 0: createTypeBoundOps(tracked, n[1].typ.lastSon, n.info) createTypeBoundOps(tracked, n[1].typ, n.info) - # new(x, finalizer): Problem: how to move finalizer into 'createTypeBoundOps'? elif a.kind == nkSym and a.sym.magic in {mArrGet, mArrPut} and optStaticBoundsCheck in tracked.currOptions: diff --git a/compiler/sem/semstmts.nim b/compiler/sem/semstmts.nim index 890d2c85009c8..941f8eb99b085 100644 --- a/compiler/sem/semstmts.nim +++ b/compiler/sem/semstmts.nim @@ -2405,15 +2405,6 @@ proc prevDestructor(c: PContext; prevOp: PSym; obj: PType; info: TLineInfo) = localReport(c.config, info, reportSym( rsemRebidingDestructor, prevOp, typ = obj)) -proc whereToBindTypeHook(c: PContext; t: PType): PType = - result = t - while true: - if result.kind in {tyGenericBody, tyGenericInst}: result = result.lastSon - elif result.kind == tyGenericInvocation: result = result[0] - else: break - if result.kind in {tyObject, tyDistinct, tySequence, tyString}: - result = canonType(c, result) - proc bindTypeHook(c: PContext; s: PSym; n: PNode; op: TTypeAttachedOp) = let t = s.typ var noError = false diff --git a/compiler/vm/vmgen.nim b/compiler/vm/vmgen.nim index f84eecfe6c45d..3109f7e9603f4 100644 --- a/compiler/vm/vmgen.nim +++ b/compiler/vm/vmgen.nim @@ -1504,7 +1504,7 @@ proc genMagic(c: var TCtx; n: PNode; dest: var TDest; m: TMagic) = c.freeTemp(L) of mIsolate: genCall(c, n, dest) - of mNew, mNewFinalize: + of mNew: unused(c, n, dest) c.genNew(n) of mNewSeq: diff --git a/lib/impure/nre.nim b/lib/impure/nre.nim index bc0c94ab9b372..11f4bcef14777 100644 --- a/lib/impure/nre.nim +++ b/lib/impure/nre.nim @@ -211,7 +211,9 @@ type ## for whatever reason. The message contains the error ## code. -proc destroyRegex(pattern: Regex) = +template objectOf[T](x: typedesc[ref T]): typedesc = T + +proc `=destroy`(pattern: var objectOf(Regex)) = pcre.free_substring(cast[cstring](pattern.pcreObj)) if pattern.pcreExtra != nil: pcre.free_study(pattern.pcreExtra) @@ -244,7 +246,7 @@ proc getNameToNumberTable(pattern: Regex): Table[string, int] = result[name] = num proc initRegex(pattern: string, flags: int, study = true): Regex = - new(result, destroyRegex) + new(result) result.pattern = pattern var errorMsg: cstring diff --git a/lib/impure/re.nim b/lib/impure/re.nim index ba968e02ff82c..4a60cf3196d35 100644 --- a/lib/impure/re.nim +++ b/lib/impure/re.nim @@ -57,12 +57,6 @@ type RegexError* = object of ValueError ## is raised if the pattern is no valid regular expression. -when defined(gcDestructors): - proc `=destroy`(x: var RegexDesc) = - pcre.free_substring(cast[cstring](x.h)) - if not isNil(x.e): - pcre.free_study(x.e) - proc raiseInvalidRegex(msg: string) {.noinline, noreturn.} = var e: ref RegexError new(e) @@ -77,7 +71,7 @@ proc rawCompile(pattern: string, flags: cint): ptr Pcre = if result == nil: raiseInvalidRegex($msg & "\n" & pattern & "\n" & spaces(offset) & "^\n") -proc finalizeRegEx(x: Regex) = +proc `=destroy`(x: var RegexDesc) = # XXX This is a hack, but PCRE does not export its "free" function properly. # Sigh. The hack relies on PCRE's implementation (see `pcre_get.c`). # Fortunately the implementation is unlikely to change. @@ -95,10 +89,7 @@ proc re*(s: string, flags = {reStudy}): Regex = ## avoid putting it directly in the arguments of the functions like ## the examples show below if you plan to use it a lot of times, as ## this will hurt performance immensely. (e.g. outside a loop, ...) - when defined(gcDestructors): - result = Regex() - else: - new(result, finalizeRegEx) + result = Regex() result.h = rawCompile(s, cast[cint](flags - {reStudy})) if reStudy in flags: var msg: cstring = "" diff --git a/lib/system.nim b/lib/system.nim index 028029418ac28..4d0a4a6ba2ff0 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -268,20 +268,6 @@ const ThisIsSystem = true proc internalNew*[T](a: var ref T) {.magic: "New", noSideEffect.} ## Leaked implementation detail. Do not use. -when true: - proc new*[T](a: var ref T, finalizer: proc (x: ref T) {.nimcall.}) {. - magic: "NewFinalize", noSideEffect.} - ## Creates a new object of type `T` and returns a safe (traced) - ## reference to it in `a`. - ## - ## When the garbage collector frees the object, `finalizer` is called. - ## The `finalizer` may not keep a reference to the - ## object pointed to by `x`. The `finalizer` cannot prevent the GC from - ## freeing the object. - ## - ## **Note**: The `finalizer` refers to the type `T`, not to the object! - ## This means that for each object of type `T` the finalizer will be called! - proc wasMoved*[T](obj: var T) {.magic: "WasMoved", noSideEffect.} = ## Resets an object `obj` to its initial (binary zero) value to signify ## it was "moved" and to signify its destructor should do nothing and diff --git a/tests/arc/t14383.nim b/tests/arc/t14383.nim index 96b5051669788..10a18e4708002 100644 --- a/tests/arc/t14383.nim +++ b/tests/arc/t14383.nim @@ -52,21 +52,6 @@ echo x import std/os discard getFileInfo(".") - -#------------------------------------------------------------------------------ -# Issue #15707 -#------------------------------------------------------------------------------ - -type - JVMObject = ref object -proc freeJVMObject(o: JVMObject) = - discard -proc fromJObject(T: typedesc[JVMObject]): T = - result.new(cast[proc(r: T) {.nimcall.}](freeJVMObject)) - -discard JVMObject.fromJObject() - - #------------------------------------------------------------------------------ # Issue #15910 #------------------------------------------------------------------------------ diff --git a/tests/arc/tarcmisc.nim b/tests/arc/tarcmisc.nim index 45d1514cd220c..361c000650dbc 100644 --- a/tests/arc/tarcmisc.nim +++ b/tests/arc/tarcmisc.nim @@ -23,10 +23,8 @@ whiley ends :( 0 new line before - @['a'] new line after - @['a'] -finalizer aaaaa hello -ok true copying 123 @@ -158,21 +156,6 @@ proc match(inp: string, rg: static MyType) = match("ac", re"a(b|c)") -#------------------------------------------------------------------------------ -# issue #14243 - -type - Game* = ref object - -proc free*(game: Game) = - let a = 5 - -proc newGame*(): Game = - new(result, free) - -var game*: Game - - #------------------------------------------------------------------------------ # issue #14333 @@ -266,23 +249,6 @@ newline.insert(indent, 0) echo "new line after - ", newline -# bug #15044 - -type - Test = ref object - -proc test: Test = - # broken - new(result, proc(x: Test) = - echo "finalizer" - ) - -proc tdirectFinalizer = - discard test() - -tdirectFinalizer() - - # bug #14480 proc hello(): int = result = 42 @@ -384,17 +350,6 @@ proc text_parser(xml: var XmlParser) = text_parser(xml) text_parser(xml2) -# bug #15599 -type - PixelBuffer = ref object - -proc newPixelBuffer(): PixelBuffer = - new(result) do (buffer: PixelBuffer): - echo "ok" - -discard newPixelBuffer() - - # bug #17199 proc passSeq(data: seq[string]) = diff --git a/tests/errmsgs/t10376.nim b/tests/errmsgs/t10376.nim deleted file mode 100644 index 2ce16d6a224be..0000000000000 --- a/tests/errmsgs/t10376.nim +++ /dev/null @@ -1,31 +0,0 @@ -discard """ - errormsg: "finalizer must be a direct reference to a proc" - line: 29 -""" - -type - A = ref object - -proc my_callback(a: A) {. nimcall .} = - discard - -proc foo(callback: proc(a: A) {. nimcall .}) = - var x1: A - new(x1, proc (x: A) {.nimcall.} = discard) - var x2: A - new(x2, func (x: A) {.nimcall.} = discard) - - var x3: A - proc foo1(a: A) {.nimcall.} = discard - new(x3, foo1) - var x4: A - func foo2(a: A) {.nimcall.} = discard - new(x4, foo2) - - var x5: A - new(x5, my_callback) - - var x6: A - new(x6, callback) - -foo(my_callback) diff --git a/tests/gc/closureleak.nim b/tests/gc/closureleak.nim index 0265431d04631..c1712c682431a 100644 --- a/tests/gc/closureleak.nim +++ b/tests/gc/closureleak.nim @@ -10,22 +10,12 @@ type var foo_counter = 0 var alive_foos = newseq[int](0) -when defined(gcDestructors): - proc `=destroy`(some: var TFoo) = - alive_foos.del alive_foos.find(some.id) - `=destroy`(some.fn) - -else: - proc free*(some: ref TFoo) = - #echo "Tfoo #", some.id, " freed" - alive_foos.del alive_foos.find(some.id) +proc `=destroy`(some: var TFoo) = + alive_foos.del alive_foos.find(some.id) + `=destroy`(some.fn) proc newFoo*(): ref TFoo = - when defined(gcDestructors): - new result - else: - new result, free - + new result result.id = foo_counter alive_foos.add result.id inc foo_counter diff --git a/tests/gc/gctest.nim b/tests/gc/gctest.nim index 78b78934c0739..f241bfaf2f052 100644 --- a/tests/gc/gctest.nim +++ b/tests/gc/gctest.nim @@ -58,8 +58,8 @@ proc caseTree(lvl: int = 0): PCaseNode = if lvl == 3: result = newCaseNode("data item") else: result = newCaseNode(caseTree(lvl+1), caseTree(lvl+1)) -proc finalizeNode(n: PNode) = - assert(n != nil) +proc `=destroy`(n: var TNode) = + assert(addr(n) != nil) write(stdout, "finalizing: ") writeLine(stdout, "not nil") @@ -68,7 +68,7 @@ var proc buildTree(depth = 1): PNode = if depth == 7: return nil - new(result, finalizeNode) + new(result) result.le = buildTree(depth+1) result.ri = buildTree(depth+1) result.data = $id @@ -76,18 +76,18 @@ proc buildTree(depth = 1): PNode = proc returnTree(): PNode = writeLine(stdout, "creating id: " & $id) - new(result, finalizeNode) + new(result) result.data = $id - new(result.le, finalizeNode) + new(result.le) result.le.data = $id & ".1" - new(result.ri, finalizeNode) + new(result.ri) result.ri.data = $id & ".2" inc(id) # now create a cycle: writeLine(stdout, "creating id (cyclic): " & $id) var cycle: PNode - new(cycle, finalizeNode) + new(cycle) cycle.data = $id cycle.le = cycle cycle.ri = cycle @@ -105,11 +105,11 @@ proc printTree(t: PNode) = proc unsureNew(result: var PNode) = writeLine(stdout, "creating unsure id: " & $id) - new(result, finalizeNode) + new(result) result.data = $id - new(result.le, finalizeNode) + new(result.le) result.le.data = $id & ".a" - new(result.ri, finalizeNode) + new(result.ri) result.ri.data = $id & ".b" inc(id) diff --git a/tests/gc/tregionleak.nim b/tests/gc/tregionleak.nim index 277cfc9875984..9d34ce379befe 100644 --- a/tests/gc/tregionleak.nim +++ b/tests/gc/tregionleak.nim @@ -6,18 +6,20 @@ finalized ''' """ -proc finish(o: RootRef) = +type Obj = object + +proc `=destroy`(o: var Obj) = echo "finalized" withScratchRegion: - var test: RootRef - new(test, finish) + var test: ref Obj + new(test) var mr: MemRegion - test: RootRef + test: ref Obj withRegion(mr): - new(test, finish) + new(test) deallocAll(mr) diff --git a/tests/gc/weakrefs.nim b/tests/gc/weakrefs.nim index 81c048d746d14..f868dafb46ba4 100644 --- a/tests/gc/weakrefs.nim +++ b/tests/gc/weakrefs.nim @@ -16,18 +16,11 @@ var gid: int # for id generation valid = initIntSet() -proc finalizer(x: StrongObject) = +proc `=destroy`(x: var TMyObject) = valid.excl(x.id) -when defined(gcDestructors): - proc `=destroy`(x: var TMyObject) = - valid.excl(x.id) - proc create: StrongObject = - when defined(gcDestructors): - new(result) - else: - new(result, finalizer) + new(result) result.id = gid valid.incl(gid) inc gid diff --git a/tests/lang_objects/destructor/tfinalizer.nim b/tests/lang_objects/destructor/tfinalizer.nim deleted file mode 100644 index eb2cd09af08e1..0000000000000 --- a/tests/lang_objects/destructor/tfinalizer.nim +++ /dev/null @@ -1,31 +0,0 @@ -discard """ - cmd: "nim c --gc:arc $file" - output: '''Foo(field: "Dick Laurent", k: ka, x: 0.0) -Nobody is dead -Dick Laurent is dead''' -""" - -type - Kind = enum - ka, kb - Foo = ref object - field: string - case k: Kind - of ka: x: float - of kb: discard - -#var x = Foo(field: "lovely") -proc finalizer(x: Foo) = - echo x.field, " is dead" - -var x: Foo -new(x, finalizer) -x.field = "Dick Laurent" -# reference to a great movie. If you haven't seen it, highly recommended. - -echo repr x - -# bug #13112: bind the same finalizer multiple times: -var xx: Foo -new(xx, finalizer) -xx.field = "Nobody" diff --git a/tests/misc/tnew.nim b/tests/misc/tnew.nim index 2d9a6446183df..318fa644be3f5 100644 --- a/tests/misc/tnew.nim +++ b/tests/misc/tnew.nim @@ -19,12 +19,12 @@ type TStressTest = ref array[0..45, array[1..45, TNode]] -proc finalizer(n: PNode) = +proc `=destroy`(n: var TNode) = write(stdout, n.data) write(stdout, " is now freed\n") proc newNode(data: int, le, ri: PNode): PNode = - new(result, finalizer) + new(result) result.le = le result.ri = ri result.data = data