1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
// RUN: %target-swift-frontend -typecheck -verify -primary-file %s %S/Inputs/struct_additive_arithmetic_other_module.swift
import _Differentiation
func testAdditiveArithmetic<T: AdditiveArithmetic>(
_ x: inout T
) {
// Test `AdditiveArithmetic` requirements: `zero`, `+`, `-`.
let zero = T.zero
x += x + zero
x -= x - zero
}
struct Empty: AdditiveArithmetic {}
func testEmpty() {
var empty = Empty()
testAdditiveArithmetic(&empty)
}
struct Int2: AdditiveArithmetic {
var a: Int
var b: Int
}
func testInt2() {
var int2 = Int2(a: 1, b: 1)
testAdditiveArithmetic(&int2)
}
// Test generic type.
struct Vector2<T: AdditiveArithmetic>: AdditiveArithmetic {
var x: T
var y: T
}
func testVector2() {
var vec2 = Vector2<Double>(x: 1, y: 1)
testAdditiveArithmetic(&vec2)
}
// Test nested type.
struct Nested: AdditiveArithmetic {
var int2: Int2
var int: Int
}
func testNested(int2: Int2) {
var nested = Nested(int2: int2, int: 1)
testAdditiveArithmetic(&nested)
}
// Test mixed type.
// Note: `Numeric` refines `AdditiveArithmetic`.
struct Mixed: AdditiveArithmetic {
var nested: Nested
var float: Float
var uint8: UInt8
}
func testMixed(nested: Nested) {
var mixed = Mixed(nested: nested, float: 1, uint8: 1)
testAdditiveArithmetic(&mixed)
}
// Test type in generic context.
struct A<T> {
struct B<U, V> {
struct GenericContextNested: AdditiveArithmetic {
var nested: Nested
var float: Float
var uint8: UInt8
}
}
}
func testGenericContext<T, U, V>(nested: Nested)
-> A<T>.B<U, V>.GenericContextNested
{
var genericNested =
A<T>.B<U, V>.GenericContextNested(nested: nested, float: 1, uint8: 1)
testAdditiveArithmetic(&genericNested)
return genericNested
}
// Test extension.
struct Extended {
var x: Int
}
extension Extended: Equatable, AdditiveArithmetic {}
// Test extension of generic type.
struct GenericExtended<T> {
var x: T
}
extension GenericExtended: Equatable, AdditiveArithmetic
where T: AdditiveArithmetic {}
// Test memberwise initializer synthesis.
struct NoMemberwiseInitializer<T: AdditiveArithmetic>: AdditiveArithmetic {
var value: T
init(randomLabel value: T) { self.value = value }
}
struct NoMemberwiseInitializerCustomZero: AdditiveArithmetic {
var x: Float
static var zero: Self { return NoMemberwiseInitializerCustomZero(0) }
init(_ x: Float) {
self.x = x
}
}
struct NoMemberwiseInitializerExtended<T> {
var value: T
init(_ value: T) {
self.value = value
}
}
extension NoMemberwiseInitializerExtended: Equatable, AdditiveArithmetic
where T: AdditiveArithmetic {}
// Test derived conformances in disallowed contexts.
extension OtherFileNonconforming: AdditiveArithmetic {}
// expected-error @-1 {{extension outside of file declaring struct 'OtherFileNonconforming' prevents automatic synthesis of 'zero' for protocol 'AdditiveArithmetic'}}
// expected-error @-2 {{extension outside of file declaring struct 'OtherFileNonconforming' prevents automatic synthesis of '+' for protocol 'AdditiveArithmetic'}}
// expected-error @-3 {{extension outside of file declaring struct 'OtherFileNonconforming' prevents automatic synthesis of '-' for protocol 'AdditiveArithmetic'}}
extension GenericOtherFileNonconforming: AdditiveArithmetic {}
// expected-error @-1 {{extension outside of file declaring generic struct 'GenericOtherFileNonconforming' prevents automatic synthesis of 'zero' for protocol 'AdditiveArithmetic'}}
// expected-error @-2 {{extension outside of file declaring generic struct 'GenericOtherFileNonconforming' prevents automatic synthesis of '+' for protocol 'AdditiveArithmetic'}}
// expected-error @-3 {{extension outside of file declaring generic struct 'GenericOtherFileNonconforming' prevents automatic synthesis of '-' for protocol 'AdditiveArithmetic'}}
|