diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp index 2829fc7063d45..c79e5f28cf70a 100644 --- a/lib/Sema/TypeCheckProtocol.cpp +++ b/lib/Sema/TypeCheckProtocol.cpp @@ -4853,6 +4853,7 @@ TypeChecker::findWitnessedObjCRequirements(const ValueDecl *witness, // We only care about Objective-C protocols. if (!proto->isObjC()) continue; + Optional conformance; for (auto req : proto->lookupDirect(name, true)) { // Skip anything in a protocol extension. if (req->getDeclContext() != proto) continue; @@ -4861,7 +4862,6 @@ TypeChecker::findWitnessedObjCRequirements(const ValueDecl *witness, if (isa(req)) continue; // Dig out the conformance. - Optional conformance; if (!conformance.hasValue()) { SmallVector conformances; nominal->lookupConformance(dc->getParentModule(), proto, diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index d36f5338bb4c4..27464da166ce0 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -2903,31 +2903,18 @@ bool TypeChecker::isCIntegerType(const DeclContext *DC, Type T) { /// Determines whether the given type is bridged to an Objective-C class type. static bool isBridgedToObjectiveCClass(DeclContext *dc, Type type) { - // Simple case: bridgeable object types. - if (type->isBridgeableObjectType()) - return true; - - // Any bridges to AnyObject. - if (type->isAny()) - return true; - - // Determine whether this type is bridged to Objective-C. - ASTContext &ctx = type->getASTContext(); - Optional bridged = ctx.getBridgedToObjC(dc, type, - ctx.getLazyResolver()); - if (!bridged) + switch (type->getForeignRepresentableIn(ForeignLanguage::ObjectiveC, dc) + .first) { + case ForeignRepresentableKind::Trivial: + case ForeignRepresentableKind::None: return false; - // Check whether we're bridging to a class. - auto classDecl = (*bridged)->getClassOrBoundGenericClass(); - if (!classDecl) - return false; - - // Allow anything that isn't bridged to NSNumber. - // FIXME: This feels like a hack, but we don't have the right predicate - // anywhere. - return classDecl->getName().str() - != ctx.getSwiftName(KnownFoundationEntity::NSNumber); + case ForeignRepresentableKind::Object: + case ForeignRepresentableKind::Bridged: + case ForeignRepresentableKind::BridgedError: + case ForeignRepresentableKind::StaticBridged: + return true; + } } bool TypeChecker::isRepresentableInObjC( diff --git a/test/attr/attr_objc.swift b/test/attr/attr_objc.swift index 89f0599fd07d7..ef37b0983d9a6 100644 --- a/test/attr/attr_objc.swift +++ b/test/attr/attr_objc.swift @@ -11,7 +11,9 @@ struct PlainStruct {} enum PlainEnum {} protocol PlainProtocol {} // expected-note {{protocol 'PlainProtocol' declared here}} -enum ErrorEnum : Error { } +enum ErrorEnum : Error { + case failed +} @objc class Class_ObjC1 {} @@ -1978,6 +1980,24 @@ class ClassThrows1 { // CHECK: @objc init(degrees: Double) throws // CHECK-DUMP: constructor_decl "init(degrees:)"{{.*}}foreign_error=NilResult,unowned,param=1,paramtype=Optional>> init(degrees: Double) throws { } + + // CHECK: {{^}} func methodReturnsBridgedValueType() throws -> NSRange + func methodReturnsBridgedValueType() throws -> NSRange { return NSRange() } + + @objc func methodReturnsBridgedValueType2() throws -> NSRange { + return NSRange() + } + // expected-error@-3{{throwing method cannot be marked @objc because it returns a value of type 'NSRange' (aka '_NSRange'); return 'Void' or a type that bridges to an Objective-C class}} + + // CHECK: {{^}} @objc func methodReturnsError() throws -> Error + func methodReturnsError() throws -> Error { return ErrorEnum.failed } + + // CHECK: @objc func methodReturnStaticBridged() throws -> ((Int) -> (Int) -> Int) + func methodReturnStaticBridged() throws -> ((Int) -> (Int) -> Int) { + func add(x: Int) -> (Int) -> Int { + return { x + $0 } + } + } } // CHECK-DUMP-LABEL: class_decl "SubclassImplicitClassThrows1" @@ -2127,15 +2147,14 @@ extension ClassInfersFromProtocol3 { func method1(value: String) { } } +// Inference for subclasses. class SuperclassImplementsProtocol : InferFromProtocol { } -// Note: no inference for subclasses class SubclassInfersFromProtocol1 : SuperclassImplementsProtocol { // CHECK: {{^}} @objc func method1(value: Int) func method1(value: Int) { } } -// Note: no inference for subclasses class SubclassInfersFromProtocol2 : SuperclassImplementsProtocol { } @@ -2143,4 +2162,3 @@ extension SubclassInfersFromProtocol2 { // CHECK: {{^}} @objc dynamic func method1(value: Int) func method1(value: Int) { } } -