Skip to content

Commit 714075a

Browse files
authored
Merge pull request #4298 from slavapestov/fix-for-missing-conformance
Fix for missing conformance with id-as-Any bridging
2 parents 53e0d78 + 56e2e13 commit 714075a

File tree

5 files changed

+56
-5
lines changed

5 files changed

+56
-5
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4246,13 +4246,25 @@ void TypeChecker::useObjectiveCBridgeableConformances(DeclContext *dc,
42464246
: TC(tc), DC(dc), Proto(proto) { }
42474247

42484248
virtual Action walkToTypePre(Type ty) {
4249+
ConformanceCheckOptions options = ConformanceCheckFlags::InExpression
4250+
| ConformanceCheckFlags::Used
4251+
| ConformanceCheckFlags::SuppressDependencyTracking;
4252+
42494253
// If we have a nominal type, "use" its conformance to
42504254
// _ObjectiveCBridgeable if it has one.
4251-
if (ty->getAnyNominal()) {
4252-
ConformanceCheckOptions options = ConformanceCheckFlags::InExpression
4253-
| ConformanceCheckFlags::Used
4254-
| ConformanceCheckFlags::SuppressDependencyTracking;
4255+
if (auto *nominalDecl = ty->getAnyNominal()) {
42554256
(void)TC.conformsToProtocol(ty, Proto, DC, options);
4257+
4258+
if (nominalDecl == TC.Context.getSetDecl() ||
4259+
nominalDecl == TC.Context.getDictionaryDecl()) {
4260+
auto args = ty->castTo<BoundGenericType>()->getGenericArgs();
4261+
if (!args.empty()) {
4262+
auto keyType = args[0];
4263+
auto *hashableProto =
4264+
TC.Context.getProtocol(KnownProtocolKind::Hashable);
4265+
(void)TC.conformsToProtocol(keyType, hashableProto, DC, options);
4266+
}
4267+
}
42564268
}
42574269

42584270
return Action::Continue;

test/IRGen/objc_generic_class_metadata.sil

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ entry(%0: $Subclass):
7171
unreachable
7272
}
7373

74+
sil @_TToFC27objc_generic_class_metadata8SubclasscfT7optionsGSqGVs10DictionaryVSC13GenericOptionP____GSQS0__ : $@convention(objc_method) (@owned Subclass, @owned NSDictionary) -> @owned Subclass {
75+
entry(%0: $Subclass, %1: $NSDictionary):
76+
unreachable
77+
}
78+
7479
// CHECK-LABEL: define linkonce_odr hidden %swift.type* @_TMaCSo12GenericClass()
7580
// CHECK: [[T0:%.*]] = load %objc_class*, %objc_class** @"OBJC_CLASS_REF_$_GenericClass",
7681
// CHECK: call %objc_class* @rt_swift_getInitializedObjCClass(%objc_class* [[T0]])

test/Inputs/clang-importer-sdk/usr/include/objc_generics.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
11
#import <Foundation.h>
22

3+
#define _CF_TYPED_ENUM __attribute__((swift_wrapper(enum)))
4+
#define NS_STRING_ENUM _CF_TYPED_ENUM
5+
#define NS_SWIFT_NAME(Name) __attribute__((swift_name(#Name)))
6+
7+
typedef NSString * GenericOption NS_STRING_ENUM;
8+
9+
GenericOption const GenericOptionMultithreaded NS_SWIFT_NAME(multithreaded);
10+
11+
312
@interface GenericClass<T> : NSObject
413
- (id)initWithThing:(T)thing;
514
- (id)initWithArrayOfThings:(NSArray<T> *__nonnull)things;
15+
- (id)initWithOptions:(nullable NSDictionary<GenericOption, id> *)options;
616
- (void)dealloc;
717
- (__nullable T)thing;
818
- (int)count;

test/SILGen/objc_imported_generic.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,5 +103,29 @@ func genericFunc<V: AnyObject>(_ v: V.Type) {
103103
}
104104
}
105105

106+
// CHECK-LABEL: sil hidden @_TF21objc_imported_generic23configureWithoutOptionsFT_T_ : $@convention(thin) () -> ()
107+
// CHECK: [[NIL_FN:%.*]] = function_ref @_TFSqCfT10nilLiteralT__GSqx_ : $@convention(method) <τ_0_0> (@thin Optional<τ_0_0>.Type) -> @out Optional<τ_0_0>
108+
// CHECK: apply [[NIL_FN]]<[GenericOption : Any]>({{.*}})
109+
// CHECK: return
110+
func configureWithoutOptions() {
111+
_ = GenericClass<NSObject>(options: nil)
112+
}
113+
114+
// foreign to native thunk for init(options:), uses GenericOption : Hashable
115+
// conformance
116+
117+
// CHECK-LABEL: sil shared [thunk] @_TTOFCSo12GenericClasscfT7optionsGSqGVs10DictionaryVSC13GenericOptionP____GSQGS_x__ : $@convention(method) <T where T : AnyObject> (@owned Optional<Dictionary<GenericOption, Any>>, @owned GenericClass<T>) -> @owned ImplicitlyUnwrappedOptional<GenericClass<T>>
118+
// CHECK: [[FN:%.*]] = function_ref @_TFE10FoundationVs10Dictionary19_bridgeToObjectiveCfT_CSo12NSDictionary : $@convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@guaranteed Dictionary<τ_0_0, τ_0_1>) -> @owned NSDictionary
119+
// CHECK: apply [[FN]]<GenericOption, Any>({{.*}}) : $@convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@guaranteed Dictionary<τ_0_0, τ_0_1>) -> @owned NSDictionary
120+
// CHECK: return
121+
122+
// This gets emitted down here for some reason
123+
106124
// CHECK-LABEL: sil shared [thunk] @_TTOFCSo12GenericClasscfT13arrayOfThings
107125
// CHECK: class_method [volatile] {{%.*}} : $GenericClass<T>, #GenericClass.init!initializer.1.foreign {{.*}}, $@convention(objc_method) @pseudogeneric <τ_0_0 where τ_0_0 : AnyObject> (NSArray, @owned GenericClass<τ_0_0>) -> @owned ImplicitlyUnwrappedOptional<GenericClass<τ_0_0>>
126+
127+
// Make sure we emitted the witness table for the above conformance
128+
129+
// CHECK-LABEL: sil_witness_table shared [fragile] GenericOption: Hashable module objc_generics {
130+
// CHECK: method #Hashable.hashValue!getter.1: @_TTWVSC13GenericOptions8Hashable13objc_genericsFS0_g9hashValueSi
131+
// CHECK: }

validation-test/stdlib/SceneKit.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ if #available(iOS 8.0, *) {
346346
let sceneData = sceneDescription.data(
347347
using: .utf8,
348348
allowLossyConversion: true)!
349-
let sceneSource = SCNSceneSource(data: sceneData as Data, options: [:])!
349+
let sceneSource = SCNSceneSource(data: sceneData as Data, options: nil)!
350350

351351
do {
352352
var unarchivedPlaneGeometry =

0 commit comments

Comments
 (0)