// 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 { 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 { var a: T var b: U } struct GenericSamePair { var a: T var b: T } struct GenericPairPlusPointer { var a: T var b: U var c: UnsafeRawPointer } struct GenericSamePairPlusPointer { var a: T var b: T var c: UnsafeRawPointer } struct GenericPairWithPointerFirst { var a: AnyObject var b: T } struct GenericPairWithPointerSecond { var a: T var b: AnyObject } struct GenericFullHouse { 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 typealias GenericPairWithPointerFirst_Int = GenericPairWithPointerFirst typealias GenericPairWithPointerFirst_AnyObject = GenericPairWithPointerFirst typealias GenericPairWithPointerSecond_Int = GenericPairWithPointerSecond typealias GenericPairWithPointerSecond_AnyObject = GenericPairWithPointerSecond var tests = TestSuite("extra inhabitants of structs") @inline(never) func expectHasAtLeastThreeExtraInhabitants(_: T.Type, nil theNil: T???, someNil: T???, someSomeNil: T???, file: String = #file, line: UInt = #line) { expectEqual(MemoryLayout.size, MemoryLayout.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.Type, nil theNil: T?, file: String = #file, line: UInt = #line) { expectEqual(MemoryLayout.size, MemoryLayout.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.Type, file: String = #file, line: UInt = #line) { expectNotEqual(MemoryLayout.size, MemoryLayout.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.self, nil: nil) expectHasExtraInhabitant(PairWithPointerSecondAndPhantomParam.self, nil: nil) expectHasExtraInhabitant(GenericPairWithPointerFirst.self, nil: nil) expectHasExtraInhabitant(GenericPairWithPointerFirst.self, nil: nil) expectHasExtraInhabitant(GenericPairWithPointerSecond.self, nil: nil) expectHasExtraInhabitant(GenericPairWithPointerSecond.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.self, nil: nil) expectHasExtraInhabitant(GenericPair.self, nil: nil) expectHasExtraInhabitant(GenericPair.self, nil: nil) expectHasExtraInhabitant(GenericPair.self, nil: nil) expectHasExtraInhabitant(GenericPair.self, nil: nil) expectHasExtraInhabitant(GenericPair.self, nil: nil) expectHasExtraInhabitant(GenericPairPlusPointer.self, nil: nil) expectHasExtraInhabitant(GenericPairPlusPointer.self, nil: nil) expectHasExtraInhabitant(GenericPairPlusPointer.self, nil: nil) expectHasExtraInhabitant(GenericPairPlusPointer.self, nil: nil) expectHasExtraInhabitant(GenericSamePair.self, nil: nil) expectHasExtraInhabitant(GenericSamePair.self, nil: nil) expectHasExtraInhabitant(GenericSamePairPlusPointer.self, nil: nil) expectHasExtraInhabitant(GenericSamePairPlusPointer.self, nil: nil) expectHasExtraInhabitant(GenericSamePairPlusPointer.self, nil: nil) expectHasExtraInhabitant(GenericFullHouse.self, nil: nil) expectHasExtraInhabitant(GenericFullHouse.self, nil: nil) expectHasExtraInhabitant(GenericFullHouse.self, nil: nil) expectHasExtraInhabitant(GenericFullHouse.self, nil: nil) expectHasExtraInhabitant(GenericFullHouse.self, nil: nil) expectHasExtraInhabitant(GenericFullHouse.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()