blob: ff0df6e0e096fd3f6af246554ffbdabdb61e0527 [file] [log] [blame]
// RUN: %empty-directory(%t)
// -- build resilient library
// RUN: %target-build-swift -force-single-frontend-invocation -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-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
// 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()