mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
203 lines
7.6 KiB
Swift
203 lines
7.6 KiB
Swift
// RUN: %empty-directory(%t)
|
|
|
|
// -- build resilient library
|
|
// RUN: %target-build-swift -whole-module-optimization -enable-library-evolution -module-name ExtraInhabitantResilientTypes -emit-module-path %t/ExtraInhabitantResilientTypes.swiftmodule -parse-as-library -c -o %t/ExtraInhabitantResilientTypes.o %S/Inputs/struct_extra_inhabitants_ExtraInhabitantResilientTypes.swift
|
|
|
|
// -- run tests
|
|
// RUN: %target-build-swift -parse-stdlib -Xfrontend -verify-type-layout -Xfrontend PairWithPointerFirst -Xfrontend -verify-type-layout -Xfrontend PairWithPointerSecond -Xfrontend -verify-type-layout -Xfrontend PairWithPointerSecondAndPhantomParam_Int -Xfrontend -verify-type-layout -Xfrontend GenericPairWithPointerFirst_Int -Xfrontend -verify-type-layout -Xfrontend GenericPairWithPointerFirst_AnyObject -Xfrontend -verify-type-layout -Xfrontend GenericPairWithPointerSecond_Int -Xfrontend -verify-type-layout -Xfrontend GenericPairWithPointerSecond_AnyObject -Xfrontend -verify-type-layout -Xfrontend StringAlike32 -Xfrontend -verify-type-layout -Xfrontend StringAlike64 -I %t -o %t/a.out.tests %s %t/ExtraInhabitantResilientTypes.o
|
|
// RUN: %target-codesign %t/a.out.tests
|
|
// RUN: %target-run %t/a.out.tests 2>&1
|
|
|
|
// Type layout verifier is only compiled into the runtime in asserts builds.
|
|
// REQUIRES: swift_stdlib_asserts
|
|
|
|
// REQUIRES: executable_test
|
|
// UNSUPPORTED: use_os_stdlib
|
|
// UNSUPPORTED: back_deployment_runtime
|
|
|
|
// CHECK-NOT: Type verification
|
|
|
|
import Swift
|
|
import ExtraInhabitantResilientTypes
|
|
import StdlibUnittest
|
|
|
|
// Enum layout should use extra inhabitants from any struct field
|
|
// for fixed-layout types.
|
|
struct PairWithPointerFirst {
|
|
var a: AnyObject
|
|
var b: Int
|
|
}
|
|
|
|
struct PairWithPointerSecond {
|
|
var a: Int
|
|
var b: AnyObject
|
|
}
|
|
|
|
struct PairWithPointerSecondAndPhantomParam<X> {
|
|
var a: Int
|
|
var b: AnyObject
|
|
}
|
|
|
|
struct StringAlike64 {
|
|
var a: Int
|
|
var b: Builtin.BridgeObject
|
|
}
|
|
struct StringAlike32 {
|
|
var a,b,c: Int
|
|
var d: Builtin.BridgeObject
|
|
}
|
|
|
|
// TODO: Runtime struct instantiation still only considers the first argument
|
|
|
|
struct GenericPair<T, U> {
|
|
var a: T
|
|
var b: U
|
|
}
|
|
|
|
struct GenericSamePair<T> {
|
|
var a: T
|
|
var b: T
|
|
}
|
|
|
|
struct GenericPairPlusPointer<T, U> {
|
|
var a: T
|
|
var b: U
|
|
var c: UnsafeRawPointer
|
|
}
|
|
|
|
struct GenericSamePairPlusPointer<T> {
|
|
var a: T
|
|
var b: T
|
|
var c: UnsafeRawPointer
|
|
}
|
|
|
|
struct GenericPairWithPointerFirst<T> {
|
|
var a: AnyObject
|
|
var b: T
|
|
}
|
|
|
|
struct GenericPairWithPointerSecond<T> {
|
|
var a: T
|
|
var b: AnyObject
|
|
}
|
|
|
|
struct GenericFullHouse<T, U> {
|
|
var a, b, c: T
|
|
var d, e: U
|
|
}
|
|
|
|
struct ResilientPairWithXIFirst {
|
|
var a: ResilientXI
|
|
var b: ResilientNoXI
|
|
}
|
|
|
|
struct ResilientPairWithXISecond {
|
|
var a: ResilientNoXI
|
|
var b: ResilientXI
|
|
}
|
|
|
|
// Typealiases for the type layout verifier
|
|
|
|
typealias PairWithPointerSecondAndPhantomParam_Int
|
|
= PairWithPointerSecondAndPhantomParam<Int>
|
|
|
|
typealias GenericPairWithPointerFirst_Int
|
|
= GenericPairWithPointerFirst<Int>
|
|
|
|
typealias GenericPairWithPointerFirst_AnyObject
|
|
= GenericPairWithPointerFirst<AnyObject>
|
|
|
|
typealias GenericPairWithPointerSecond_Int
|
|
= GenericPairWithPointerSecond<Int>
|
|
|
|
typealias GenericPairWithPointerSecond_AnyObject
|
|
= GenericPairWithPointerSecond<AnyObject>
|
|
|
|
var tests = TestSuite("extra inhabitants of structs")
|
|
|
|
@inline(never)
|
|
func expectHasAtLeastThreeExtraInhabitants<T>(_: T.Type,
|
|
nil theNil: T???,
|
|
someNil: T???,
|
|
someSomeNil: T???,
|
|
file: String = #file, line: UInt = #line) {
|
|
expectEqual(MemoryLayout<T>.size, MemoryLayout<T???>.size,
|
|
"\(T.self) has at least three extra inhabitants",
|
|
file: file, line: line)
|
|
|
|
expectNil(theNil,
|
|
"\(T.self) extra inhabitant should agree in generic and concrete " +
|
|
"context")
|
|
|
|
expectNil(someNil!,
|
|
"\(T.self) extra inhabitant should agree in generic and concrete " +
|
|
"context")
|
|
|
|
expectNil(someSomeNil!!,
|
|
"\(T.self) extra inhabitant should agree in generic and concrete " +
|
|
"context")
|
|
}
|
|
|
|
@inline(never)
|
|
func expectHasExtraInhabitant<T>(_: T.Type, nil theNil: T?,
|
|
file: String = #file, line: UInt = #line) {
|
|
expectEqual(MemoryLayout<T>.size, MemoryLayout<T?>.size,
|
|
"\(T.self) has extra inhabitant",
|
|
file: file, line: line)
|
|
|
|
expectNil(theNil,
|
|
"\(T.self) extra inhabitant should agree in generic and concrete " +
|
|
"context")
|
|
}
|
|
|
|
func expectHasNoExtraInhabitant<T>(_: T.Type,
|
|
file: String = #file, line: UInt = #line) {
|
|
expectNotEqual(MemoryLayout<T>.size, MemoryLayout<T?>.size,
|
|
"\(T.self) does not have extra inhabitant",
|
|
file: file, line: line)
|
|
}
|
|
|
|
tests.test("types that have extra inhabitants") {
|
|
expectHasExtraInhabitant(PairWithPointerFirst.self, nil: nil)
|
|
expectHasExtraInhabitant(PairWithPointerSecond.self, nil: nil)
|
|
expectHasExtraInhabitant(PairWithPointerSecondAndPhantomParam<Int>.self, nil: nil)
|
|
expectHasExtraInhabitant(PairWithPointerSecondAndPhantomParam<AnyObject>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericPairWithPointerFirst<Int>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericPairWithPointerFirst<AnyObject>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericPairWithPointerSecond<Int>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericPairWithPointerSecond<AnyObject>.self, nil: nil)
|
|
expectHasExtraInhabitant(ResilientPairWithXIFirst.self, nil: nil)
|
|
expectHasExtraInhabitant(ResilientPairWithXISecond.self, nil: nil)
|
|
expectHasExtraInhabitant(StringAlike64.self, nil: nil)
|
|
expectHasExtraInhabitant(StringAlike32.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericPair<AnyObject, Int>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericPair<Int, AnyObject>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericPair<AnyObject, AnyObject>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericPair<AnyObject, UnsafeRawPointer>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericPair<UnsafeRawPointer, AnyObject>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericPair<UnsafeRawPointer, UnsafeRawPointer>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericPairPlusPointer<Int, Int>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericPairPlusPointer<AnyObject, Int>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericPairPlusPointer<Int, AnyObject>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericPairPlusPointer<AnyObject, AnyObject>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericSamePair<UnsafeRawPointer>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericSamePair<AnyObject>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericSamePairPlusPointer<UnsafeRawPointer>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericSamePairPlusPointer<AnyObject>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericSamePairPlusPointer<Int>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericFullHouse<AnyObject, Int>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericFullHouse<Int, AnyObject>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericFullHouse<AnyObject, AnyObject>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericFullHouse<AnyObject, UnsafeRawPointer>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericFullHouse<UnsafeRawPointer, AnyObject>.self, nil: nil)
|
|
expectHasExtraInhabitant(GenericFullHouse<UnsafeRawPointer, UnsafeRawPointer>.self, nil: nil)
|
|
}
|
|
|
|
tests.test("types that have more than one extra inhabitant") {
|
|
expectHasAtLeastThreeExtraInhabitants(StringAlike64.self, nil: nil, someNil: .some(nil), someSomeNil: .some(.some(nil)))
|
|
expectHasAtLeastThreeExtraInhabitants(StringAlike32.self, nil: nil, someNil: .some(nil), someSomeNil: .some(.some(nil)))
|
|
}
|
|
|
|
runAllTests()
|
|
|