Skip to content

UnsafeMutablePointer Not Calling Deinit of Generic Noncopyable Type in -ONone #85725

@Nobody1707

Description

@Nobody1707

Description

When calling deinitialize(count:) on an UnsafeMutablePointer containing a generic non-copyable type, the deinit of said type is not called unless optimizations are enabled. Calling deinitialize(count:) works properly when applied to an UnsafeMutablePointer containing either a non-generic non-copyable type or a copyable class type.

Reproduction

struct Unique<T: ~Copyable>: ~Copyable {
  public var value: T
  public init(_ value: consuming T) {
    print("Initializing Unique<\(T.self)>")
    self.value = value
  }
  deinit {
    print("Deinitializing Unique<\(T.self)>")
  }
}

struct Number: ~Copyable {
    public var value: Int
    public init(_ value: consuming Int) {
        print("Initializing Number(\(copy value))")
        self.value = value
    }
    deinit {
        print("Deinitializing Number(\(value))")
    }
}

final class Noisy<T: ~Copyable> {
    public var value: T
    public init(_ value: consuming T) {
        self.value = value
        print("Initializng Noisy<\(T.self)>")
    }
    deinit {
        print("Deinitializing Noisy<\(T.self)>")
    }
}

do {
  let a = UnsafeMutablePointer<Unique<Int>>.allocate(capacity: 1)
  a.initialize(to: Unique(42))
  a.deinitialize(count: 1) // deinit should be called here.
  a.deallocate()
}

do {
  let a = UnsafeMutablePointer<Number>.allocate(capacity: 1)
  a.initialize(to: Number(42))
  a.deinitialize(count: 1) // deinit is called here.
  a.deallocate()
}

do {
  let a = UnsafeMutablePointer<Noisy<Int>>.allocate(capacity: 1)
  a.initialize(to: Noisy(42))
  a.deinitialize(count: 1) // deinit is called here.
  a.deallocate()
}

Expected behavior

Expected output at all optimization levels:

Initializing Unique<Int>
Deinitializing Unique<Int>
Initializing Number(42)
Deinitializing Number(42)
Initializng Noisy<Int>
Deinitializing Noisy<Int>

Actual output at -ONone:

Initializing Unique<Int>
Initializing Number(42)
Deinitializing Number(42)
Initializng Noisy<Int>
Deinitializing Noisy<Int>

Environment

Swiftc 6.2 x86-64 Linux

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.triage neededThis issue needs more specific labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions