Implement Copyable protocol in a class hierarchy

:pushpin:
The only partially satisfying realization in my opinion looks like this:

protocol Copyable: AnyObject {
	init(_ copy: Self)
}

class A: Copyable {
	var bar = 21
	
	init() {
	}
	
	required init(_ copy: A) {
		self.bar = copy.bar
	}
}

class B: A {
	var baz = 22
	
	override init() {
		super.init()
	}
	
	required init(_ copy: B) {
		self.baz = copy.baz
		super.init(copy)
	}
	
	@available(*, unavailable)
	required init(_ copy: A) {
		fatalError()
	}
}

final class C: B {
	var qux = 23
	
	override init() {
		super.init()
	}
	
	required init(_ copy: C) {
		self.qux = copy.qux
		super.init(copy)
	}
	
	@available(*, unavailable)
	required init(_ copy: B) {
		fatalError()
	}
}

This approach is good because it forces us to implement the initializer we need in every possible subclass. But with that it brings one big headache, the requirement, in view of the required, it is also necessary to redefine the copy initializer inherited. We have to define it, mark it as inaccessible and provide a repeated implementation everywhere. The main question is why should we do it?

Also, due to the special rules of initializer inheritance, we have to drag the most common default initializer through the whole hierarchy. But this is if you need it, of course.

:pushpin:
The alternative realization is absolutely as far as I am concerned does not tolerate any comment:

protocol Copyable: AnyObject {
	func copy() -> Self
}

class A: Copyable {
	var bar = 21
	
	func copy() -> Self {
		precondition(type(of: self) == A.self)
		return A(bar: bar) as! Self
	}
	
	init(bar: Int = 21) {
		self.bar = bar
	}
}

class B: A {
	var baz = 22
	
	override func copy() -> Self {
		precondition(type(of: self) == B.self)
		return B(baz: baz, bar: bar) as! Self
	}
	
	init(baz: Int = 22, bar: Int = 21) {
		self.baz = baz
		super.init(bar: bar)
	}
}

:pushpin:
So why is it so complicated and extremely inexpressive? Is there really no way to avoid such a headache for developers? And is the language itself planning to do something about it?

Something similar:

Classes are reference types, so they all support copying implicitly, via copying of the reference. That's a shallow copy of the object that Swift uses by default for classes. It's also what Copyable, as briefly alluded to in SE-390, will most likely mean for classes. For example, b is semantically a shallow copy of a here:

let a = MyClass()
let b = a

The compiler will optimize this when possible so we don't actually do any shallow copy for b, which would require us to increment the reference count of a.

My impression of your version of Copyable here is that it means the type supports creating a deep copy of the object, via a requirement to define a copy-init in all conformers. I think in that case you'd also want a sort of clone method requirement too so that in these copy-inits, you call clone on each property of the "other" instance to get a deep copy instead.