Skip to content

Inferred destructors =, =sink, =destroy should be inline #14116

@mratsim

Description

@mratsim

As soon as we define a destructor proc, the compiler will create inferred ones.

The inferred destructors should be tagged inline.

Even in the case one is "expensive", for example the =destroy for a copy-on-write scheme, that means it is user-defined and users can set its visibility. And autogenerated =sink would be inline but the inner wasMoved/=destroy will not.

Test case:

import std/atomics

type AtomicCounter = object
  count: Atomic[int]

proc `=`*(dst: var AtomicCounter, src: AtomicCounter) {.error: "An atomic counter cannot be copied.".}

proc initialize*(ac: var AtomicCounter) {.inline.} =
  ac.count.store(0, moRelaxed)

proc foo() =
  var a: AtomicCounter
  a.initialize()

  echo "Done"

foo()

Code generated

N_LIB_PRIVATE N_NIMCALL(void, eqdestroy___RSZ6ZmHixIDkz6af7YhiEg)(tyObject_AtomicCounter__Yz7FoDTBlGPGeC6wQ9aoO7Q* dest) {
}
N_LIB_PRIVATE N_NIMCALL(void, foo__JzbnjO5RDbS420V3wzhF6Q)(void) {
	tyObject_AtomicCounter__Yz7FoDTBlGPGeC6wQ9aoO7Q a;
	TSafePoint TM__9aQ9cEDplzy5RH1NH07Dxehw_2;
	nimZeroMem((void*)(&a), sizeof(tyObject_AtomicCounter__Yz7FoDTBlGPGeC6wQ9aoO7Q));
	pushSafePoint(&TM__9aQ9cEDplzy5RH1NH07Dxehw_2);
	TM__9aQ9cEDplzy5RH1NH07Dxehw_2.status = setjmp(TM__9aQ9cEDplzy5RH1NH07Dxehw_2.context);
	if (TM__9aQ9cEDplzy5RH1NH07Dxehw_2.status == 0) {
		initialize__5UeDB2gx8kATVzHYGeWFRAnoinit_custom_destructors((&a));
		echoBinSafe(TM__9aQ9cEDplzy5RH1NH07Dxehw_3, 1);
		popSafePoint();
	}
	else {
		popSafePoint();
	}
	{
		eqdestroy___RSZ6ZmHixIDkz6af7YhiEg((&a));
		if (TM__9aQ9cEDplzy5RH1NH07Dxehw_2.status != 0) nimLeaveFinally();
	}
	if (TM__9aQ9cEDplzy5RH1NH07Dxehw_2.status != 0) reraiseException();
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions