From 6f3bb493b42b554b620172c92a51f349e71e8d06 Mon Sep 17 00:00:00 2001 From: Nate Chandler Date: Thu, 8 Feb 2024 17:52:17 -0800 Subject: [PATCH] [BitwiseCopyable] Verify only within module. Don't verify lowering in modules built from swiftinterface (which may not have been built with `-enable-experimental-feature BitwiseCopyable`) Allow trivial types defined in other modules to lack conformance because those modules may not have been built with the feature enabled. --- lib/SIL/IR/TypeLowering.cpp | 22 ++++++++++++++++++++-- test/IRGen/bitwise_copyable.swift | 6 ++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/lib/SIL/IR/TypeLowering.cpp b/lib/SIL/IR/TypeLowering.cpp index 8529aa8ca9e56..ca11bd30bb539 100644 --- a/lib/SIL/IR/TypeLowering.cpp +++ b/lib/SIL/IR/TypeLowering.cpp @@ -3038,6 +3038,15 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering, auto conformance = M.checkConformance(substType, bitwiseCopyableProtocol); + if (auto *nominal = substType.getAnyNominal()) { + auto *module = nominal->getModuleContext(); + if (module && module->isBuiltFromInterface()) { + // Don't verify for types in modules built from interfaces; the feature + // may not have been enabled in them. + return; + } + } + if (lowering.isTrivial() && !conformance) { // A trivial type can lack a conformance in a few cases: // (1) containing or being a resilient type @@ -3054,6 +3063,7 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering, // struct S { // unowned(unsafe) var o: AnyObject // } + // (5) being defined in a different module bool hasNoNonconformingNode = visitAggregateLeaves( origType, substType, forExpansion, /*isLeafAggregate=*/ @@ -3072,7 +3082,11 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering, } // Resilient trivial types may not conform (case (1)). - return nominal->isResilient(); + if (nominal->isResilient()) + return true; + + // Trivial types from other modules may not conform (case (5)). + return nominal->getModuleContext() != &M; }, /*visit=*/ [&](auto ty, auto origTy, auto *field, auto index) -> bool { @@ -3128,7 +3142,11 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering, } // Resilient trivial types may not conform (case (1)). - return !nominal->isResilient(); + if (nominal->isResilient()) + return false; + + // Trivial types from other modules may not conform (case (5)). + return nominal->getModuleContext() == &M; }); if (hasNoNonconformingNode) { llvm::errs() << "Trivial type without a BitwiseCopyable conformance!?:\n" diff --git a/test/IRGen/bitwise_copyable.swift b/test/IRGen/bitwise_copyable.swift index ece6e2b8162b0..55cd75a033546 100644 --- a/test/IRGen/bitwise_copyable.swift +++ b/test/IRGen/bitwise_copyable.swift @@ -6,9 +6,11 @@ // RUN: -enable-builtin-module // REQUIRES: asserts +// REQUIRES: objc_interop // Force verification of TypeLowering's isTrivial. +import Foundation import Builtin struct Box : _BitwiseCopyable { @@ -32,3 +34,7 @@ func nameBuiltinBridgeObject(_ b: Builtin.BridgeObject) {} func nameBuiltinUnsafeValueBuffer(_ b: Builtin.UnsafeValueBuffer) {} func nameBuiltinDefaultActorStorage(_ b: Builtin.DefaultActorStorage) {} func nameBuiltinNonDefaultDistributedActorStorage(_ b: Builtin.NonDefaultDistributedActorStorage) {} + +struct MyObjCBool { + var value: ObjCBool +}