diff --git a/include/swift/AST/Builtins.def b/include/swift/AST/Builtins.def index 1510688d37e3d..988010672c3d5 100644 --- a/include/swift/AST/Builtins.def +++ b/include/swift/AST/Builtins.def @@ -429,6 +429,35 @@ BUILTIN_SIL_OPERATION(IsUnique, "isUnique", Special) /// BridgeObject to be treated as a native object by the runtime. BUILTIN_SIL_OPERATION(IsUnique_native, "isUnique_native", Special) +/// beginCOWMutation(inout T) -> Int1 +/// +/// Begins a copy-on-write mutation for a buffer reference which is passed as +/// inout argument. It returns a true if the buffer is uniquely referenced. +/// In this case the buffer may be mutated after calling this builtin. +/// +/// The beginCOWMutation builtin is very similar to isUnique. It just translates +/// to a different SIL instruction (begin_cow_mutation), which is the preferred +/// representation of COW in SIL. +BUILTIN_SIL_OPERATION(BeginCOWMutation, "beginCOWMutation", Special) + +/// beginCOWMutation_native(inout T) -> Int1 +/// +/// Like beginCOWMutation, but it's assumed that T has native Swift reference +/// counting. +BUILTIN_SIL_OPERATION(BeginCOWMutation_native, "beginCOWMutation_native", Special) + +/// endCOWMutation(inout T) +/// +/// Ends a copy-on-write mutation for a buffer reference which is passed as +/// inout argument. After calling this builtin, the buffer must not be mutated. +BUILTIN_SIL_OPERATION(EndCOWMutation, "endCOWMutation", Special) + +/// COWBufferForReading has type T -> T +/// +/// Returns the buffer reference which is passed as argument. +/// This builtin indicates to the optimizer that the buffer is not mutable. +BUILTIN_SIL_OPERATION(COWBufferForReading, "COWBufferForReading", Special) + /// bindMemory : (Builtin.RawPointer, Builtin.Word, T.Type) -> () BUILTIN_SIL_OPERATION(BindMemory, "bindMemory", Special) diff --git a/include/swift/Demangling/Demangler.h b/include/swift/Demangling/Demangler.h index 8afd2e929863d..b346a898caf19 100644 --- a/include/swift/Demangling/Demangler.h +++ b/include/swift/Demangling/Demangler.h @@ -564,8 +564,7 @@ class Demangler : public NodeFactory { NodePointer demangleValueWitness(); NodePointer demangleTypeMangling(); - NodePointer demangleSymbolicReference(unsigned char rawKind, - const void *at); + NodePointer demangleSymbolicReference(unsigned char rawKind); bool demangleBoundGenerics(Vector &TypeListList, NodePointer &RetroactiveConformances); diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp index 29a85b226ca3d..c5580e34748b4 100644 --- a/lib/AST/Builtins.cpp +++ b/lib/AST/Builtins.cpp @@ -431,13 +431,26 @@ createGenericParam(ASTContext &ctx, const char *name, unsigned index) { /// Create a generic parameter list with multiple generic parameters. static GenericParamList *getGenericParams(ASTContext &ctx, - unsigned numParameters) { + unsigned numParameters, + bool isAnyObject) { assert(numParameters <= llvm::array_lengthof(GenericParamNames)); SmallVector genericParams; for (unsigned i = 0; i != numParameters; ++i) genericParams.push_back(createGenericParam(ctx, GenericParamNames[i], i)); + + if (isAnyObject) { + CanType ao = ctx.getAnyObjectType(); + SmallVector req; + req.push_back(RequirementRepr::getTypeConstraint(TypeLoc::withoutLoc(genericParams[0]->getInterfaceType()), SourceLoc(), + TypeLoc::withoutLoc(ao))); + + auto paramList = GenericParamList::create(ctx, SourceLoc(), genericParams, + SourceLoc(), req, SourceLoc()); + return paramList; + } + auto paramList = GenericParamList::create(ctx, SourceLoc(), genericParams, SourceLoc()); return paramList; @@ -460,9 +473,10 @@ namespace { SmallVector addedRequirements; public: - BuiltinFunctionBuilder(ASTContext &ctx, unsigned numGenericParams = 1) + BuiltinFunctionBuilder(ASTContext &ctx, unsigned numGenericParams = 1, + bool isAnyObject = false) : Context(ctx) { - TheGenericParamList = getGenericParams(ctx, numGenericParams); + TheGenericParamList = getGenericParams(ctx, numGenericParams, isAnyObject); for (auto gp : TheGenericParamList->getParams()) { genericParamTypes.push_back( gp->getDeclaredInterfaceType()->castTo()); @@ -645,6 +659,14 @@ static ValueDecl *getIsUniqueOperation(ASTContext &Context, Identifier Id) { return builder.build(Id); } +static ValueDecl *getEndCOWMutation(ASTContext &Context, Identifier Id) { + // (@inout T) -> () + BuiltinFunctionBuilder builder(Context); + builder.addParameter(makeGenericParam(), ValueOwnership::InOut); + builder.setResult(makeConcrete(TupleType::getEmpty(Context))); + return builder.build(Id); +} + static ValueDecl *getBindMemoryOperation(ASTContext &Context, Identifier Id) { BuiltinFunctionBuilder builder(Context); builder.addParameter(makeConcrete(Context.TheRawPointerType)); @@ -908,6 +930,16 @@ static ValueDecl *getValueToBridgeObject(ASTContext &C, Identifier Id) { return builder.build(Id); } +static ValueDecl *getCOWBufferForReading(ASTContext &C, Identifier Id) { + // T -> T + // + BuiltinFunctionBuilder builder(C, 1, true); + auto T = makeGenericParam(); + builder.addParameter(T); + builder.setResult(T); + return builder.build(Id); +} + static ValueDecl *getUnsafeGuaranteed(ASTContext &C, Identifier Id) { // T -> (T, Int8Ty) // @@ -2249,9 +2281,16 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) { case BuiltinValueKind::IsUnique: case BuiltinValueKind::IsUnique_native: + case BuiltinValueKind::BeginCOWMutation: + case BuiltinValueKind::BeginCOWMutation_native: if (!Types.empty()) return nullptr; + // BeginCOWMutation has the same signature as IsUnique. return getIsUniqueOperation(Context, Id); + case BuiltinValueKind::EndCOWMutation: + if (!Types.empty()) return nullptr; + return getEndCOWMutation(Context, Id); + case BuiltinValueKind::BindMemory: if (!Types.empty()) return nullptr; return getBindMemoryOperation(Context, Id); @@ -2380,6 +2419,10 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) { if (!Types.empty()) return nullptr; return getValueToBridgeObject(Context, Id); + + case BuiltinValueKind::COWBufferForReading: + return getCOWBufferForReading(Context, Id); + case BuiltinValueKind::UnsafeGuaranteed: return getUnsafeGuaranteed(Context, Id); diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index ffdf8b00618ce..9efee131c4915 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -4993,27 +4993,6 @@ namespace { } result->setSuperclass(superclassType); - // Mark the class as runtime-only if it is named 'OS_object', even - // if it doesn't have the runtime-only Clang attribute. This is a - // targeted fix allowing IRGen to emit convenience initializers - // correctly. - // - // FIXME: Remove this once SILGen gets proper support for factory - // initializers. - if (decl->getName() == "OS_object" || - decl->getName() == "OS_os_log") { - result->setForeignClassKind(ClassDecl::ForeignKind::RuntimeOnly); - } - - // If the superclass is runtime-only, our class is also. This only - // matters in the case above. - if (superclassType) { - auto superclassDecl = cast(superclassType->getAnyNominal()); - auto kind = superclassDecl->getForeignClassKind(); - if (kind != ClassDecl::ForeignKind::Normal) - result->setForeignClassKind(kind); - } - // Import protocols this class conforms to. importObjCProtocols(result, decl->getReferencedProtocols(), inheritedTypes); diff --git a/lib/Demangling/Demangler.cpp b/lib/Demangling/Demangler.cpp index 9caa70dfbf331..e0e665f44dbe2 100644 --- a/lib/Demangling/Demangler.cpp +++ b/lib/Demangling/Demangler.cpp @@ -677,12 +677,14 @@ NodePointer Demangler::demangleTypeMangling() { return TypeMangling; } -NodePointer Demangler::demangleSymbolicReference(unsigned char rawKind, - const void *at) { +NodePointer Demangler::demangleSymbolicReference(unsigned char rawKind) { // The symbolic reference is a 4-byte machine integer encoded in the following // four bytes. + if (Pos + 4 > Text.size()) + return nullptr; + const void *at = Text.data() + Pos; int32_t value; - memcpy(&value, Text.data() + Pos, 4); + memcpy(&value, at, 4); Pos += 4; // Map the encoded kind to a specific kind and directness. @@ -734,7 +736,7 @@ NodePointer Demangler::demangleOperator() { goto recur; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 0xA: case 0xB: case 0xC: - return demangleSymbolicReference((unsigned char)c, Text.data() + Pos); + return demangleSymbolicReference((unsigned char)c); case 'A': return demangleMultiSubstitutions(); case 'B': return demangleBuiltinType(); case 'C': return demangleAnyGenericType(Node::Kind::Class); diff --git a/lib/SILGen/SILGenBuiltin.cpp b/lib/SILGen/SILGenBuiltin.cpp index 45e94b5575123..69bb753687243 100644 --- a/lib/SILGen/SILGenBuiltin.cpp +++ b/lib/SILGen/SILGenBuiltin.cpp @@ -901,6 +901,45 @@ emitBuiltinIsUnique_native(SILGenFunction &SGF, return ManagedValue::forUnmanaged(result); } +static ManagedValue +emitBuiltinBeginCOWMutation(SILGenFunction &SGF, + SILLocation loc, + SubstitutionMap subs, + ArrayRef args, + SGFContext C) { + return emitBuiltinIsUnique(SGF, loc, subs, args, C); +} + +static ManagedValue +emitBuiltinBeginCOWMutation_native(SILGenFunction &SGF, + SILLocation loc, + SubstitutionMap subs, + ArrayRef args, + SGFContext C) { + return emitBuiltinIsUnique_native(SGF, loc, subs, args, C); +} + +static ManagedValue +emitBuiltinEndCOWMutation(SILGenFunction &SGF, + SILLocation loc, + SubstitutionMap subs, + ArrayRef args, + SGFContext C) { + return ManagedValue::forUnmanaged(SGF.emitEmptyTuple(loc)); +} + +static ManagedValue +emitBuiltinCOWBufferForReading(SILGenFunction &SGF, + SILLocation loc, + SubstitutionMap subs, + ArrayRef args, + SGFContext C) { + + + assert(args.size() == 1 && "isUnique_native should have one arg."); + return args[0]; +} + static ManagedValue emitBuiltinBindMemory(SILGenFunction &SGF, SILLocation loc, SubstitutionMap subs, diff --git a/lib/SILOptimizer/Analysis/ArraySemantic.cpp b/lib/SILOptimizer/Analysis/ArraySemantic.cpp index 807a4d67017d6..ee50619935ccc 100644 --- a/lib/SILOptimizer/Analysis/ArraySemantic.cpp +++ b/lib/SILOptimizer/Analysis/ArraySemantic.cpp @@ -183,7 +183,13 @@ void ArraySemanticsCall::initialize(ApplyInst *AI, StringRef semanticName, // Need a 'self' argument otherwise this is not a semantic call that // we recognize. - if (getKind() < ArrayCallKind::kArrayInit && !hasSelf()) + ArrayCallKind kind = getKind(); + if (kind == ArrayCallKind::kNone) { + SemanticsCall = nullptr; + return; + } + + if (kind < ArrayCallKind::kArrayInit && !hasSelf()) SemanticsCall = nullptr; // A arguments must be passed reference count neutral except for self. diff --git a/lib/Sema/CSBindings.cpp b/lib/Sema/CSBindings.cpp index b4ac022c4811d..fac3bd9c85bda 100644 --- a/lib/Sema/CSBindings.cpp +++ b/lib/Sema/CSBindings.cpp @@ -1038,8 +1038,9 @@ bool TypeVarBindingProducer::computeNext() { auto srcLocator = binding.getLocator(); if (srcLocator && - srcLocator->isLastElement() && - !type->hasTypeVariable() && CS.isCollectionType(type)) { + (srcLocator->isLastElement() || + srcLocator->isLastElement()) && + !type->hasTypeVariable() && CS.isCollectionType(type)) { // If the type binding comes from the argument conversion, let's // instead of binding collection types directly, try to bind // using temporary type variables substituted for element diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp index 6ddb39a07e68c..47e0795f5ac4d 100644 --- a/lib/Sema/TypeCheckConstraints.cpp +++ b/lib/Sema/TypeCheckConstraints.cpp @@ -1161,7 +1161,7 @@ namespace { ExprStack.pop_back(); // Mark the direct callee as being a callee. - if (auto *call = dyn_cast(expr)) + if (auto *call = dyn_cast(expr)) markDirectCallee(call->getFn()); // Fold sequence expressions. diff --git a/stdlib/public/runtime/Casting.cpp b/stdlib/public/runtime/Casting.cpp index 0ee06c24033fb..6e7d14e2b58ab 100644 --- a/stdlib/public/runtime/Casting.cpp +++ b/stdlib/public/runtime/Casting.cpp @@ -1189,13 +1189,6 @@ swift_dynamicCastMetatypeImpl(const Metadata *sourceType, } break; - case MetadataKind::Existential: { - auto targetTypeAsExistential = static_cast(targetType); - if (_conformsToProtocols(nullptr, sourceType, targetTypeAsExistential, nullptr)) - return origSourceType; - return nullptr; - } - default: return nullptr; } diff --git a/test/Constraints/keyword_arguments.swift b/test/Constraints/keyword_arguments.swift index 8ea73b96d2033..2076815fb8f35 100644 --- a/test/Constraints/keyword_arguments.swift +++ b/test/Constraints/keyword_arguments.swift @@ -874,3 +874,19 @@ func generic_and_missing_label(x: T) {} generic_and_missing_label(42) // expected-error@-1 {{missing argument label 'x:' in call}} {{27-27=x: }} + +// SR-13135: Type inference regression in Swift 5.3 - can't infer a type of @autoclosure result. +func sr13135() { + struct Foo { + var bar: [Int] = [] + } + + let baz: Int? = nil + + func foo( + _ a: @autoclosure () throws -> T, + _ b: @autoclosure () throws -> T + ) {} + + foo(Foo().bar, [baz]) +} diff --git a/test/Constraints/operator.swift b/test/Constraints/operator.swift index 6b2ffe10644c4..8830df2d18102 100644 --- a/test/Constraints/operator.swift +++ b/test/Constraints/operator.swift @@ -290,3 +290,9 @@ func rdar_62054241() { return arr.sorted(by: <) // expected-error {{no exact matches in reference to operator function '<'}} } } + +// SR-11399 - Operator returning IUO doesn't implicitly unwrap +postfix operator ^^^ +postfix func ^^^ (lhs: Int) -> Int! { 0 } + +let x: Int = 1^^^ diff --git a/test/IRGen/builtins.swift b/test/IRGen/builtins.swift index d051f5ede450a..d2dbff0b194c9 100644 --- a/test/IRGen/builtins.swift +++ b/test/IRGen/builtins.swift @@ -683,6 +683,12 @@ func isUniqueIUO(_ ref: inout Builtin.NativeObject?) -> Bool { return Builtin.isUnique(&iuo) } +// CHECK-LABEL: define hidden {{.*}} @"$s8builtins19COWBufferForReadingyAA1CCADnF" +// CHECK: ret %T8builtins1CC* %0 +func COWBufferForReading(_ ref: __owned C) -> C { + return Builtin.COWBufferForReading(ref) +} + // CHECK-LABEL: define {{.*}} @{{.*}}generic_ispod_test func generic_ispod_test(_: T) { // CHECK: [[T0:%.*]] = getelementptr inbounds %swift.vwtable, %swift.vwtable* [[T:%.*]], i32 10 diff --git a/test/Interpreter/generic_casts.swift b/test/Interpreter/generic_casts.swift index ecace2ee16136..73f1837d20ab9 100644 --- a/test/Interpreter/generic_casts.swift +++ b/test/Interpreter/generic_casts.swift @@ -1,9 +1,10 @@ // RUN: %empty-directory(%t) // RUN: %target-build-swift -Onone %s -o %t/a.out -// RUN: %target-run %t/a.out | %FileCheck --check-prefix CHECK --check-prefix CHECK-ONONE %s // RUN: %target-build-swift -O %s -o %t/a.out.optimized // RUN: %target-codesign %t/a.out.optimized -// RUN: %target-run %t/a.out.optimized | %FileCheck %s +// +// RUN: %target-run %t/a.out | %FileCheck --check-prefix CHECK %s +// RUN: %target-run %t/a.out.optimized | %FileCheck --check-prefix CHECK %s // REQUIRES: executable_test // FIXME: rdar://problem/19648117 Needs splitting objc parts out @@ -140,42 +141,50 @@ class PC: P {} class PCSub: PC {} // `is` checks -func nongenericAnyIsPConforming(type: Any.Type) -> Bool { +func nongenericAnyIsPType(type: Any.Type) -> Bool { // `is P.Type` tests whether the argument conforms to `P` // Note: this can only be true for a concrete type, never a protocol return type is P.Type } -func nongenericAnyIsPSubtype(type: Any.Type) -> Bool { +func nongenericAnyIsPProtocol(type: Any.Type) -> Bool { + // `P.Protocol` is the metatype for `P` (the type of `P.self`) // `is P.Protocol` tests whether the argument is a subtype of `P` // In particular, it is true for `P.self` return type is P.Protocol } -func nongenericAnyIsPAndAnyObjectConforming(type: Any.Type) -> Bool { +func nongenericAnyIsPAndAnyObjectType(type: Any.Type) -> Bool { return type is (P & AnyObject).Type } -func nongenericAnyIsPAndPCSubConforming(type: Any.Type) -> Bool { +func nongenericAnyIsPAndAnyObjectProtocol(type: Any.Type) -> Bool { + return type is (P & AnyObject).Protocol +} +func nongenericAnyIsPAndPCSubType(type: Any.Type) -> Bool { return type is (P & PCSub).Type } func genericAnyIs(type: Any.Type, to: T.Type, expected: Bool) -> Bool { // If we're testing against a runtime that doesn't have the fix this tests, // just pretend we got it right. if #available(macOS 10.15.4, iOS 13.4, watchOS 6.2, tvOS 13.4, *) { + // Remember: If `T` is bound to `P`, then `T.Type` is `P.Protocol` return type is T.Type } else { return expected } } // `as?` checks -func nongenericAnyAsConditionalPConforming(type: Any.Type) -> Bool { +func nongenericAnyAsConditionalPType(type: Any.Type) -> Bool { return (type as? P.Type) != nil } -func nongenericAnyAsConditionalPSubtype(type: Any.Type) -> Bool { +func nongenericAnyAsConditionalPProtocol(type: Any.Type) -> Bool { return (type as? P.Protocol) != nil } -func nongenericAnyAsConditionalPAndAnyObjectConforming(type: Any.Type) -> Bool { +func nongenericAnyAsConditionalPAndAnyObjectType(type: Any.Type) -> Bool { return (type as? (P & AnyObject).Type) != nil } -func nongenericAnyAsConditionalPAndPCSubConforming(type: Any.Type) -> Bool { +func nongenericAnyAsConditionalPAndAnyObjectProtocol(type: Any.Type) -> Bool { + return (type as? (P & AnyObject).Protocol) != nil +} +func nongenericAnyAsConditionalPAndPCSubType(type: Any.Type) -> Bool { return (type as? (P & PCSub).Type) != nil } func genericAnyAsConditional(type: Any.Type, to: T.Type, expected: Bool) -> Bool { @@ -190,19 +199,19 @@ func genericAnyAsConditional(type: Any.Type, to: T.Type, expected: Bool) -> B // `as!` checks func blackhole(_ : T) { } -func nongenericAnyAsUnconditionalPConforming(type: Any.Type) -> Bool { +func nongenericAnyAsUnconditionalPType(type: Any.Type) -> Bool { blackhole(type as! P.Type) return true } -func nongenericAnyAsUnconditionalPSubtype(type: Any.Type) -> Bool { +func nongenericAnyAsUnconditionalPProtocol(type: Any.Type) -> Bool { blackhole(type as! P.Protocol) return true } -func nongenericAnyAsUnconditionalPAndAnyObjectConforming(type: Any.Type) -> Bool { +func nongenericAnyAsUnconditionalPAndAnyObjectType(type: Any.Type) -> Bool { blackhole(type as! (P & AnyObject).Type) return true } -func nongenericAnyAsUnconditionalPAndPCSubConforming(type: Any.Type) -> Bool { +func nongenericAnyAsUnconditionalPAndPCSubType(type: Any.Type) -> Bool { blackhole(type as! (P & PCSub).Type) return true } @@ -215,135 +224,153 @@ func genericAnyAsUnconditional(type: Any.Type, to: T.Type, expected: Bool) -> // CHECK-LABEL: casting types to protocols with generics: print("casting types to protocols with generics:") -print(nongenericAnyIsPConforming(type: P.self)) // CHECK: false -print(nongenericAnyIsPSubtype(type: P.self)) // CHECK: true -print(genericAnyIs(type: P.self, to: P.self, expected: true)) // CHECK: true -print(nongenericAnyIsPConforming(type: PS.self)) // CHECK: true -print(genericAnyIs(type: PS.self, to: P.self, expected: true)) // CHECK-ONONE: true -print(nongenericAnyIsPConforming(type: PE.self)) // CHECK: true -print(genericAnyIs(type: PE.self, to: P.self, expected: true)) // CHECK-ONONE: true -print(nongenericAnyIsPConforming(type: PC.self)) // CHECK: true -print(genericAnyIs(type: PC.self, to: P.self, expected: true)) // CHECK-ONONE: true -print(nongenericAnyIsPConforming(type: PCSub.self)) // CHECK: true -print(genericAnyIs(type: PCSub.self, to: P.self, expected: true)) // CHECK-ONONE: true +print(#line, nongenericAnyIsPType(type: P.self)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyIsPProtocol(type: P.self)) // CHECK: [[@LINE]] true +print(#line, genericAnyIs(type: P.self, to: P.self, expected: true)) // CHECK: [[@LINE]] true +print(#line, nongenericAnyIsPType(type: PS.self)) // CHECK: [[@LINE]] true +print(#line, PS() is P) // CHECK: [[@LINE]] true +// One candidate for a Swift type theory holds that +// `A is a subtype of B iff A.self is metatype` +// In that theory, `PS() is P` above would imply that +// `PS.self is P.Protocol` below must also be true. +// But that theory is not the one that Swift currently +// implements. +print(#line, nongenericAnyIsPProtocol(type: PS.self)) // CHECK: [[@LINE]] false +print(#line, genericAnyIs(type: PS.self, to: P.self, expected: false)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyIsPType(type: PE.self)) // CHECK: [[@LINE]] true +print(#line, nongenericAnyIsPProtocol(type: PE.self)) // CHECK: [[@LINE]] false +print(#line, genericAnyIs(type: PE.self, to: P.self, expected: false)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyIsPType(type: PC.self)) // CHECK: [[@LINE]] true +print(#line, nongenericAnyIsPProtocol(type: PC.self)) // CHECK: [[@LINE]] false +print(#line, genericAnyIs(type: PC.self, to: P.self, expected: false)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyIsPType(type: PCSub.self)) // CHECK: [[@LINE]] true +print(#line, nongenericAnyIsPProtocol(type: PCSub.self)) // CHECK: [[@LINE]] false +print(#line, genericAnyIs(type: PCSub.self, to: P.self, expected: false)) // CHECK: [[@LINE]] false // CHECK-LABEL: conditionally casting types to protocols with generics: -print("conditionally casting types to protocols with generics:") -print(nongenericAnyAsConditionalPConforming(type: P.self)) // CHECK: false -print(nongenericAnyAsConditionalPSubtype(type: P.self)) // CHECK: true -print(genericAnyAsConditional(type: P.self, to: P.self, expected: true)) // CHECK: true -print(nongenericAnyAsConditionalPConforming(type: PS.self)) // CHECK: true -print(genericAnyAsConditional(type: PS.self, to: P.self, expected: true)) // CHECK-ONONE: true -print(nongenericAnyAsConditionalPConforming(type: PE.self)) // CHECK: true -print(genericAnyAsConditional(type: PE.self, to: P.self, expected: true)) // CHECK-ONONE: true -print(nongenericAnyAsConditionalPConforming(type: PC.self)) // CHECK: true -print(genericAnyAsConditional(type: PC.self, to: P.self, expected: true)) // CHECK-ONONE: true -print(nongenericAnyAsConditionalPConforming(type: PCSub.self)) // CHECK: true -print(genericAnyAsConditional(type: PCSub.self, to: P.self, expected: true)) // CHECK-ONONE: true +print(#line, "conditionally casting types to protocols with generics:") +print(#line, nongenericAnyAsConditionalPType(type: P.self)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyAsConditionalPProtocol(type: P.self)) // CHECK: [[@LINE]] true +print(#line, genericAnyAsConditional(type: P.self, to: P.self, expected: true)) // CHECK: [[@LINE]] true +print(#line, nongenericAnyAsConditionalPType(type: PS.self)) // CHECK: [[@LINE]] true +print(#line, nongenericAnyAsConditionalPProtocol(type: PS.self)) // CHECK: [[@LINE]] false +print(#line, genericAnyAsConditional(type: PS.self, to: P.self, expected: false)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyAsConditionalPType(type: PE.self)) // CHECK: [[@LINE]] true +print(#line, nongenericAnyAsConditionalPProtocol(type: PE.self)) // CHECK: [[@LINE]] false +print(#line, genericAnyAsConditional(type: PE.self, to: P.self, expected: false)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyAsConditionalPType(type: PC.self)) // CHECK: [[@LINE]] true +print(#line, nongenericAnyAsConditionalPProtocol(type: PC.self)) // CHECK: [[@LINE]] false +print(#line, genericAnyAsConditional(type: PC.self, to: P.self, expected: false)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyAsConditionalPType(type: PCSub.self)) // CHECK: [[@LINE]] true +print(#line, nongenericAnyAsConditionalPProtocol(type: PCSub.self)) // CHECK: [[@LINE]] false +print(#line, genericAnyAsConditional(type: PCSub.self, to: P.self, expected: false)) // CHECK: [[@LINE]] false // CHECK-LABEL: unconditionally casting types to protocols with generics: -print("unconditionally casting types to protocols with generics:") -//print(nongenericAnyAsUnconditionalPConforming(type: P.self)) // expected to trap -print(nongenericAnyAsUnconditionalPSubtype(type: P.self)) // CHECK: true -print(genericAnyAsUnconditional(type: P.self, to: P.self, expected: true)) // CHECK: true -print(nongenericAnyAsUnconditionalPConforming(type: PS.self)) // CHECK: true -print(genericAnyAsUnconditional(type: PS.self, to: P.self, expected: true)) // CHECK: true -print(nongenericAnyAsUnconditionalPConforming(type: PE.self)) // CHECK: true -print(genericAnyAsUnconditional(type: PE.self, to: P.self, expected: true)) // CHECK: true -print(nongenericAnyAsUnconditionalPConforming(type: PC.self)) // CHECK: true -print(genericAnyAsUnconditional(type: PC.self, to: P.self, expected: true)) // CHECK: true -print(nongenericAnyAsUnconditionalPConforming(type: PCSub.self)) // CHECK: true -print(genericAnyAsUnconditional(type: PCSub.self, to: P.self, expected: true)) // CHECK: true +print(#line, "unconditionally casting types to protocols with generics:") +//print(#line, nongenericAnyAsUnconditionalPType(type: P.self)) // expected to trap +print(#line, nongenericAnyAsUnconditionalPProtocol(type: P.self)) // CHECK: [[@LINE]] true +print(#line, genericAnyAsUnconditional(type: P.self, to: P.self, expected: true)) // CHECK: [[@LINE]] true +print(#line, nongenericAnyAsUnconditionalPType(type: PS.self)) // CHECK: [[@LINE]] true +print(#line, genericAnyAsUnconditional(type: PS.self, to: P.self, expected: true)) // CHECK: [[@LINE]] true +print(#line, nongenericAnyAsUnconditionalPType(type: PE.self)) // CHECK: [[@LINE]] true +print(#line, genericAnyAsUnconditional(type: PE.self, to: P.self, expected: true)) // CHECK: [[@LINE]] true +print(#line, nongenericAnyAsUnconditionalPType(type: PC.self)) // CHECK: [[@LINE]] true +print(#line, genericAnyAsUnconditional(type: PC.self, to: P.self, expected: true)) // CHECK: [[@LINE]] true +print(#line, nongenericAnyAsUnconditionalPType(type: PCSub.self)) // CHECK: [[@LINE]] true +print(#line, genericAnyAsUnconditional(type: PCSub.self, to: P.self, expected: true)) // CHECK: [[@LINE]] true // CHECK-LABEL: casting types to protocol & AnyObject existentials: -print("casting types to protocol & AnyObject existentials:") -print(nongenericAnyIsPAndAnyObjectConforming(type: PS.self)) // CHECK: false -print(genericAnyIs(type: PS.self, to: (P & AnyObject).self, expected: false)) // CHECK: false -print(nongenericAnyIsPAndAnyObjectConforming(type: PE.self)) // CHECK: false -print(genericAnyIs(type: PE.self, to: (P & AnyObject).self, expected: false)) // CHECK: false -print(nongenericAnyIsPAndAnyObjectConforming(type: PC.self)) // CHECK: true -print(genericAnyIs(type: PC.self, to: (P & AnyObject).self, expected: true)) // CHECK-ONONE: true -print(nongenericAnyIsPAndAnyObjectConforming(type: PCSub.self)) // CHECK: true -print(genericAnyIs(type: PCSub.self, to: (P & AnyObject).self, expected: true)) // CHECK-ONONE: true -print(nongenericAnyAsConditionalPAndAnyObjectConforming(type: PS.self)) // CHECK: false -print(genericAnyAsConditional(type: PS.self, to: (P & AnyObject).self, expected: false)) // CHECK: false -print(nongenericAnyAsConditionalPAndAnyObjectConforming(type: PE.self)) // CHECK: false -print(genericAnyAsConditional(type: PE.self, to: (P & AnyObject).self, expected: false)) // CHECK: false -print(nongenericAnyAsConditionalPAndAnyObjectConforming(type: PC.self)) // CHECK: true -print(genericAnyAsConditional(type: PC.self, to: (P & AnyObject).self, expected: true)) // CHECK-ONONE: true -print(nongenericAnyAsConditionalPAndAnyObjectConforming(type: PCSub.self)) // CHECK: true -print(genericAnyAsConditional(type: PCSub.self, to: (P & AnyObject).self, expected: true)) // CHECK-ONONE: true +print(#line, "casting types to protocol & AnyObject existentials:") +print(#line, nongenericAnyIsPAndAnyObjectType(type: PS.self)) // CHECK: [[@LINE]] false +print(#line, genericAnyIs(type: PS.self, to: (P & AnyObject).self, expected: false)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyIsPAndAnyObjectType(type: PE.self)) // CHECK: [[@LINE]] false +print(#line, genericAnyIs(type: PE.self, to: (P & AnyObject).self, expected: false)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyIsPAndAnyObjectType(type: PC.self)) // CHECK: [[@LINE]] true +print(#line, nongenericAnyIsPAndAnyObjectProtocol(type: PC.self)) // CHECK: [[@LINE]] false +print(#line, genericAnyIs(type: PC.self, to: (P & AnyObject).self, expected: false)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyIsPAndAnyObjectType(type: PCSub.self)) // CHECK: [[@LINE]] true +print(#line, nongenericAnyIsPAndAnyObjectProtocol(type: PCSub.self)) // CHECK: [[@LINE]] false +print(#line, genericAnyIs(type: PCSub.self, to: (P & AnyObject).self, expected: false)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyAsConditionalPAndAnyObjectType(type: PS.self)) // CHECK: [[@LINE]] false +print(#line, genericAnyAsConditional(type: PS.self, to: (P & AnyObject).self, expected: false)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyAsConditionalPAndAnyObjectType(type: PE.self)) // CHECK: [[@LINE]] false +print(#line, genericAnyAsConditional(type: PE.self, to: (P & AnyObject).self, expected: false)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyAsConditionalPAndAnyObjectType(type: PC.self)) // CHECK: [[@LINE]] true +print(#line, nongenericAnyAsConditionalPAndAnyObjectProtocol(type: PC.self)) // CHECK: [[@LINE]] false +print(#line, genericAnyAsConditional(type: PC.self, to: (P & AnyObject).self, expected: false)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyAsConditionalPAndAnyObjectType(type: PCSub.self)) // CHECK: [[@LINE]] true +print(#line, genericAnyAsConditional(type: PCSub.self, to: (P & AnyObject).self, expected: false)) // CHECK: [[@LINE]] false // CHECK-LABEL: casting types to protocol & class existentials: -print("casting types to protocol & class existentials:") -print(nongenericAnyIsPAndPCSubConforming(type: PS.self)) // CHECK: false -print(genericAnyIs(type: PS.self, to: (P & PCSub).self, expected: false)) // CHECK: false -print(nongenericAnyIsPAndPCSubConforming(type: PE.self)) // CHECK: false -print(genericAnyIs(type: PE.self, to: (P & PCSub).self, expected: false)) // CHECK: false -//print(nongenericAnyIsPAndPCSubConforming(type: PC.self)) // CHECK-SR-11565: false -- FIXME: reenable this when SR-11565 is fixed -print(genericAnyIs(type: PC.self, to: (P & PCSub).self, expected: false)) // CHECK: false -print(nongenericAnyIsPAndPCSubConforming(type: PCSub.self)) // CHECK: true -print(genericAnyIs(type: PCSub.self, to: (P & PCSub).self, expected: true)) // CHECK-ONONE: true -print(nongenericAnyAsConditionalPAndPCSubConforming(type: PS.self)) // CHECK: false -print(genericAnyAsConditional(type: PS.self, to: (P & PCSub).self, expected: false)) // CHECK: false -print(nongenericAnyAsConditionalPAndPCSubConforming(type: PE.self)) // CHECK: false -print(genericAnyAsConditional(type: PE.self, to: (P & PCSub).self, expected: false)) // CHECK: false -//print(nongenericAnyAsConditionalPAndPCSubConforming(type: PC.self)) // CHECK-SR-11565: false -- FIXME: reenable this when SR-11565 is fixed -print(genericAnyAsConditional(type: PC.self, to: (P & PCSub).self, expected: false)) // CHECK: false -print(nongenericAnyAsConditionalPAndPCSubConforming(type: PCSub.self)) // CHECK: true -print(genericAnyAsConditional(type: PCSub.self, to: (P & PCSub).self, expected: true)) // CHECK-ONONE: true +print(#line, "casting types to protocol & class existentials:") +print(#line, nongenericAnyIsPAndPCSubType(type: PS.self)) // CHECK: [[@LINE]] false +print(#line, genericAnyIs(type: PS.self, to: (P & PCSub).self, expected: false)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyIsPAndPCSubType(type: PE.self)) // CHECK: [[@LINE]] false +print(#line, genericAnyIs(type: PE.self, to: (P & PCSub).self, expected: false)) // CHECK: [[@LINE]] false +//print(#line, nongenericAnyIsPAndPCSubType(type: PC.self)) // CHECK-SR-11565: [[@LINE]] false -- FIXME: reenable this when SR-11565 is fixed +print(#line, genericAnyIs(type: PC.self, to: (P & PCSub).self, expected: false)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyIsPAndPCSubType(type: PCSub.self)) // CHECK: [[@LINE]] true +print(#line, genericAnyIs(type: PCSub.self, to: (P & PCSub).self, expected: false)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyAsConditionalPAndPCSubType(type: PS.self)) // CHECK: [[@LINE]] false +print(#line, genericAnyAsConditional(type: PS.self, to: (P & PCSub).self, expected: false)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyAsConditionalPAndPCSubType(type: PE.self)) // CHECK: [[@LINE]] false +print(#line, genericAnyAsConditional(type: PE.self, to: (P & PCSub).self, expected: false)) // CHECK: [[@LINE]] false +// print(#line, nongenericAnyAsConditionalPAndPCSubType(type: PC.self)) // CHECK-SR-11565: [[@LINE]] false -- FIXME: reenable this when SR-11565 is fixed +print(#line, genericAnyAsConditional(type: PC.self, to: (P & PCSub).self, expected: false)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyAsConditionalPAndPCSubType(type: PCSub.self)) // CHECK: [[@LINE]] true +print(#line, genericAnyAsConditional(type: PCSub.self, to: (P & PCSub).self, expected: false)) // CHECK: [[@LINE]] false // CHECK-LABEL: type comparisons: -print("type comparisons:\n") -print(allMetasToAllMetas(Int.self, Int.self)) // CHECK: true -print(allMetasToAllMetas(Int.self, Float.self)) // CHECK: false -print(allMetasToAllMetas(C.self, C.self)) // CHECK: true -print(allMetasToAllMetas(D.self, C.self)) // CHECK: true -print(allMetasToAllMetas(C.self, D.self)) // CHECK: false -print(C.self is D.Type) // CHECK: false -print((D.self as C.Type) is D.Type) // CHECK: true +print(#line, "type comparisons:\n") +print(#line, allMetasToAllMetas(Int.self, Int.self)) // CHECK: [[@LINE]] true +print(#line, allMetasToAllMetas(Int.self, Float.self)) // CHECK: [[@LINE]] false +print(#line, allMetasToAllMetas(C.self, C.self)) // CHECK: [[@LINE]] true +print(#line, allMetasToAllMetas(D.self, C.self)) // CHECK: [[@LINE]] true +print(#line, allMetasToAllMetas(C.self, D.self)) // CHECK: [[@LINE]] false +print(#line, C.self is D.Type) // CHECK: [[@LINE]] false +print(#line, (D.self as C.Type) is D.Type) // CHECK: [[@LINE]] true let t: Any.Type = type(of: 1 as Any) -print(t is Int.Type) // CHECK: true -print(t is Float.Type) // CHECK: false -print(t is C.Type) // CHECK: false +print(#line, t is Int.Type) // CHECK: [[@LINE]] true +print(#line, t is Float.Type) // CHECK: [[@LINE]] false +print(#line, t is C.Type) // CHECK: [[@LINE]] false let u: Any.Type = type(of: (D() as Any)) -print(u is C.Type) // CHECK: true -print(u is D.Type) // CHECK: true -print(u is E.Type) // CHECK: false -print(u is Int.Type) // CHECK: false +print(#line, u is C.Type) // CHECK: [[@LINE]] true +print(#line, u is D.Type) // CHECK: [[@LINE]] true +print(#line, u is E.Type) // CHECK: [[@LINE]] false +print(#line, u is Int.Type) // CHECK: [[@LINE]] false // FIXME: Can't spell AnyObject.Protocol // CHECK-LABEL: AnyObject casts: -print("AnyObject casts:") -print(allToAll(C(), AnyObject.self)) // CHECK: true +print(#line, "AnyObject casts:") +print(#line, allToAll(C(), AnyObject.self)) // CHECK: [[@LINE]] true // On Darwin, the object will be the ObjC-runtime-class object; // out of Darwin, this should not succeed. -print(allToAll(type(of: C()), AnyObject.self)) +print(#line, allToAll(type(of: C()), AnyObject.self)) // CHECK-objc: true // CHECK-native: false // Bridging // NSNumber on Darwin, __SwiftValue on Linux. -print(allToAll(0, AnyObject.self)) // CHECK: true +print(#line, allToAll(0, AnyObject.self)) // CHECK: [[@LINE]] true // This will get bridged using __SwiftValue. struct NotBridged { var x: Int } -print(allToAll(NotBridged(x: 0), AnyObject.self)) // CHECK: true +print(#line, allToAll(NotBridged(x: 0), AnyObject.self)) // CHECK: [[@LINE]] true #if canImport(Foundation) // This requires Foundation (for NSCopying): -print(allToAll(NotBridged(x: 0), NSCopying.self)) // CHECK-objc: true +print(#line, allToAll(NotBridged(x: 0), NSCopying.self)) // CHECK-objc: [[@LINE]] true #endif // On Darwin, these casts fail (intentionally) even though __SwiftValue does // technically conform to these protocols through NSObject. // Off Darwin, it should not conform at all. -print(allToAll(NotBridged(x: 0), CustomStringConvertible.self)) // CHECK: false -print(allToAll(NotBridged(x: 0), (AnyObject & CustomStringConvertible).self)) // CHECK: false +print(#line, allToAll(NotBridged(x: 0), CustomStringConvertible.self)) // CHECK: [[@LINE]] false +print(#line, allToAll(NotBridged(x: 0), (AnyObject & CustomStringConvertible).self)) // CHECK: [[@LINE]] false #if canImport(Foundation) // This requires Foundation (for NSArray): @@ -362,5 +389,5 @@ func swiftOptimizesThisFunctionIncorrectly() -> Bool { } let result = swiftOptimizesThisFunctionIncorrectly() -print("Bridge cast result: \(result)") // CHECK-NEXT-objc: Bridge cast result: true +print(#line, "Bridge cast result: \(result)") // CHECK-NEXT-objc: Bridge cast result: true #endif diff --git a/test/Interpreter/generic_casts_objc.swift b/test/Interpreter/generic_casts_objc.swift index f7e9ccd80c01e..e9561d2e2e047 100644 --- a/test/Interpreter/generic_casts_objc.swift +++ b/test/Interpreter/generic_casts_objc.swift @@ -16,9 +16,12 @@ enum PE: P {} class PC: P, PObjC {} class PCSub: PC {} -func nongenericAnyIsPObjC(type: Any.Type) -> Bool { +func nongenericAnyIsPObjCType(type: Any.Type) -> Bool { return type is PObjC.Type } +func nongenericAnyIsPObjCProtocol(type: Any.Type) -> Bool { + return type is PObjC.Protocol +} func genericAnyIs(type: Any.Type, to: T.Type, expected: Bool) -> Bool { // If we're testing against a runtime that doesn't have the fix this tests, // just pretend we got it right. @@ -29,13 +32,23 @@ func genericAnyIs(type: Any.Type, to: T.Type, expected: Bool) -> Bool { } } -// CHECK-LABEL: casting types to ObjC protocols with generics: -print("casting types to ObjC protocols with generics:") -print(nongenericAnyIsPObjC(type: PS.self)) // CHECK: false -print(genericAnyIs(type: PS.self, to: PObjC.self, expected: false)) // CHECK: false -print(nongenericAnyIsPObjC(type: PE.self)) // CHECK: false -print(genericAnyIs(type: PE.self, to: PObjC.self, expected: false)) // CHECK: false -print(nongenericAnyIsPObjC(type: PC.self)) // CHECK: true -print(genericAnyIs(type: PC.self, to: PObjC.self, expected: true)) // CHECK-ONONE: true -print(nongenericAnyIsPObjC(type: PCSub.self)) // CHECK: true -print(genericAnyIs(type: PCSub.self, to: PObjC.self, expected: true)) // CHECK-ONONE: true +// CHECK-LABEL: casting types to ObjC protocol existential metatype: +print("casting types to ObjC protocol existential metatype:") +print(#line, nongenericAnyIsPObjCType(type: PS.self)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyIsPObjCType(type: PE.self)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyIsPObjCType(type: PC.self)) // CHECK: [[@LINE]] true +print(#line, nongenericAnyIsPObjCType(type: PCSub.self)) // CHECK: [[@LINE]] true + +// CHECK-LABEL: casting types to ObjC protocol metatype: +print("casting types to ObjC protocol metatype:") +print(#line, nongenericAnyIsPObjCProtocol(type: PS.self)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyIsPObjCProtocol(type: PE.self)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyIsPObjCProtocol(type: PC.self)) // CHECK: [[@LINE]] false +print(#line, nongenericAnyIsPObjCProtocol(type: PCSub.self)) // CHECK: [[@LINE]] false + +// CHECK-LABEL: casting types to ObjC protocol metatype via generic: +print("casting types to ObjC protocol metatype via generic:") +print(#line, genericAnyIs(type: PS.self, to: PObjC.self, expected: false)) // CHECK: [[@LINE]] false +print(#line, genericAnyIs(type: PE.self, to: PObjC.self, expected: false)) // CHECK: [[@LINE]] false +print(#line, genericAnyIs(type: PC.self, to: PObjC.self, expected: false)) // CHECK: [[@LINE]] false +print(#line, genericAnyIs(type: PCSub.self, to: PObjC.self, expected: false)) // CHECK: [[@LINE]] false diff --git a/test/SILGen/builtins.swift b/test/SILGen/builtins.swift index fa7792c4c3aab..9aaa51f424b55 100644 --- a/test/SILGen/builtins.swift +++ b/test/SILGen/builtins.swift @@ -600,6 +600,31 @@ func castBitPatternFromBridgeObject(_ bo: Builtin.BridgeObject) -> Builtin.Word return Builtin.castBitPatternFromBridgeObject(bo) } +// CHECK-LABEL: sil hidden [ossa] @$s8builtins16beginCOWMutationySbAA1CCzF +// CHECK: [[WRITE:%.*]] = begin_access [modify] [unknown] %0 : $*C +// CHECK: [[BUILTIN:%.*]] = is_unique [[WRITE]] : $*C +// CHECK: return +func beginCOWMutation(_ c: inout C) -> Bool { + return Bool(_builtinBooleanLiteral: Builtin.beginCOWMutation(&c)) +} + +// CHECK-LABEL: sil hidden [ossa] @$s8builtins23beginCOWMutation_nativeySbAA1CCzF +// CHECK: [[WRITE:%.*]] = begin_access [modify] [unknown] %0 : $*C +// CHECK: [[CAST:%.*]] = unchecked_addr_cast [[WRITE]] : $*C to $*Builtin.NativeObject +// CHECK: [[BUILTIN:%.*]] = is_unique [[CAST]] : $*Builtin.NativeObject +// CHECK: return +func beginCOWMutation_native(_ c: inout C) -> Bool { + return Bool(_builtinBooleanLiteral: Builtin.beginCOWMutation_native(&c)) +} + +// CHECK-LABEL: sil hidden [ossa] @$s8builtins14endCOWMutationyyAA1CCzF +// CHECK: begin_access +// CHECK-NEXT: tuple () +// CHECK-NEXT: end_access +func endCOWMutation(_ c: inout C) { + Builtin.endCOWMutation(&c) +} + // ---------------------------------------------------------------------------- // isUnique variants // ---------------------------------------------------------------------------- diff --git a/test/stdlib/Casts.swift b/test/stdlib/Casts.swift index 95bfd67ceb3e1..e29d94c043f88 100644 --- a/test/stdlib/Casts.swift +++ b/test/stdlib/Casts.swift @@ -21,6 +21,8 @@ import StdlibUnittest import Foundation #endif +private func blackhole(_ t: T) {} + let CastsTests = TestSuite("Casts") // Test for SR-426: missing release for some types after failed conversion @@ -161,4 +163,63 @@ CastsTests.test("Dynamic casts of CF types to protocol existentials") } #endif +CastsTests.test("Any.Protocol") { + class C {} + struct S {} + func isAnyProtocol(_ type: T.Type) -> Bool { + let result = T.self is Any.Protocol + if result { + // `as!` should succeed if `is` does + blackhole(T.self as! Any.Protocol) + } + return result + } + func isAnyType(_ type: T.Type) -> Bool { + return T.self is Any.Type + } + func isType(_ type: T.Type, to: U.Type) -> Bool { + return T.self is U.Type + } + + expectTrue(Int.self is Any.Type) + expectNotNil(Int.self as? Any.Type) + expectTrue(isAnyType(Int.self)) + expectFalse(Int.self is Any.Protocol) + expectNil(Int.self as? Any.Protocol) + expectFalse(isAnyProtocol(Int.self)) + expectFalse(isType(Int.self, to: Any.self)) + + expectTrue(C.self is Any.Type) + expectNotNil(C.self as? Any.Type) + expectTrue(isAnyType(C.self)) + expectFalse(C.self is Any.Protocol) + expectNil(C.self as? Any.Protocol) + expectFalse(isAnyProtocol(C.self)) + expectFalse(isType(C.self, to: Any.self)) + + expectTrue(S.self is Any.Type) + expectNotNil(S.self as? Any.Type) + expectTrue(isAnyType(S.self)) + expectFalse(S.self is Any.Protocol) + expectNil(S.self as? Any.Protocol) + expectFalse(isAnyProtocol(S.self)) + expectFalse(isType(S.self, to: Any.self)) + + expectTrue(Any.self is Any.Type) + expectNotNil(Any.self as? Any.Type) + expectTrue(isAnyType(Any.self)) + expectTrue(Any.self is Any.Protocol) + expectNotNil(Any.self as? Any.Protocol) + expectTrue(isAnyProtocol(Any.self)) + expectTrue(isType(Any.self, to: Any.self)) + + expectTrue(Any?.self is Any.Type) + expectNotNil(Any?.self as? Any.Type) + expectTrue(isAnyType(Any?.self)) + expectFalse(Any?.self is Any.Protocol) + expectNil(Any?.self as? Any.Protocol) + expectFalse(isAnyProtocol(Any?.self)) + expectFalse(isType(Any?.self, to: Any.self)) +} + runAllTests()