Files
swift-mirror/test/ModuleInterface/pre_inverse_generics_except.swift
T
Kavon Farvardin 19119ad88a introduce @_preInverseGenerics(except:)
@_preInverseGenerics(except: <inverses>) is an extension of the existing
@_preInverseGenerics attribute that provides selective control over which
inverse requirements are mangled into a declaration's symbol name.

While the bare @_preInverseGenerics strips all inverse constraints
(~Copyable and ~Escapable) from mangling, the 'except:' form allows specific
inverses to be retained. This is needed when a type like Span already had
~Copyable mangled into its ABI-stable symbols and now needs to retroactively
adopt ~Escapable without changing those existing symbols. You can now express
that with `@_preInverseGenerics(except: ~Copyable)` to strip-out every inverse
except ~Copyable to preserve the pre-existing ~Copyable-containing symbols.

It requires the new experimental feature `PreInverseGenericsExcept`.

rdar://176395527
2026-05-14 18:27:00 -07:00

44 lines
2.0 KiB
Swift

// RUN: %empty-directory(%t)
// RUN: %target-swift-emit-module-interface(%t/Test.swiftinterface) %s \
// RUN: -module-name Test \
// RUN: -enable-experimental-feature PreInverseGenericsExcept
// RUN: %FileCheck --implicit-check-not '#if' %s < %t/Test.swiftinterface
// REQUIRES: swift_feature_PreInverseGenericsExcept
// The bare @_preInverseGenerics needs no feature guard.
// CHECK: @_preInverseGenerics public func bare<T>(_ t: borrowing T) where T : ~Copyable
@_preInverseGenerics
public func bare<T: ~Copyable>(_ t: borrowing T) {}
// The except: form requires a #if $PreInverseGenericsExcept guard.
// Older compilers that don't support the feature will not see the declaration.
// CHECK: #if compiler(>=5.3) && $PreInverseGenericsExcept
// CHECK-NEXT: @_preInverseGenerics(except: ~Copyable) public func exceptCopyable<T>(_ t: borrowing T) where T : ~Copyable, T : ~Escapable
// CHECK-NEXT: #endif
@_preInverseGenerics(except: ~Copyable)
public func exceptCopyable<T: ~Copyable & ~Escapable>(_ t: borrowing T) {}
// CHECK: #if compiler(>=5.3) && $PreInverseGenericsExcept
// CHECK-NEXT: @_preInverseGenerics(except: ~Escapable) public func exceptEscapable<T>(_ t: borrowing T) where T : ~Copyable, T : ~Escapable
// CHECK-NEXT: #endif
@_preInverseGenerics(except: ~Escapable)
public func exceptEscapable<T: ~Copyable & ~Escapable>(_ t: borrowing T) {}
// CHECK: #if compiler(>=5.3) && $PreInverseGenericsExcept
// CHECK-NEXT: @_preInverseGenerics(except: ~Copyable & ~Escapable) public func exceptBoth<T>(_ t: borrowing T) where T : ~Copyable, T : ~Escapable
@_preInverseGenerics(except: ~Copyable & ~Escapable)
public func exceptBoth<T: ~Copyable & ~Escapable>(_ t: borrowing T) {}
@frozen
public struct MySpan<T: ~Copyable & ~Escapable>: ~Copyable {
// CHECK: #if compiler(>=5.3) && $PreInverseGenericsExcept
// CHECK-NEXT: @_preInverseGenerics(except: ~Copyable) public var _count: Swift::Int
// CHECK-NEXT: #endif
@_preInverseGenerics(except: ~Copyable)
public var _count: Int
}