diff --git a/lib/IRGen/GenReflection.cpp b/lib/IRGen/GenReflection.cpp index 51ad0a295abc8..0ed853fc1d6d2 100644 --- a/lib/IRGen/GenReflection.cpp +++ b/lib/IRGen/GenReflection.cpp @@ -315,9 +315,8 @@ getRuntimeVersionThatSupportsDemanglingType(CanType type) { // where completing the metadata during demangling might cause cyclic // dependencies. static std::pair -getTypeRefByFunction(IRGenModule &IGM, - CanGenericSignature sig, - CanType t) { +getTypeRefByFunction(IRGenModule &IGM, CanGenericSignature sig, CanType t, + MangledTypeRefRole role) { IRGenMangler mangler(IGM.Context); std::string symbolName = mangler.mangleSymbolNameForMangledMetadataAccessorString( @@ -433,7 +432,11 @@ getTypeRefByFunction(IRGenModule &IGM, // Form the mangled name with its relative reference. auto S = B.beginStruct(); S.setPacked(true); - S.add(llvm::ConstantInt::get(IGM.Int8Ty, 255)); + if (role == MangledTypeRefRole::DefaultAssociatedTypeWitness) { + S.add(llvm::ConstantInt::get( + IGM.Int8Ty, + ProtocolRequirementFlags::AssociatedTypeInProtocolContextByte)); + } S.add(llvm::ConstantInt::get(IGM.Int8Ty, 9)); S.addCompactFunctionReference(accessor); @@ -513,7 +516,7 @@ getTypeRefImpl(IRGenModule &IGM, // the field will be artificially hidden to reflectors. if (isAlwaysNoncopyable) { IGM.IRGen.noteUseOfTypeMetadata(type); - return getTypeRefByFunction(IGM, sig, type); + return getTypeRefByFunction(IGM, sig, type, role); } } LLVM_FALLTHROUGH; @@ -524,12 +527,12 @@ getTypeRefImpl(IRGenModule &IGM, // ensuring that we can always reconstruct type metadata from a mangled name // in-process. IGM.IRGen.noteUseOfTypeMetadata(type); - + // If the minimum deployment target's runtime demangler wouldn't understand // this mangled name, then fall back to generating a "mangled name" with a // symbolic reference with a callback function. if (mangledNameIsUnknownToDeployTarget(IGM, type)) { - return getTypeRefByFunction(IGM, sig, type); + return getTypeRefByFunction(IGM, sig, type, role); } break; diff --git a/test/IRGen/Inputs/associated_type_by_mangled_name.swift b/test/IRGen/Inputs/associated_type_by_mangled_name.swift new file mode 100644 index 0000000000000..3e8ee23c00200 --- /dev/null +++ b/test/IRGen/Inputs/associated_type_by_mangled_name.swift @@ -0,0 +1,21 @@ +public protocol Proto { + associatedtype T: Proto + + var value: T {get} +} + +public func makeThing(_ t: P) -> some Proto { + return ProtoImpl(t.value) +} + +public struct ProtoImpl: Proto { + public let genValue: V + + public init(_ genValue: V) { + self.genValue = genValue + } + + public var value: some Proto { + return self + } +} diff --git a/test/IRGen/nonisolated_nonsending_closure.swift b/test/IRGen/nonisolated_nonsending_closure.swift new file mode 100644 index 0000000000000..32edb5efbb14d --- /dev/null +++ b/test/IRGen/nonisolated_nonsending_closure.swift @@ -0,0 +1,55 @@ +// RUN: %empty-directory(%t) + +// RUN: %target-build-swift-dylib(%t/%target-library-name(associated_type_by_mangled_name)) -target %target-cpu-apple-macosx15.0 -enable-library-evolution %S/Inputs/associated_type_by_mangled_name.swift -emit-module -emit-module-path %t/associated_type_by_mangled_name.swiftmodule -module-name associated_type_by_mangled_name +// RUN: %target-codesign %t/%target-library-name(associated_type_by_mangled_name) + +// RUN: %target-swift-frontend -target %target-cpu-apple-macosx15.0 -I %t %s -emit-ir -o - | %FileCheck %s +// RUN: %target-swift-frontend -target %target-cpu-apple-macosx26.0 -I %t %s -emit-ir -o - | %FileCheck %s -check-prefix CHECK-SUPPORTED + +// RUN: %target-build-swift -target %target-cpu-apple-macosx15.0 %s -lassociated_type_by_mangled_name -I %t -L %t -o %t/main15 %target-rpath(%t) +// RUN: %target-codesign %t/main15 + +// RUN: %target-run %t/main15 %t/%target-library-name(associated_type_by_mangled_name) + +// RUN: %target-build-swift -target %target-cpu-apple-macosx26.0 %s -lassociated_type_by_mangled_name -I %t -L %t -o %t/main26 %target-rpath(%t) +// RUN: %target-codesign %t/main26 + +// RUN: %target-run %t/main26 %t/%target-library-name(associated_type_by_mangled_name) + +// REQUIRES: executable_test +// REQUIRES: OS=macosx +// UNSUPPORTED: back_deployment_runtime || use_os_stdlib + +import associated_type_by_mangled_name + +protocol P: Sendable { + associatedtype T: Proto + func foo() -> T +} + +struct PImpl: P { + func foo() -> some Proto { + return ProtoImpl(2) + } +} + +// CHECK: @"get_type_metadata 30nonisolated_nonsending_closure1PRzl31associated_type_by_mangled_name9ProtoImplVyySiYaKYCcG.3" = linkonce_odr hidden constant <{ i8, i32, i8 }> <{ i8 9, i32 trunc (i64 sub (i64 ptrtoint (ptr @"get_type_metadata 30nonisolated_nonsending_closure1PRzl31associated_type_by_mangled_name9ProtoImplVyySiYaKYCcG" to i64), i64 ptrtoint (ptr getelementptr inbounds (<{ i8, i32, i8 }>, ptr @"get_type_metadata 30nonisolated_nonsending_closure1PRzl31associated_type_by_mangled_name9ProtoImplVyySiYaKYCcG.3", i32 0, i32 1) to i64)) to i32), i8 0 }> +// CHECK: define linkonce_odr hidden ptr @"$s31associated_type_by_mangled_name9ProtoImplVyySiYaKYCcGACyxGAA0F0AAWl"() #1 { +// CHECK: call swiftcc %swift.metadata_response @"$s31associated_type_by_mangled_name9ProtoImplVyySiYaKYCcGMa"(i64 255) +// CHECK: } + +// CHECK-SUPPORTED-NOT: @"get_type_metadata 30nonisolated_nonsending_closure1PRzl31associated_type_by_mangled_name9ProtoImplVyySiYaKYCcG.3" +// CHECK-SUPPORTED: define linkonce_odr hidden ptr @"$s31associated_type_by_mangled_name9ProtoImplVyySiYaKYCcGACyxGAA0F0AAWl"() #1 { +// CHECK-SUPPORTED: call ptr @__swift_instantiateConcreteTypeFromMangledNameAbstract(ptr @"$s31associated_type_by_mangled_name9ProtoImplVyySiYaKYCcGMD") +// CHECK-SUPPORTED: } +struct MyStruct: Proto { + typealias Closure = nonisolated(nonsending) (Int) async throws -> Void + + let x: T + + public var value: some Proto { + return ProtoImpl { _ in } + } +} + +print(makeThing(MyStruct(x: PImpl())))