[Accepted] SE-0390: Noncopyable structs and enums

@Joe_Groff @Michael_Gottesman @kavon I've posted an update to SE-0390: Noncopyable structs and enums; Deinitialization #2432. The proposal was accepted, but a few people noticed incorrect wording in the definition of strict lifetimes for noncopyable types. This update makes the proposal consistent with the implementation and with what was discussed in the this review thread. In the process, I clarified the related example. I renamed the example's noncopyable struct to File because current and future FileDescriptor types will likely be copyable.

11 Likes

Personally, I call it the sans operator, and pronounce ~Copyable as sans Copyable, using sans to mean without implying conformance to.


@Andrew_Trick - In the proposal, there's a code example that confused me:

struct FileDescriptor: ~Copyable {
  private var fd: Int32

  init(fd: Int32) { self.fd = fd }

  func write(buffer: Data) {
    buffer.withUnsafeBytes { 
      write(fd, $0.baseAddress!, $0.count)
    }
  }

  deinit {
    close(fd)
  }
}

Presumably, the line write(fd, $0.baseAddress!, $0.count) would call self.write, but the signature is wrong.

I understand it's just example code, but wondered if I misunderstood something??

It’s calling write(2)

4 Likes

Oh, I see now. Thank you, @Slava_Pestov.

I was thinking it would call self.write because self has a member called write, as if it matched the name first (to methods of that name), then matched the signature (to the correct overload from amongst them). I don't know why I thought that.

Thanks again.

That actually is how overload resolution works today, more or less—once the member with that basename is found, I think it stops searching. The code in that snippet won't compile without an explicit Darwin./Glibc. qualifier to explicitly request the global function: Compiler Explorer

4 Likes

Ahh. Thank you, @allevato. I appreciate the clarification.