Merge pull request #84187 from drexin/wip-159310652

[IRGen] Only emit AssociatedTypeInProtocolContextByte for default ass…
This commit is contained in:
Dario Rexin
2025-09-26 19:21:56 -07:00
committed by GitHub
3 changed files with 86 additions and 7 deletions

View File

@@ -315,9 +315,8 @@ getRuntimeVersionThatSupportsDemanglingType(CanType type) {
// where completing the metadata during demangling might cause cyclic
// dependencies.
static std::pair<llvm::Constant *, unsigned>
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;

View File

@@ -0,0 +1,21 @@
public protocol Proto {
associatedtype T: Proto
var value: T {get}
}
public func makeThing<P: Proto>(_ t: P) -> some Proto {
return ProtoImpl(t.value)
}
public struct ProtoImpl<V>: Proto {
public let genValue: V
public init(_ genValue: V) {
self.genValue = genValue
}
public var value: some Proto {
return self
}
}

View File

@@ -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<T: P>: Proto {
typealias Closure = nonisolated(nonsending) (Int) async throws -> Void
let x: T
public var value: some Proto {
return ProtoImpl<Closure> { _ in }
}
}
print(makeThing(MyStruct(x: PImpl())))