diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp index 9988de7c6bc95..cdbeee80d29b1 100644 --- a/lib/IRGen/GenProto.cpp +++ b/lib/IRGen/GenProto.cpp @@ -959,8 +959,13 @@ namespace { /// Return true if the witness table requires runtime instantiation to /// handle resiliently-added requirements with default implementations. +/// +/// If disableOptimizations is true, skip optimizations that treat +/// formally-resilient conformances as non-resilient. bool IRGenModule::isResilientConformance( - const NormalProtocolConformance *conformance) { + const NormalProtocolConformance *conformance, + bool disableOptimizations +) { // If the protocol is not resilient, the conformance is not resilient // either. bool shouldTreatProtocolNonResilient = @@ -992,16 +997,18 @@ bool IRGenModule::isResilientConformance( // This is an optimization -- a conformance of a non-generic type cannot // resiliently become dependent. if (!conformance->getDeclContext()->isGenericContext() && - conformanceModule == conformance->getProtocol()->getParentModule()) + conformanceModule == conformance->getProtocol()->getParentModule() && + !disableOptimizations) return false; // We have a resilient conformance. return true; } -bool IRGenModule::isResilientConformance(const RootProtocolConformance *root) { +bool IRGenModule::isResilientConformance(const RootProtocolConformance *root, + bool disableOptimizations) { if (auto normal = dyn_cast(root)) - return isResilientConformance(normal); + return isResilientConformance(normal, disableOptimizations); // Self-conformances never require this. return false; } @@ -1185,7 +1192,9 @@ bool IRGenModule::isDependentConformance( const RootProtocolConformance *conformance) { llvm::SmallPtrSet visited; return ::isDependentConformance( - *this, conformance, conformance->getProtocol()->isResilient(), visited); + *this, conformance, + isResilientConformance(conformance, /*disableOptimizations=*/true), + visited); } static llvm::Value * diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h index aa81382c0a48a..8ee9edf61fc86 100644 --- a/lib/IRGen/IRGenModule.h +++ b/lib/IRGen/IRGenModule.h @@ -1119,8 +1119,10 @@ class IRGenModule { TypeExpansionContext getMaximalTypeExpansionContext() const; - bool isResilientConformance(const NormalProtocolConformance *conformance); - bool isResilientConformance(const RootProtocolConformance *root); + bool isResilientConformance(const NormalProtocolConformance *conformance, + bool disableOptimizations = false); + bool isResilientConformance(const RootProtocolConformance *root, + bool disableOptimizations = false); bool isDependentConformance(const RootProtocolConformance *conformance); Alignment getCappedAlignment(Alignment alignment); diff --git a/test/IRGen/protocol_resilience_sendable.swift b/test/IRGen/protocol_resilience_sendable.swift index d4c0fa138b1bd..cdc0c5fb81ac8 100644 --- a/test/IRGen/protocol_resilience_sendable.swift +++ b/test/IRGen/protocol_resilience_sendable.swift @@ -6,11 +6,37 @@ // RUN: %target-swift-frontend -I %t -emit-ir %s -target %target-cpu-apple-macos14.0 | %FileCheck %s -DINT=i%target-ptrsize -check-prefix=CHECK-USAGE -check-prefix=CHECK-USAGE-BEFORE // RUN: %target-swift-frontend -I %t -emit-ir %s -target %target-cpu-apple-macos15.0 | %FileCheck %s -DINT=i%target-ptrsize -check-prefix=CHECK-USAGE -check-prefix=CHECK-USAGE-AFTER +// RUN: %target-swift-frontend -I %t -emit-ir %s -target %target-cpu-apple-macos14.0 -enable-library-evolution | %FileCheck %s -DINT=i%target-ptrsize -check-prefix=CHECK-USAGE -check-prefix=CHECK-USAGE-BEFORE +// RUN: %target-swift-frontend -I %t -emit-ir %s -target %target-cpu-apple-macos15.0 -enable-library-evolution | %FileCheck %s -DINT=i%target-ptrsize -check-prefix=CHECK-USAGE -check-prefix=CHECK-USAGE-AFTER + // REQUIRES: OS=macosx import resilient_protocol import non_resilient_protocol +// CHECK-USAGE: @"$s28protocol_resilience_sendable9LocalTypeVAA0D11SubProtocolAAWP" = hidden constant [3 x ptr] [ +// CHECK-USAGE-SAME: ptr @"$s28protocol_resilience_sendable9LocalTypeVAA0D11SubProtocolAAMc", +// CHECK-USAGE-SAME: ptr @"$s28protocol_resilience_sendable9LocalTypeVAA0D8ProtocolAAWP", +// CHECK-USAGE-SAME: ptr @"$s28protocol_resilience_sendable9LocalTypeVAA0D11SubProtocolA2aDP9subMethodyyFTW" +public protocol LocalProtocol: Sendable { + func method() +} + +protocol LocalSubProtocol: Sendable, LocalProtocol { + func subMethod() +} + +struct LocalType: Sendable, LocalSubProtocol { + func method() { } + func subMethod() { } +} + +func acceptLocalProtocol(_: T.Type) { } +func testLocalType() { + acceptLocalProtocol(LocalType.self) +} + + func acceptResilientSendableBase(_: T.Type) { } // CHECK-USAGE: define{{.*}}swiftcc void @"$s28protocol_resilience_sendable25passResilientSendableBaseyyF"()