SWIFT_NONCOPYABLE macro questions

I was following the official guide for cpp interop and some topics including How can I use the pimpl idiom with std::unique_ptr with Swift/C++ interop?

I'll start with several samples that I tried to make it work.
I was experimenting a bit with c++ interop trying to compile and use proprietary pre-compiled library which has a lot of c++ pimpl idioms in its headers.

Pimpl automatically disables a lot of things from automatic bridging with note:

note: record '<xxx>' is not automatically available: does not have a copy constructor or destructor; does this type have reference semantics?

I was playing around it with SWIFT_NONCOPYABLE and SWIFT_UNSAFE_REFERENCE and found some things that seems a bit strange to me.

For example, I have approximately the following classes structure:

class Class1 {
public:
    Class1(long);
public:
    virtual ~Class1();
};

class Class2: Class1 {
public:
    Class2(); // cannot compile without this constructor when marking SWIFT_NONCOPYABLE
    Class2(const Class2 &) = delete;

    Class2(int);
    virtual ~Class2();

    class Private;
private:
    std::unique_ptr<Private> m_value;
}

I tried to use SWIFT_NONCOPYABLE directly applying to Class2:

class Class2: Class1 {
...
} SWIFT_NONCOPYABLE;

That did not help with the following outcome:

record 'Class2' is not automatically available: does not have a copy constructor or destructor; does this type have reference semantics
Other attempt

Placing SWIFT_NONCOPYABLE as was discussed in https://forums.swift.org/t/how-can-i-use-the-pimpl-idiom-with-std-unique-ptr-with-swift-c-interop/76606/5:

class SWIFT_NONCOPYABLE  Class2: Class1 {
...
};

led to compilation error:

Sources/CppTarget/Headers/LibCpp/Test.h:15:31: error: expected ';' after top level declarator
   15 | class SWIFT_NONCOPYABLE Class2: Class1 {
      |                               ^
      |                               ;

I tried other two ways.
First attempt:

struct WrapClass2_1 {
   WrapClass2_1(); // cannot compile without this constructor when marking SWIFT_NONCOPYABLE

   WrapClass2_1(Class2 && value);
   WrapClass2_1(int v);

private:
   Class2 m_value;
} SWIFT_NONCOPYABLE;

The same outcome:

note: record 'WrapClass2_1' is not automatically available: does not have a copy constructor or destructor; does this type have reference semantics?

Successful attempt: use Pimpl with c++ struct over the class with pimpl:

struct WrapClass2_2 {
   WrapClass2_2(); // cannot compile without this constructor when marking SWIFT_NONCOPYABLE

   WrapClass2_2(Class2 && value);
   WrapClass2_2(int v);

private:
   std::unique_ptr<Class2> m_value;
} SWIFT_NONCOPYABLE;

That one worked:

swift code
final class A { // wrap non-copyable
    let aa = Foo.WrapClass2_2(123)
    init() {}
}
print(A())
$ swift run
Building for debugging...
[7/7] Linking CppTargetTest
Build of product 'CppTargetTest' complete! (0.74s)
default ctor() called: why?
123
CppTargetTest.A
But not that good in fact

If add WrapClass2_2(const Class2 & value) = delete; everything will broke again...

So, I can wrap all the classes with struct pimpl over class pimpl and that will work.

There are some questions left that I didn't find answers for:

  1. Is it intentional to disallow c++ class (which is equal to swift struct) to be non-copyable?
  2. Would it be technically possible to make non-copyable but movable types make non-copyable in swift?
  3. Why should default constructor (without arguments) is required when adding SWIFT_NONCOPYABLE? and...
  4. Why is default constructor called when using non-default constructor?

Thanks in advance for helping with this topic.

My experiments with minimal sources are available at: external-reproducers/swift/swift-cpp-interop-non-copyable at main · ordo-one/external-reproducers · GitHub