mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Runtime] Handle incomplete class metadata in _checkGenericRequirements.
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
This commit is contained in:
@@ -796,6 +796,10 @@ SWIFT_CC(swift)
|
||||
SWIFT_RUNTIME_STDLIB_INTERNAL
|
||||
const Metadata *_swift_class_getSuperclass(const Metadata *theClass);
|
||||
|
||||
SWIFT_CC(swift)
|
||||
SWIFT_RUNTIME_STDLIB_INTERNAL MetadataResponse
|
||||
getSuperclassMetadata(MetadataRequest request, const ClassMetadata *self);
|
||||
|
||||
#if !NDEBUG
|
||||
/// Verify that the given metadata pointer correctly roundtrips its
|
||||
/// mangled name through the demangler.
|
||||
|
||||
@@ -2735,19 +2735,14 @@ initGenericObjCClass(ClassMetadata *self, size_t numFields,
|
||||
#endif
|
||||
|
||||
SWIFT_CC(swift)
|
||||
static std::pair<MetadataDependency, const ClassMetadata *>
|
||||
getSuperclassMetadata(ClassMetadata *self, bool allowDependency) {
|
||||
SWIFT_RUNTIME_STDLIB_INTERNAL MetadataResponse
|
||||
getSuperclassMetadata(MetadataRequest request, const ClassMetadata *self) {
|
||||
// If there is a mangled superclass name, demangle it to the superclass
|
||||
// type.
|
||||
const ClassMetadata *super = nullptr;
|
||||
if (auto superclassNameBase = self->getDescription()->SuperclassType.get()) {
|
||||
StringRef superclassName =
|
||||
Demangle::makeSymbolicMangledNameStringRef(superclassNameBase);
|
||||
SubstGenericParametersFromMetadata substitutions(self);
|
||||
MetadataRequest request(allowDependency
|
||||
? MetadataState::NonTransitiveComplete
|
||||
: /*FIXME*/ MetadataState::Abstract,
|
||||
/*non-blocking*/ allowDependency);
|
||||
MetadataResponse response =
|
||||
swift_getTypeByMangledName(request, superclassName,
|
||||
substitutions.getGenericArgs(),
|
||||
@@ -2765,22 +2760,42 @@ getSuperclassMetadata(ClassMetadata *self, bool allowDependency) {
|
||||
superclassName.str().c_str());
|
||||
}
|
||||
|
||||
return response;
|
||||
} else {
|
||||
return MetadataResponse();
|
||||
}
|
||||
}
|
||||
|
||||
SWIFT_CC(swift)
|
||||
static std::pair<MetadataDependency, const ClassMetadata *>
|
||||
getSuperclassMetadata(ClassMetadata *self, bool allowDependency) {
|
||||
MetadataRequest request(allowDependency ? MetadataState::NonTransitiveComplete
|
||||
: /*FIXME*/ MetadataState::Abstract,
|
||||
/*non-blocking*/ allowDependency);
|
||||
auto response = getSuperclassMetadata(request, self);
|
||||
|
||||
auto *superclass = response.Value;
|
||||
if (!superclass)
|
||||
return {MetadataDependency(), nullptr};
|
||||
|
||||
const ClassMetadata *second;
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
if (auto objcWrapper = dyn_cast<ObjCClassWrapperMetadata>(superclass)) {
|
||||
second = objcWrapper->Class;
|
||||
} else {
|
||||
second = cast<ClassMetadata>(superclass);
|
||||
}
|
||||
#else
|
||||
second = cast<ClassMetadata>(superclass);
|
||||
#endif
|
||||
|
||||
// If the request isn't satisfied, we have a new dependency.
|
||||
if (!request.isSatisfiedBy(response.State)) {
|
||||
assert(allowDependency);
|
||||
return {MetadataDependency(superclass, request.getState()),
|
||||
cast<ClassMetadata>(superclass)};
|
||||
return {MetadataDependency(superclass, request.getState()), second};
|
||||
}
|
||||
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
if (auto objcWrapper = dyn_cast<ObjCClassWrapperMetadata>(superclass))
|
||||
superclass = objcWrapper->Class;
|
||||
#endif
|
||||
|
||||
super = cast<ClassMetadata>(superclass);
|
||||
}
|
||||
|
||||
return {MetadataDependency(), super};
|
||||
return {MetadataDependency(), second};
|
||||
}
|
||||
|
||||
// Suppress diagnostic about the availability of _objc_realizeClassFromSwift.
|
||||
|
||||
@@ -665,6 +665,137 @@ swift::_searchConformancesByMangledTypeName(Demangle::NodePointer node) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static MetadataState
|
||||
tryGetCompleteMetadataNonblocking(const Metadata *metadata) {
|
||||
return swift_checkMetadataState(
|
||||
MetadataRequest(MetadataState::Complete, /*isNonBlocking*/ true),
|
||||
metadata)
|
||||
.State;
|
||||
}
|
||||
|
||||
template <typename HandleObjc>
|
||||
bool isSwiftClassMetadataSubclass(const ClassMetadata *subclass,
|
||||
const ClassMetadata *superclass,
|
||||
HandleObjc handleObjc) {
|
||||
assert(subclass);
|
||||
assert(superclass);
|
||||
|
||||
MetadataState subclassState = tryGetCompleteMetadataNonblocking(subclass);
|
||||
|
||||
do {
|
||||
if (subclassState == MetadataState::Complete) {
|
||||
// The subclass metadata is complete. That means not just that its
|
||||
// Superclass field is valid, but that the Superclass field of the
|
||||
// referenced class metadata is valid, and the Superclass field of the
|
||||
// class metadata referenced there, and so on transitively.
|
||||
//
|
||||
// Scan the superclass chains in the ClassMetadata looking for a match.
|
||||
while ((subclass = subclass->Superclass)) {
|
||||
if (subclass == superclass)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (subclassState == MetadataState::NonTransitiveComplete) {
|
||||
// The subclass metadata is complete, but, unlike above, not transitively.
|
||||
// Its Superclass field is valid, so just read that field to get to the
|
||||
// superclass to proceed to the next step.
|
||||
subclass = subclass->Superclass;
|
||||
if (subclass->isPureObjC()) {
|
||||
return handleObjc(subclass, superclass);
|
||||
}
|
||||
subclassState = tryGetCompleteMetadataNonblocking(subclass);
|
||||
} else {
|
||||
// The subclass metadata is either LayoutComplete or Abstract, so the
|
||||
// Superclass field is not valid. To get to the superclass, make the
|
||||
// expensive call to getSuperclassMetadata which demangles the superclass
|
||||
// name from the nominal type descriptor to get the metadata for the
|
||||
// superclass.
|
||||
MetadataRequest request(MetadataState::Complete,
|
||||
/*non-blocking*/ true);
|
||||
auto response = getSuperclassMetadata(request, subclass);
|
||||
auto newMetadata = response.Value;
|
||||
if (auto newSubclass = dyn_cast<ClassMetadata>(newMetadata)) {
|
||||
subclass = newSubclass;
|
||||
subclassState = response.State;
|
||||
} else {
|
||||
return handleObjc(newMetadata, superclass);
|
||||
}
|
||||
}
|
||||
if (subclass == superclass)
|
||||
return true;
|
||||
} while (subclass);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Whether the provided `subclass` is metadata for a subclass* of the superclass
|
||||
// whose metadata is specified.
|
||||
//
|
||||
// The function is robust against incomplete metadata for both subclass and
|
||||
// superclass. In the worst case, each intervening class between subclass and
|
||||
// superclass is demangled. Besides that slow path, there are a number of fast
|
||||
// paths:
|
||||
// - both classes are ObjC: swift_dynamicCastMetatype
|
||||
// - Complete subclass metadata: loop over Superclass fields
|
||||
// - NonTransitiveComplete: read the Superclass field once
|
||||
//
|
||||
// * A non-strict subclass; that is, given a class X, isSubclass(X.self, X.self)
|
||||
// is true.
|
||||
static bool isSubclass(const Metadata *subclass, const Metadata *superclass) {
|
||||
assert(subclass);
|
||||
assert(superclass);
|
||||
assert(subclass->isAnyClass());
|
||||
assert(superclass->isAnyClass());
|
||||
|
||||
if (subclass == superclass)
|
||||
return true;
|
||||
if (!isa<ClassMetadata>(subclass)) {
|
||||
if (!isa<ClassMetadata>(superclass)) {
|
||||
// Only ClassMetadata can be incomplete; when the class metadata is not
|
||||
// ClassMetadata, just use swift_dynamicCastMetatype.
|
||||
return swift_dynamicCastMetatype(subclass, superclass);
|
||||
} else {
|
||||
// subclass is ObjC, but superclass is not; since it is not possible for
|
||||
// any ObjC class to be a subclass of any Swift class, this subclass is
|
||||
// not a subclass of this superclass.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
const ClassMetadata *swiftSubclass = cast<ClassMetadata>(subclass);
|
||||
if (auto *objcSuperclass = dyn_cast<ObjCClassWrapperMetadata>(superclass)) {
|
||||
// Walk up swiftSubclass's ancestors until we get to an ObjC class, then
|
||||
// kick over to swift_dynamicCastMetatype.
|
||||
return isSwiftClassMetadataSubclass(
|
||||
swiftSubclass, objcSuperclass->Class,
|
||||
[](const Metadata *intermediate, const Metadata *superclass) {
|
||||
// Intermediate is an ObjC class, and superclass is an ObjC class;
|
||||
// as above, just use swift_dynamicCastMetatype.
|
||||
return swift_dynamicCastMetatype(intermediate, superclass);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (isa<ForeignClassMetadata>(superclass)) {
|
||||
// superclass is foreign, but subclass is not (if it were, the above
|
||||
// !isa<ClassMetadata> condition would have been entered). Since it is not
|
||||
// possible for any Swift class to be a subclass of any foreign superclass,
|
||||
// this subclass is not a subclass of this superclass.
|
||||
return false;
|
||||
}
|
||||
auto swiftSuperclass = cast<ClassMetadata>(superclass);
|
||||
return isSwiftClassMetadataSubclass(swiftSubclass, swiftSuperclass,
|
||||
[](const Metadata *, const Metadata *) {
|
||||
// Because (1) no ObjC classes inherit
|
||||
// from Swift classes and (2)
|
||||
// `superclass` is not ObjC, if some
|
||||
// ancestor of `subclass` is ObjC, then
|
||||
// `subclass` cannot descend from
|
||||
// `superclass` (otherwise at some point
|
||||
// some ObjC class would have to inherit
|
||||
// from a Swift class).
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
bool swift::_checkGenericRequirements(
|
||||
llvm::ArrayRef<GenericRequirementDescriptor> requirements,
|
||||
SmallVectorImpl<const void *> &extraArguments,
|
||||
@@ -738,11 +869,8 @@ bool swift::_checkGenericRequirements(
|
||||
substGenericParam, substWitnessTable).getMetadata();
|
||||
if (!baseType) return true;
|
||||
|
||||
// Check whether it's dynamically castable, which works as a superclass
|
||||
// check.
|
||||
// FIXME: We should be explicitly checking the superclass, so we
|
||||
// don't require the subject type to be complete.
|
||||
if (!swift_dynamicCastMetatype(subjectType, baseType)) return true;
|
||||
if (!isSubclass(subjectType, baseType))
|
||||
return true;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
5
test/Runtime/Inputs/SubclassOfNSObject.h
Normal file
5
test/Runtime/Inputs/SubclassOfNSObject.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface Subclass : NSObject
|
||||
|
||||
@end
|
||||
8
test/Runtime/Inputs/SubclassOfNSObject.m
Normal file
8
test/Runtime/Inputs/SubclassOfNSObject.m
Normal file
@@ -0,0 +1,8 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface Subclass : NSObject
|
||||
|
||||
@end
|
||||
|
||||
@implementation Subclass
|
||||
@end
|
||||
4
test/Runtime/Inputs/Superclass.h
Normal file
4
test/Runtime/Inputs/Superclass.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface Superclass : NSObject
|
||||
@end
|
||||
7
test/Runtime/Inputs/Superclass.m
Normal file
7
test/Runtime/Inputs/Superclass.m
Normal file
@@ -0,0 +1,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface Superclass : NSObject
|
||||
@end
|
||||
|
||||
@implementation Superclass
|
||||
@end
|
||||
@@ -0,0 +1,4 @@
|
||||
import Framework
|
||||
|
||||
open class Subclass1 : Superclass {
|
||||
}
|
||||
3
test/Runtime/Inputs/print_subclass/main.swift
Normal file
3
test/Runtime/Inputs/print_subclass/main.swift
Normal file
@@ -0,0 +1,3 @@
|
||||
// CHECK: Subclass
|
||||
print(Subclass().self)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import Foundation
|
||||
|
||||
public struct Gen<Subclass : NSObject> {
|
||||
public init() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
open class Superclass {
|
||||
public init() {
|
||||
}
|
||||
}
|
||||
|
||||
public struct Gen<Subclass : Superclass> {
|
||||
public init() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// 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
|
||||
// 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
|
||||
// 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 Swift class
|
||||
|
||||
// subclass isSwiftClassMetadataSubclass metadata completeness : Complete
|
||||
// superclass metadata path: loop
|
||||
// iteration 1: subclass->Superclass == NSObject
|
||||
// subclass <= NSObject
|
||||
// superclass == NSObject; done
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// 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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// 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
|
||||
// RUN: %target-codesign %t/libFramework.dylib
|
||||
|
||||
// RUN: %target-clang -fobjc-arc %S/Inputs/Superclass.m -c -o %t/Superclass.o
|
||||
// RUN: %target-build-swift %s %t/Superclass.o %S/Inputs/print_subclass/main.swift -import-objc-header %S/Inputs/Superclass.h -module-name main -o %t/main -I %t -L %t
|
||||
// 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 an ObjC subclass of an ObjC class
|
||||
|
||||
// subclass isSwiftClassMetadataSubclass metadata completeness : Complete
|
||||
// superclass metadata path: loop
|
||||
// iteration 1: subclass->Superclass == NSObject
|
||||
// subclass <= NSObject
|
||||
// superclass == NSObject; done
|
||||
|
||||
typealias Gen = Framework.Gen<Subclass>
|
||||
|
||||
public class Subclass : Superclass {
|
||||
override init() {
|
||||
self.gen = Gen()
|
||||
super.init()
|
||||
}
|
||||
|
||||
var gen: Gen?
|
||||
}
|
||||
|
||||
@inline(never)
|
||||
public func consume<T>(_ t: T) {
|
||||
withExtendedLifetime(t) { t in
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// 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-clang -fobjc-arc %S/Inputs/Superclass.m -c -o %t/Superclass.o
|
||||
// RUN: %target-build-swift %s %t/Superclass.o %S/Inputs/print_subclass/main.swift -import-objc-header %S/Inputs/Superclass.h -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 an ObjC subclass of an ObjC class
|
||||
|
||||
// subclass isSwiftClassMetadataSubclass metadata completeness : Complete
|
||||
// superclass metadata path: getSuperclassMetadata
|
||||
// getSuperclassMetadata result 1: (Complete, NSObject, !ClassMetadata)
|
||||
// handleObjc => swift_dynamicCastMetatype
|
||||
|
||||
typealias Gen = Framework.Gen<Subclass>
|
||||
|
||||
public class Subclass : Superclass {
|
||||
override init() {
|
||||
self.gen = Gen()
|
||||
super.init()
|
||||
}
|
||||
|
||||
var gen: Gen?
|
||||
}
|
||||
|
||||
@inline(never)
|
||||
public func consume<T>(_ t: T) {
|
||||
withExtendedLifetime(t) { t in
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// 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
|
||||
// RUN: %target-codesign %t/libFramework.dylib
|
||||
|
||||
// RUN: %target-clang -fobjc-arc %S/Inputs/SubclassOfNSObject.m -c -o %t/Superclass.o
|
||||
// RUN: %target-build-swift %s %t/Superclass.o %S/Inputs/print_subclass/main.swift -import-objc-header %S/Inputs/SubclassOfNSObject.h -module-name main -o %t/main -I %t -L %t
|
||||
// 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
|
||||
|
||||
// ObjC subclass of an ObjC subclass
|
||||
|
||||
// isSubclass is never called: no reference to subclass metadata from subclass
|
||||
// metadata; i.e. Subclass has no member of type Gen<Subclass>?
|
||||
|
||||
@inline(never)
|
||||
public func consume<T>(_ t: T) {
|
||||
withExtendedLifetime(t) { t in
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// 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_swift_class_constrained.swift -o %t/%target-library-name(Framework) -emit-module-path %t/Framework.swiftmodule
|
||||
// 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
|
||||
// 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 Framework
|
||||
|
||||
// Swift subclass of a Swift class
|
||||
|
||||
// subclass isSwiftClassMetadataSubclass metadata completeness : Complete
|
||||
// superclass metadata path: loop
|
||||
// iteration 1: subclass->Superclass == Superclass
|
||||
// subclass <= Superclass
|
||||
// superclass == Superclass; done
|
||||
|
||||
typealias Gen = Framework.Gen<Subclass>
|
||||
|
||||
public class Subclass : Superclass {
|
||||
override init() {
|
||||
self.gen = Gen()
|
||||
super.init()
|
||||
}
|
||||
|
||||
var gen: Gen?
|
||||
}
|
||||
|
||||
@inline(never)
|
||||
public func consume<T>(_ t: T) {
|
||||
withExtendedLifetime(t) { t in
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// 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_swift_class_constrained.swift -o %t/%target-library-name(Framework) -emit-module-path %t/Framework.swiftmodule
|
||||
// RUN: %target-codesign %t/libFramework.dylib
|
||||
// RUN: %target-build-swift -emit-library -enable-library-evolution -module-name Framework2 -module-link-name Framework2 %S/Inputs/open_subclass_of_Framework.Superclass.swift -o %t/%target-library-name(Framework2) -emit-module-path %t/Framework2.swiftmodule -I %t -L %t
|
||||
// RUN: %target-codesign %t/libFramework2.dylib
|
||||
|
||||
// RUN: %target-build-swift %s %S/Inputs/print_subclass/main.swift -module-name main -o %t/main -I %t -L %t
|
||||
// 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 Framework
|
||||
import Framework2
|
||||
|
||||
// Swift subclass of a Swift subclass of a Swift class
|
||||
|
||||
// subclass isSwiftClassMetadataSubclass metadata completeness : Complete
|
||||
// superclass metadata path: loop
|
||||
// iteration 1: subclass->Superclass == Subclass1
|
||||
// subclass <= Subclass1
|
||||
// iteration 2: subclass->Superclass == Superclass
|
||||
// subclass <= Superclass
|
||||
// superclass == Superclass; done
|
||||
|
||||
typealias Gen = Framework.Gen<Subclass>
|
||||
|
||||
public class Subclass : Subclass1 {
|
||||
override init() {
|
||||
self.gen = Gen()
|
||||
super.init()
|
||||
}
|
||||
|
||||
var gen: Gen?
|
||||
}
|
||||
|
||||
@inline(never)
|
||||
public func consume<T>(_ t: T) {
|
||||
withExtendedLifetime(t) { t in
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
// 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_swift_class_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 -emit-library -enable-library-evolution -module-name Framework2 -module-link-name Framework2 %S/Inputs/open_subclass_of_Framework.Superclass.swift -o %t/%target-library-name(Framework2) -emit-module-path %t/Framework2.swiftmodule -target %module-target-future -I %t -L %t
|
||||
// RUN: %target-codesign %t/libFramework2.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 Framework
|
||||
import Framework2
|
||||
|
||||
// Swift subclass of a Swift class
|
||||
|
||||
// subclass isSwiftClassMetadataSubclass metadata completeness : LayoutComplete
|
||||
// superclass metadata path: getSuperclassMetadata
|
||||
// getSuperclassMetadata result 1: (Complete, Subclass1)
|
||||
// superclass metadata path: loop
|
||||
// iteration 1: subclass->Superclass == Superclass
|
||||
// subclass <= Superclass
|
||||
// superclass == Superclass; done
|
||||
|
||||
typealias Gen = Framework.Gen<Subclass>
|
||||
|
||||
public class Subclass : Subclass1 {
|
||||
override init() {
|
||||
self.gen = Gen()
|
||||
super.init()
|
||||
}
|
||||
|
||||
var gen: Gen?
|
||||
}
|
||||
|
||||
@inline(never)
|
||||
public func consume<T>(_ t: T) {
|
||||
withExtendedLifetime(t) { t in
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// 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_swift_class_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 Framework
|
||||
|
||||
// Swift subclass of a Swift class
|
||||
|
||||
// subclass isSwiftClassMetadataSubclass metadata completeness : LayoutComplete
|
||||
// superclass metadata path: getSuperclassMetadata
|
||||
// getSuperclassMetadata result 1: (Complete, Superclass)
|
||||
// subclass == superclass; done
|
||||
|
||||
typealias Gen = Framework.Gen<Subclass>
|
||||
|
||||
public class Subclass : Superclass {
|
||||
override init() {
|
||||
self.gen = Gen()
|
||||
super.init()
|
||||
}
|
||||
|
||||
var gen: Gen?
|
||||
}
|
||||
|
||||
@inline(never)
|
||||
public func consume<T>(_ t: T) {
|
||||
withExtendedLifetime(t) { t in
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user