Skip to content

Found consume that was not recorded as a 'claimed consume'! in MoveOnlyChecker SIL pass #89250

@FranzBusch

Description

@FranzBusch

Description

A ~Copyable struct that conforms to a ~Copyable protocol with a consuming requirement taking a closure crashes the SIL MoveOnlyChecker pass when its witness:

  1. Calls another consuming witness on a stored property (partially consuming self)
  2. Passes an @noescape closure to that call which captures another stored property of self

Without the protocol (i.e. concrete-type calls), the compiler emits a clean 'self' used after consume diagnostic. The crash is specific to the protocol-witness code path.

Reproduction

  public protocol BodyWriter: ~Copyable {
      consuming func finish(body: (inout Int) -> Void)
  }

  public struct BaseWriter: BodyWriter, ~Copyable {
      public init() {}
      public consuming func finish(body: (inout Int) -> Void) {
          var x = 0
          body(&x)
      }
  }

  public struct WrappingWriter<Base: BodyWriter & ~Copyable>: BodyWriter, ~Copyable {
      var underlying: Base
      let label: String

      public init(wrapping underlying: consuming Base, label: String) {
          self.underlying = underlying
          self.label = label
      }

      public consuming func finish(body: (inout Int) -> Void) {
          self.underlying.finish { (buf: inout Int) -> Void in
              body(&buf)
              print(self.label)   // captures another stored property of self
          }
      }
  }

Expected behavior

Doesn't crash the compiler

Environment

swift-driver version: 1.166 Apple Swift version 6.4 (swiftlang-6.4.0.19.4 clang-2100.3.19.4)

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    triage neededThis issue needs more specific labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions