SILGen: Don't ask for context substitution map of existential

This commit is contained in:
Slava Pestov
2024-09-19 12:45:26 -04:00
parent abbc37e41d
commit 74b2b03565
2 changed files with 23 additions and 8 deletions

View File

@@ -4244,19 +4244,25 @@ SILGenModule::emitKeyPathComponentForDecl(SILLocation loc,
CanType componentTy;
if (!var->getDeclContext()->isTypeContext()) {
componentTy = var->getInterfaceType()->getCanonicalType();
} else if (var->getDeclContext()->getSelfProtocolDecl() &&
baseTy->isExistentialType()) {
componentTy = var->getValueInterfaceType()->getCanonicalType();
ASSERT(!componentTy->hasTypeParameter());
} else {
componentTy =
// The mapTypeIntoContext() / mapTypeOutOfContext() dance is there
// to handle the case where baseTy being a type parameter subject
// to a superclass requirement.
componentTy = var->getValueInterfaceType().subst(
GenericEnvironment::mapTypeIntoContext(genericEnv, baseTy)
->getTypeOfMember(var)
->getReferenceStorageReferent()
->getContextSubstitutionMap(var->getDeclContext()))
->mapTypeOutOfContext()
->getCanonicalType();
}
// The component type for an @objc optional requirement needs to be
// wrapped in an optional.
if (var->getAttrs().hasAttribute<OptionalAttr>()) {
componentTy = OptionalType::get(componentTy)->getCanonicalType();
}
// The component type for an @objc optional requirement needs to be
// wrapped in an optional.
if (var->getAttrs().hasAttribute<OptionalAttr>()) {
componentTy = OptionalType::get(componentTy)->getCanonicalType();
}
if (canStorageUseStoredKeyPathComponent(var, expansion)) {

View File

@@ -677,3 +677,12 @@ func test_optional_chaining_with_function_conversion() {
_ = data.compactMap(\.elements!.db)
}
}
protocol HasAlias {
var id: Self.ID { get }
typealias ID = Int
}
func testHasAlias() {
_ = \HasAlias.id
}