Skip to content

Commit d0dc64e

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 9084682 commit d0dc64e

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
@@ -2443,9 +2443,13 @@ bool ClangImporter::Implementation::matchesHashableBound(Type type) {
24432443
// Match generic parameters against their bounds.
24442444
if (auto *genericTy = type->getAs<GenericTypeParamType>()) {
24452445
if (auto *generic = genericTy->getDecl()) {
2446-
type = generic->getSuperclass();
2447-
if (!type)
2448-
return false;
2446+
auto genericSig =
2447+
generic->getDeclContext()->getGenericSignatureOfContext();
2448+
if (genericSig && genericSig->getConformsTo(type).empty()) {
2449+
type = genericSig->getSuperclassBound(type);
2450+
if (!type)
2451+
return false;
2452+
}
24492453
}
24502454
}
24512455

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)