Skip to content

Commit 2f3468f

Browse files
committed
[Clang importer] Type parameters substituted with existentials aren't Hashable
As a follow-on to the fix for rdar://problem/47564982, a type parameter in a generic Objective-C class whose type bounds include both a NSObject-derived superclass and a protocol would have been classified has being Hashable, when in fact the corresponding existential type will not conform to Hashable. Only allow hashability when there are no protocol requirements.
1 parent 4056273 commit 2f3468f

File tree

2 files changed

+8
-4
lines changed

2 files changed

+8
-4
lines changed

lib/ClangImporter/ImportType.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2436,9 +2436,13 @@ bool ClangImporter::Implementation::matchesHashableBound(Type type) {
24362436
// Match generic parameters against their bounds.
24372437
if (auto *genericTy = type->getAs<GenericTypeParamType>()) {
24382438
if (auto *generic = genericTy->getDecl()) {
2439-
type = generic->getSuperclass();
2440-
if (!type)
2441-
return false;
2439+
auto genericSig =
2440+
generic->getDeclContext()->getGenericSignatureOfContext();
2441+
if (genericSig && genericSig->getConformsTo(type).empty()) {
2442+
type = genericSig->getSuperclassBound(type);
2443+
if (!type)
2444+
return false;
2445+
}
24422446
}
24432447
}
24442448

test/ClangImporter/objc_bridging_generics.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ func testHashableGenerics(
413413
let _: Int = any.foo // expected-error{{cannot convert value of type 'Set<AnyHashable>' to specified type 'Int'}}
414414
let _: Int = constrained.foo // expected-error{{cannot convert value of type 'Set<ElementConcrete>' to specified type 'Int'}}
415415
let _: Int = insufficient.foo // expected-error{{cannot convert value of type 'Set<AnyHashable>' to specified type 'Int'}}
416-
let _: Int = extra.foo // expected-error{{cannot convert value of type 'Set<ElementConcrete>' to specified type 'Int'}}
416+
let _: Int = extra.foo // expected-error{{cannot convert value of type 'Set<AnyHashable>' to specified type 'Int'}}
417417
let _: Int = existential.foo // expected-error{{cannot convert value of type 'Set<AnyHashable>' to specified type 'Int'}}
418418
}
419419

0 commit comments

Comments
 (0)