mirror of
https://github.com/apple/swift.git
synced 2026-06-20 15:42:51 +02:00
19119ad88a
@_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
41 lines
1.9 KiB
Swift
41 lines
1.9 KiB
Swift
// RUN: %target-typecheck-verify-swift -enable-experimental-feature PreInverseGenericsExcept
|
|
|
|
// REQUIRES: swift_feature_PreInverseGenericsExcept
|
|
|
|
@_preInverseGenerics
|
|
func bare<T: ~Copyable>(_ t: borrowing T) {}
|
|
|
|
@_preInverseGenerics(except: ~Copyable)
|
|
func exceptCopyable<T: ~Copyable & ~Escapable>(_ t: borrowing T) {}
|
|
|
|
@_preInverseGenerics(except: ~Escapable)
|
|
func exceptEscapable<T: ~Copyable & ~Escapable>(_ t: borrowing T) {}
|
|
|
|
// excepting all inverses is equivalent to not using the attribute
|
|
@_preInverseGenerics(except: ~Copyable & ~Escapable) // expected-warning {{'@_preInverseGenerics' that excepts all inverse constraints is equivalent to not using the attribute}}
|
|
func exceptBoth<T: ~Copyable & ~Escapable>(_ t: borrowing T) {}
|
|
|
|
// `except: Any` is confusing; reject it in favor of the bare form.
|
|
@_preInverseGenerics(except: Any) // expected-error {{'except' argument to '@_preInverseGenerics' must consist only of inverse constraints such as '~Copyable' or '~Escapable'}}
|
|
func exceptAny<T: ~Copyable & ~Escapable>(_ t: borrowing T) {}
|
|
|
|
// wrong label
|
|
@_preInverseGenerics(foo: ~Copyable) // expected-error {{expected 'except:' argument in '@_preInverseGenerics'}}
|
|
func bad1() {}
|
|
|
|
// non-inverse type
|
|
@_preInverseGenerics(except: Int) // expected-error {{'except' argument to '@_preInverseGenerics' must consist only of inverse constraints such as '~Copyable' or '~Escapable'}}
|
|
func bad2() {}
|
|
|
|
// positive protocol (not inverted)
|
|
@_preInverseGenerics(except: Copyable) // expected-error {{'except' argument to '@_preInverseGenerics' must consist only of inverse constraints such as '~Copyable' or '~Escapable'}}
|
|
func bad3() {}
|
|
|
|
// Warning: attribute on extension has no effect
|
|
struct S<T: ~Copyable>: ~Copyable {}
|
|
|
|
@_preInverseGenerics // expected-warning {{'@_preInverseGenerics' has no effect on an extension; place it on individual members instead}}
|
|
extension S where T: ~Copyable {
|
|
func extMethod() {}
|
|
}
|