// RUN: %empty-directory(%t) // RUN: %target-swift-frontend %s -module-name Generics -enable-experimental-cxx-interop -typecheck -verify -emit-clang-header-path %t/generics.h // RUN: %FileCheck %s < %t/generics.h // RUN: %check-interop-cxx-header-in-clang(%t/generics.h -Wno-reserved-identifier -DSWIFT_CXX_INTEROP_HIDE_STL_OVERLAY) // RUN: %empty-directory(%t) // RUN: %target-swift-frontend %s -enable-library-evolution -module-name Generics -clang-header-expose-decls=all-public -typecheck -verify -emit-clang-header-path %t/generics.h // RUN: %FileCheck %s < %t/generics.h // RUN: %check-interop-cxx-header-in-clang(%t/generics.h -Wno-reserved-identifier -DSWIFT_CXX_INTEROP_HIDE_STL_OVERLAY) // FIXME: remove the need for -Wno-reserved-identifier public class TracksDeinit { init() { print("init-TracksDeinit") } deinit { print("destroy-TracksDeinit") } } public func constructTracksDeinit() -> TracksDeinit { return TracksDeinit() } @frozen public struct StructForEnum { let x: TracksDeinit public init() { x = TracksDeinit() } } @frozen public enum GenericOpt { // expected-note@-1 {{'T' previously declared here}} case none case some(T) public func method() { let copyOfSelf = self print("GenericOpt::testme::\(copyOfSelf);") } public mutating func reset() { self = .none } public func genericMethod(_ x: T) -> T { // expected-warning@-1 {{generic parameter 'T' shadows generic parameter from outer scope with the same name}} print("GenericOpt::genericMethod::\(self),\(x);") return x } public var computedProp: Int { return 42 } } public func makeGenericOpt(_ x: T) -> GenericOpt { return .some(x) } public func makeConcreteOpt(_ x: UInt16) -> GenericOpt { return GenericOpt.some(x) } public func takeGenericOpt(_ x: GenericOpt) { print(x) } public func takeConcreteOpt(_ x: GenericOpt) { print("CONCRETE opt:", x, ";") } public func inoutGenericOpt(_ x: inout GenericOpt, _ y: T) { switch (x) { case .some: x = .none case .none: x = .some(y) } } public func inoutConcreteOpt(_ x: inout GenericOpt) { switch (x) { case .some(let x_): x = .some(x_ * 3) case .none: break } } @frozen public enum GenericCustomType { case success(T?) case failure } // CHECK: namespace Generics SWIFT_PRIVATE_ATTR SWIFT_SYMBOL_MODULE("Generics") { // CHECK: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: class SWIFT_SYMBOL("s:8Generics17GenericCustomTypeO") GenericCustomType; // CHECK: inline const constexpr bool isOpaqueLayout> = true; // CHECK: template // CHECK: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: class SWIFT_SYMBOL("s:8Generics10GenericOptO") GenericOpt; // CHECK: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: inline const constexpr bool isUsableInGenericContext> = isUsableInGenericContext; // CHECK: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: class _impl_GenericOpt; // CHECK: SWIFT_EXTERN swift::_impl::MetadataResponseTy $s8Generics10GenericOptOMa(swift::_impl::MetadataRequestTy, void * _Nonnull) SWIFT_NOEXCEPT SWIFT_CALL; // CHECK: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: class SWIFT_SYMBOL("s:8Generics10GenericOptO") GenericOpt final { // CHECK-NEXT: public: // CHECK-NEXT: #ifndef __cpp_concepts // CHECK-NEXT: static_assert(swift::isUsableInGenericContext, "type cannot be used in a Swift generic context"); // CHECK-NEXT: #endif // CHECK-NEXT: SWIFT_INLINE_THUNK ~GenericOpt() noexcept { // CHECK-NEXT: auto metadata = _impl::$s8Generics10GenericOptOMa(0, swift::TypeMetadataTrait::getTypeMetadata()); // CHECK-NEXT: auto *vwTableAddr = reinterpret_cast(metadata._0) - 1; // CHECK-NEXT: #ifdef __arm64e__ // CHECK-NEXT: auto *vwTable = reinterpret_cast(ptrauth_auth_data(reinterpret_cast(*vwTableAddr), ptrauth_key_process_independent_data, ptrauth_blend_discriminator(vwTableAddr, 11839))); // CHECK-NEXT: #else // CHECK-NEXT: auto *vwTable = *vwTableAddr; // CHECK-NEXT: #endif // CHECK-NEXT: vwTable->destroy(_getOpaquePointer(), metadata._0); // CHECK-NEXT: } // CHECK: enum class cases { // CHECK-NEXT: some SWIFT_SYMBOL("s:8Generics10GenericOptO4someyACyxGxcAEmlF"), // CHECK-NEXT: none SWIFT_SYMBOL("s:8Generics10GenericOptO4noneyACyxGAEmlF") // CHECK-NEXT: }; // CHECK: SWIFT_INLINE_THUNK GenericOpt operator()(const T_0_0& val) const; // CHECK-NEXT: } some SWIFT_SYMBOL("s:8Generics10GenericOptO4someyACyxGxcAEmlF"); // CHECK: SWIFT_INLINE_THUNK GenericOpt operator()() const; // CHECK-NEXT: } none SWIFT_SYMBOL("s:8Generics10GenericOptO4noneyACyxGAEmlF"); // CHECK: SWIFT_INLINE_THUNK operator cases() const { // CHECK-NEXT: switch (_getEnumTag()) { // CHECK-NEXT: case 0: return cases::some; // CHECK-NEXT: case 1: return cases::none; // CHECK-NEXT: default: abort(); // CHECK-NEXT: } // CHECK-NEXT: } // CHECK: SWIFT_INLINE_THUNK void method() const SWIFT_SYMBOL("s:8Generics10GenericOptO6methodyyF"); // CHECK-NEXT: SWIFT_INLINE_THUNK void reset() SWIFT_SYMBOL("s:8Generics10GenericOptO5resetyyF"); // CHECK-NEXT: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: SWIFT_INLINE_THUNK T_1_0 genericMethod(const T_1_0& x) const SWIFT_SYMBOL("s:8Generics10GenericOptO13genericMethodyqd__qd__lF"); // CHECK-NEXT: SWIFT_INLINE_THUNK swift::Int getComputedProp() const SWIFT_SYMBOL("s:8Generics10GenericOptO12computedPropSivp"); // CHECK: SWIFT_INLINE_THUNK void inoutConcreteOpt(GenericOpt& x) noexcept SWIFT_SYMBOL("s:8Generics16inoutConcreteOptyyAA07GenericD0Oys6UInt16VGzF") { // CHECK-NEXT: Generics::_impl::$s8Generics16inoutConcreteOptyyAA07GenericD0Oys6UInt16VGzF(Generics::_impl::_impl_GenericOpt::getOpaquePointer(x)); // CHECK-NEXT: } // CHECK: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: SWIFT_INLINE_THUNK void inoutGenericOpt(GenericOpt& x, const T_0_0& y) noexcept SWIFT_SYMBOL("s:8Generics15inoutGenericOptyyAA0cD0OyxGz_xtlF") { // CHECK-NEXT: #ifndef __cpp_concepts // CHECK-NEXT: static_assert(swift::isUsableInGenericContext, "type cannot be used in a Swift generic context"); // CHECK-NEXT: #endif // CHECK-NEXT: Generics::_impl::$s8Generics15inoutGenericOptyyAA0cD0OyxGz_xtlF(Generics::_impl::_impl_GenericOpt::getOpaquePointer(x), swift::_impl::getOpaquePointer(y), swift::TypeMetadataTrait::getTypeMetadata()); // CHECK-NEXT: } // CHECK: SWIFT_INLINE_THUNK GenericOpt makeConcreteOpt(uint16_t x) noexcept SWIFT_SYMBOL("s:8Generics15makeConcreteOptyAA07GenericD0Oys6UInt16VGAFF") SWIFT_WARN_UNUSED_RESULT { // CHECK-NEXT: return Generics::_impl::_impl_GenericOpt::returnNewValue([&](char * _Nonnull result) SWIFT_INLINE_THUNK_ATTRIBUTES { // CHECK-NEXT: Generics::_impl::swift_interop_returnDirect_Generics_uint32_t_0_4(result, Generics::_impl::$s8Generics15makeConcreteOptyAA07GenericD0Oys6UInt16VGAFF(x)); // CHECK-NEXT: }); // CHECK-NEXT: } // CHECK: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: SWIFT_INLINE_THUNK GenericOpt makeGenericOpt(const T_0_0& x) noexcept SWIFT_SYMBOL("s:8Generics14makeGenericOptyAA0cD0OyxGxlF") SWIFT_WARN_UNUSED_RESULT { // CHECK-NEXT: #ifndef __cpp_concepts // CHECK-NEXT: static_assert(swift::isUsableInGenericContext, "type cannot be used in a Swift generic context"); // CHECK-NEXT: #endif // CHECK-NEXT: return Generics::_impl::_impl_GenericOpt::returnNewValue([&](char * _Nonnull result) SWIFT_INLINE_THUNK_ATTRIBUTES { // CHECK-NEXT: Generics::_impl::$s8Generics14makeGenericOptyAA0cD0OyxGxlF(result, swift::_impl::getOpaquePointer(x), swift::TypeMetadataTrait::getTypeMetadata()); // CHECK-NEXT: }); // CHECK-NEXT: } // CHECK: SWIFT_INLINE_THUNK void takeConcreteOpt(const GenericOpt& x) noexcept SWIFT_SYMBOL("s:8Generics15takeConcreteOptyyAA07GenericD0Oys6UInt16VGF") { // CHECK-NEXT: Generics::_impl::$s8Generics15takeConcreteOptyyAA07GenericD0Oys6UInt16VGF(Generics::_impl::swift_interop_passDirect_Generics_uint32_t_0_4(Generics::_impl::_impl_GenericOpt::getOpaquePointer(x))); // CHECK-NEXT: } // CHECK: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: SWIFT_INLINE_THUNK void takeGenericOpt(const GenericOpt& x) noexcept SWIFT_SYMBOL("s:8Generics14takeGenericOptyyAA0cD0OyxGlF") { // CHECK-NEXT: #ifndef __cpp_concepts // CHECK-NEXT: static_assert(swift::isUsableInGenericContext, "type cannot be used in a Swift generic context"); // CHECK-NEXT: #endif // CHECK-NEXT: Generics::_impl::$s8Generics14takeGenericOptyyAA0cD0OyxGlF(Generics::_impl::_impl_GenericOpt::getOpaquePointer(x), swift::TypeMetadataTrait::getTypeMetadata()); // CHECK-NEXT: } // CHECK: SWIFT_INLINE_THUNK bool GenericCustomType::isFailure() const { // CHECK: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // __cpp_concepts // CHECK-NEXT: SWIFT_INLINE_THUNK GenericOpt GenericOpt::_impl_some::operator()(const T_0_0& val) const { // CHECK-NEXT: auto result = GenericOpt::_make(); // CHECK-NEXT: #pragma clang diagnostic push // CHECK-NEXT: #pragma clang diagnostic ignored "-Wc++17-extensions" // CHECK-NEXT: if constexpr (std::is_base_of<::swift::_impl::RefCountedClass, T_0_0>::value) { // CHECK-NEXT: void *ptr = ::swift::_impl::_impl_RefCountedClass::copyOpaquePointer(val); // CHECK-NEXT: memcpy(result._getOpaquePointer(), &ptr, sizeof(ptr)); // CHECK-NEXT: } else if constexpr (::swift::_impl::isValueType) { // CHECK-NEXT: alignas(T_0_0) unsigned char buffer[sizeof(T_0_0)]; // CHECK-NEXT: auto *valCopy = new(buffer) T_0_0(val); // CHECK-NEXT: swift::_impl::implClassFor::type::initializeWithTake(result._getOpaquePointer(), swift::_impl::implClassFor::type::getOpaquePointer(*valCopy)); // CHECK-NEXT: } else { // CHECK-NEXT: memcpy(result._getOpaquePointer(), &val, sizeof(val)); // CHECK-NEXT: } // CHECK-NEXT: #pragma clang diagnostic pop // CHECK-NEXT: result._destructiveInjectEnumTag(0); // CHECK-NEXT: return result; // CHECK-NEXT: } // CHECK-NEXT: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: SWIFT_INLINE_THUNK bool GenericOpt::isSome() const { // CHECK-NEXT: return *this == GenericOpt::some; // CHECK-NEXT: } // CHECK-NEXT: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: SWIFT_INLINE_THUNK T_0_0 GenericOpt::getSome() const { // CHECK-NEXT: if (!isSome()) abort(); // CHECK-NEXT: alignas(GenericOpt) unsigned char buffer[sizeof(GenericOpt)]; // CHECK-NEXT: auto *thisCopy = new(buffer) GenericOpt(*this); // CHECK-NEXT: char * _Nonnull payloadFromDestruction = thisCopy->_destructiveProjectEnumData(); // CHECK-NEXT: #pragma clang diagnostic push // CHECK-NEXT: #pragma clang diagnostic ignored "-Wc++17-extensions" // CHECK-NEXT: if constexpr (std::is_base_of<::swift::_impl::RefCountedClass, T_0_0>::value) { // CHECK-NEXT: void *returnValue; // CHECK-NEXT: returnValue = *reinterpret_cast(payloadFromDestruction); // CHECK-NEXT: return ::swift::_impl::implClassFor::type::makeRetained(returnValue); // CHECK-NEXT: } else if constexpr (::swift::_impl::isValueType) { // CHECK-NEXT: return ::swift::_impl::implClassFor::type::returnNewValue([&](void * _Nonnull returnValue) SWIFT_INLINE_THUNK_ATTRIBUTES { // CHECK-NEXT: return ::swift::_impl::implClassFor::type::initializeWithTake(reinterpret_cast(returnValue), payloadFromDestruction); // CHECK-NEXT: }); // CHECK-NEXT: } else if constexpr (::swift::_impl::isSwiftBridgedCxxRecord) { // CHECK-NEXT: abort(); // CHECK-NEXT: } else { // CHECK-NEXT: T_0_0 returnValue; // CHECK-NEXT: memcpy(&returnValue, payloadFromDestruction, sizeof(returnValue)); // CHECK-NEXT: return returnValue; // CHECK-NEXT: } // CHECK-NEXT: #pragma clang diagnostic pop // CHECK-NEXT: } // CHECK-NEXT: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // __cpp_concepts // CHECK-NEXT: SWIFT_INLINE_THUNK GenericOpt GenericOpt::_impl_none::operator()() const { // CHECK-NEXT: auto result = GenericOpt::_make(); // CHECK-NEXT: result._destructiveInjectEnumTag(1); // CHECK-NEXT: return result; // CHECK-NEXT: } // CHECK-NEXT: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: SWIFT_INLINE_THUNK bool GenericOpt::isNone() const { // CHECK-NEXT: return *this == GenericOpt::none; // CHECK-NEXT: } // CHECK: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: SWIFT_INLINE_THUNK void GenericOpt::method() const { // CHECK-NEXT: #ifndef __cpp_concepts // CHECK-NEXT: static_assert(swift::isUsableInGenericContext, "type cannot be used in a Swift generic context"); // CHECK-NEXT: #endif // CHECK-NEXT: Generics::_impl::$s8Generics10GenericOptO6methodyyF(swift::TypeMetadataTrait>::getTypeMetadata(), _getOpaquePointer()); // CHECK-NEXT: } // CHECK: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: void GenericOpt::reset() // CHECK: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: SWIFT_INLINE_THUNK T_1_0 GenericOpt::genericMethod(const T_1_0& x) const { // CHECK: template // CHECK-NEXT: #ifdef __cpp_concepts // CHECK-NEXT: requires swift::isUsableInGenericContext // CHECK-NEXT: #endif // CHECK-NEXT: SWIFT_INLINE_THUNK swift::Int GenericOpt::getComputedProp() const { // CHECK-NEXT: #ifndef __cpp_concepts // CHECK-NEXT: static_assert(swift::isUsableInGenericContext, "type cannot be used in a Swift generic context"); // CHECK-NEXT: #endif // CHECK-NEXT: return Generics::_impl::$s8Generics10GenericOptO12computedPropSivg(swift::TypeMetadataTrait>::getTypeMetadata(), _getOpaquePointer()); // CHECK-NEXT: }