Skip to content

Commit 5a546ed

Browse files
authored
Merge pull request #72762 from slavapestov/fix-rdar125460667
Sema: Fix existential-metatype-to-Any conversion
2 parents 3ea6ee2 + 32dab83 commit 5a546ed

File tree

7 files changed

+52
-59
lines changed

7 files changed

+52
-59
lines changed

include/swift/AST/Type.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -126,17 +126,6 @@ class MakeAbstractConformanceForGenericType {
126126
ProtocolDecl *conformedProtocol) const;
127127
};
128128

129-
/// Functor class suitable for use as a \c LookupConformanceFn that provides
130-
/// only abstract conformances, or builtin conformances for invertible protocols
131-
/// for generic types. Asserts that the replacement
132-
/// type is an opaque generic type.
133-
class MakeAbstractOrBuiltinConformanceForGenericType {
134-
public:
135-
ProtocolConformanceRef operator()(CanType dependentType,
136-
Type conformingReplacementType,
137-
ProtocolDecl *conformedProtocol) const;
138-
};
139-
140129
/// Functor class suitable for use as a \c LookupConformanceFn that fetches
141130
/// conformances from a generic signature.
142131
class LookUpConformanceInSignature {

include/swift/SIL/SILCloner.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
196196
// If we found a type containing a local archetype, substitute
197197
// open existentials throughout the substitution map.
198198
Subs = Subs.subst(QueryTypeSubstitutionMapOrIdentity{LocalArchetypeSubs},
199-
MakeAbstractOrBuiltinConformanceForGenericType());
199+
MakeAbstractConformanceForGenericType());
200200
}
201201
}
202202

@@ -219,7 +219,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
219219
return Ty.subst(
220220
Builder.getModule(),
221221
QueryTypeSubstitutionMapOrIdentity{LocalArchetypeSubs},
222-
MakeAbstractOrBuiltinConformanceForGenericType(),
222+
MakeAbstractConformanceForGenericType(),
223223
CanGenericSignature());
224224
}
225225
SILType getOpType(SILType Ty) {
@@ -239,7 +239,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
239239

240240
return ty.subst(
241241
QueryTypeSubstitutionMapOrIdentity{LocalArchetypeSubs},
242-
MakeAbstractOrBuiltinConformanceForGenericType()
242+
MakeAbstractConformanceForGenericType()
243243
)->getCanonicalType();
244244
}
245245

@@ -352,7 +352,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
352352
conformance.subst(ty,
353353
QueryTypeSubstitutionMapOrIdentity{
354354
LocalArchetypeSubs},
355-
MakeAbstractOrBuiltinConformanceForGenericType());
355+
MakeAbstractConformanceForGenericType());
356356
}
357357

358358
return asImpl().remapConformance(getASTTypeInClonedContext(ty),

lib/AST/TypeSubstitution.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -230,22 +230,6 @@ operator()(CanType dependentType, Type conformingReplacementType,
230230
return Subs.lookupConformance(dependentType, conformedProtocol);
231231
}
232232

233-
ProtocolConformanceRef MakeAbstractOrBuiltinConformanceForGenericType::
234-
operator()(CanType dependentType, Type conformingReplacementType,
235-
ProtocolDecl *conformedProtocol) const {
236-
// Workaround for rdar://125460667
237-
if (conformedProtocol->getInvertibleProtocolKind()) {
238-
auto &ctx = conformedProtocol->getASTContext();
239-
return ProtocolConformanceRef(
240-
ctx.getBuiltinConformance(conformingReplacementType, conformedProtocol,
241-
BuiltinConformanceKind::Synthesized));
242-
}
243-
244-
return MakeAbstractConformanceForGenericType()(dependentType,
245-
conformingReplacementType,
246-
conformedProtocol);
247-
}
248-
249233
ProtocolConformanceRef MakeAbstractConformanceForGenericType::
250234
operator()(CanType dependentType, Type conformingReplacementType,
251235
ProtocolDecl *conformedProtocol) const {

lib/SIL/IR/SILInstructions.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2185,14 +2185,24 @@ ObjCMethodInst::create(SILDebugLocation DebugLoc, SILValue Operand,
21852185
Member, Ty);
21862186
}
21872187

2188+
static void checkExistentialPreconditions(SILType ExistentialType,
2189+
CanType ConcreteType,
2190+
ArrayRef<ProtocolConformanceRef> Conformances) {
2191+
#ifndef NDEBUG
2192+
auto layout = ExistentialType.getASTType().getExistentialLayout();
2193+
assert(layout.getProtocols().size() == Conformances.size());
2194+
2195+
for (auto conformance : Conformances) {
2196+
assert(!conformance.isAbstract() || isa<ArchetypeType>(ConcreteType));
2197+
}
2198+
#endif
2199+
}
2200+
21882201
InitExistentialAddrInst *InitExistentialAddrInst::create(
21892202
SILDebugLocation Loc, SILValue Existential, CanType ConcreteType,
21902203
SILType ConcreteLoweredType, ArrayRef<ProtocolConformanceRef> Conformances,
21912204
SILFunction *F) {
2192-
#ifndef NDEBUG
2193-
auto layout = Existential->getType().getASTType().getExistentialLayout();
2194-
assert(layout.getProtocols().size() == Conformances.size());
2195-
#endif
2205+
checkExistentialPreconditions(Existential->getType(), ConcreteType, Conformances);
21962206

21972207
SILModule &Mod = F->getModule();
21982208
SmallVector<SILValue, 8> TypeDependentOperands;
@@ -2212,10 +2222,7 @@ InitExistentialValueInst *InitExistentialValueInst::create(
22122222
SILDebugLocation Loc, SILType ExistentialType, CanType ConcreteType,
22132223
SILValue Instance, ArrayRef<ProtocolConformanceRef> Conformances,
22142224
SILFunction *F) {
2215-
#ifndef NDEBUG
2216-
auto layout = ExistentialType.getASTType().getExistentialLayout();
2217-
assert(layout.getProtocols().size() == Conformances.size());
2218-
#endif
2225+
checkExistentialPreconditions(ExistentialType, ConcreteType, Conformances);
22192226

22202227
SILModule &Mod = F->getModule();
22212228
SmallVector<SILValue, 8> TypeDependentOperands;
@@ -2233,10 +2240,7 @@ InitExistentialRefInst *InitExistentialRefInst::create(
22332240
SILDebugLocation Loc, SILType ExistentialType, CanType ConcreteType,
22342241
SILValue Instance, ArrayRef<ProtocolConformanceRef> Conformances,
22352242
SILFunction *F, ValueOwnershipKind forwardingOwnershipKind) {
2236-
#ifndef NDEBUG
2237-
auto layout = ExistentialType.getASTType().getExistentialLayout();
2238-
assert(layout.getProtocols().size() == Conformances.size());
2239-
#endif
2243+
checkExistentialPreconditions(ExistentialType, ConcreteType, Conformances);
22402244

22412245
SILModule &Mod = F->getModule();
22422246
SmallVector<SILValue, 8> TypeDependentOperands;

lib/SILGen/SILGenConvert.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -853,9 +853,6 @@ ManagedValue SILGenFunction::emitExistentialErasure(
853853
[&, concreteFormalType, F](SGFContext C) -> ManagedValue {
854854
auto concreteValue = F(SGFContext());
855855
assert(concreteFormalType->isBridgeableObjectType());
856-
auto *M = SGM.M.getSwiftModule();
857-
auto conformances = M->collectExistentialConformances(
858-
concreteFormalType, anyObjectTy);
859856
return B.createInitExistentialRef(
860857
loc, SILType::getPrimitiveObjectType(anyObjectTy), concreteFormalType,
861858
concreteValue, conformances);
@@ -864,6 +861,12 @@ ManagedValue SILGenFunction::emitExistentialErasure(
864861
if (this->F.getLoweredFunctionType()->isPseudogeneric()) {
865862
if (anyObjectTy && concreteFormalType->is<ArchetypeType>()) {
866863
concreteFormalType = anyObjectTy;
864+
865+
// The original conformances are no good because they have the wrong
866+
// (pseudogeneric) subject type.
867+
auto *M = SGM.M.getSwiftModule();
868+
conformances = M->collectExistentialConformances(
869+
concreteFormalType, anyObjectTy);
867870
F = eraseToAnyObject;
868871
}
869872
}

lib/Sema/CSApply.cpp

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6688,13 +6688,24 @@ Expr *ExprRewriter::coerceExistential(Expr *expr, Type toType,
66886688
Type fromInstanceType = fromType;
66896689
Type toInstanceType = toType;
66906690

6691-
// Look through metatypes
6691+
// For existential-to-existential coercions, open the source existential.
6692+
Type openedFromType;
6693+
if (fromType->isAnyExistentialType()) {
6694+
openedFromType = OpenedArchetypeType::getAny(fromType->getCanonicalType(),
6695+
dc->getGenericSignatureOfContext());
6696+
}
6697+
6698+
Type openedFromInstanceType = openedFromType;
6699+
6700+
// Look through metatypes.
66926701
while ((fromInstanceType->is<UnresolvedType>() ||
66936702
fromInstanceType->is<AnyMetatypeType>()) &&
66946703
toInstanceType->is<ExistentialMetatypeType>()) {
66956704
if (!fromInstanceType->is<UnresolvedType>())
6696-
fromInstanceType = fromInstanceType->castTo<AnyMetatypeType>()->getInstanceType();
6697-
toInstanceType = toInstanceType->castTo<ExistentialMetatypeType>()->getExistentialInstanceType();
6705+
fromInstanceType = fromInstanceType->getMetatypeInstanceType();
6706+
if (openedFromInstanceType && !openedFromInstanceType->is<UnresolvedType>())
6707+
openedFromInstanceType = openedFromInstanceType->getMetatypeInstanceType();
6708+
toInstanceType = toInstanceType->getMetatypeInstanceType();
66986709
}
66996710

67006711
ASTContext &ctx = cs.getASTContext();
@@ -6758,20 +6769,13 @@ Expr *ExprRewriter::coerceExistential(Expr *expr, Type toType,
67586769
}
67596770

67606771
// For existential-to-existential coercions, open the source existential.
6761-
if (fromType->isAnyExistentialType()) {
6762-
fromType = OpenedArchetypeType::getAny(fromType->getCanonicalType(),
6763-
dc->getGenericSignatureOfContext());
6764-
6772+
if (openedFromType) {
67656773
auto *archetypeVal = cs.cacheType(
6766-
new (ctx) OpaqueValueExpr(expr->getSourceRange(), fromType));
6767-
6768-
fromInstanceType = fromType;
6769-
while (auto *metatypeType = fromInstanceType->getAs<MetatypeType>())
6770-
fromInstanceType = metatypeType->getInstanceType();
6774+
new (ctx) OpaqueValueExpr(expr->getSourceRange(), openedFromType));
67716775

67726776
auto conformances =
67736777
dc->getParentModule()
6774-
->collectExistentialConformances(fromInstanceType->getCanonicalType(),
6778+
->collectExistentialConformances(openedFromInstanceType->getCanonicalType(),
67756779
toInstanceType->getCanonicalType(),
67766780
/*allowMissing=*/true);
67776781

test/SILOptimizer/rdar125460667.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %target-swift-frontend -emit-sil %s
2+
3+
@_transparent func f(a: Any.Type) -> Any {
4+
return a
5+
}
6+
7+
func g(a: Any.Type) {
8+
f(a: a)
9+
}

0 commit comments

Comments
 (0)