mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
When constructing the metadata for a type Gen<T : Super>
where Super is a superclass constraint, the generic argument K at which
the metadata for Gen is being instantiated is verified to be a subclass
of Super via _checkGenericRequirements.
Previously, that check was done using swift_dynamicCastMetatype. That
worked for the most part but provided an incorrect answer if the
metadata for K was not yet complete. These classes are incomplete more
often thanks to __swift_instantiateConcreteTypeFromMangledNameAbstract.
That issue occurred concretely in the following case:
Framework with Library Evolution enabled:
open class Super { ... }
public struct Gen<T : Super> {
}
Target in a different resilience domain from that framework:
class Sub : Super {
var gen: Gen<Sub>?
}
Here, the mechanism for checking whether the generic argument K at which
the metadata for Gen is being instantiated handles the case where K's
metadata is incomplete. At worst, every superclass name from super(K)
up to Super are demangled to instantiate metadata. A number of faster
paths are included as well.
rdar://problem/60790020
42 lines
1.3 KiB
Swift
42 lines
1.3 KiB
Swift
// RUN: %empty-directory(%t)
|
|
// RUN: %target-build-swift -emit-library -enable-library-evolution -module-name Framework -module-link-name Framework %S/Inputs/public_struct_with_generic_arg_nsobject_constrained.swift -o %t/%target-library-name(Framework) -emit-module-path %t/Framework.swiftmodule -target %module-target-future
|
|
// RUN: %target-codesign %t/libFramework.dylib
|
|
|
|
// RUN: %target-build-swift %s %S/Inputs/print_subclass/main.swift -module-name main -o %t/main -I %t -L %t -target %module-target-future
|
|
// RUN: %target-codesign %t/main
|
|
// RUN: %target-run %t/main | %FileCheck %S/Inputs/print_subclass/main.swift
|
|
|
|
// REQUIRES: executable_test
|
|
|
|
// REQUIRES: OS=macosx
|
|
// Testing runtime changes that aren't in the os stdlib.
|
|
// UNSUPPORTED: use_os_stdlib
|
|
|
|
import Swift
|
|
import Foundation
|
|
import Framework
|
|
|
|
// Swift subclass of a ObjC class
|
|
|
|
// subclass isSwiftClassMetadataSubclass metadata completeness : LayoutComplete
|
|
// superclass metadata path: getSuperclassMetadata
|
|
// getSuperclassMetadata result 1: (Complete, NSObject, !ClassMetadata)
|
|
// handleObjc => swift_dynamicCastMetatype
|
|
|
|
typealias Gen = Framework.Gen<Subclass>
|
|
|
|
public class Subclass : NSObject {
|
|
override init() {
|
|
self.gen = Gen()
|
|
super.init()
|
|
}
|
|
|
|
var gen: Gen?
|
|
}
|
|
|
|
@inline(never)
|
|
public func consume<T>(_ t: T) {
|
|
withExtendedLifetime(t) { t in
|
|
}
|
|
}
|