Skip to content

Commit a7fa469

Browse files
committed
[GenericSignature] Don't allow conformance requirements with explicit
existential types.
1 parent 6cee193 commit a7fa469

File tree

6 files changed

+29
-9
lines changed

6 files changed

+29
-9
lines changed

lib/AST/ASTContext.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -5000,24 +5000,26 @@ CanGenericSignature ASTContext::getSingleGenericParameterSignature() const {
50005000
// constraints while existential values do.
50015001
CanGenericSignature ASTContext::getOpenedArchetypeSignature(Type type) {
50025002
assert(type->isExistentialType());
5003+
if (auto existential = type->getAs<ExistentialType>())
5004+
type = existential->getConstraintType();
50035005

5004-
const CanType existential = type->getCanonicalType();
5006+
const CanType constraint = type->getCanonicalType();
50055007

50065008
// The opened archetype signature for a protocol type is identical
50075009
// to the protocol's own canonical generic signature.
5008-
if (const auto protoTy = dyn_cast<ProtocolType>(existential)) {
5010+
if (const auto protoTy = dyn_cast<ProtocolType>(constraint)) {
50095011
return protoTy->getDecl()->getGenericSignature().getCanonicalSignature();
50105012
}
50115013

5012-
auto found = getImpl().ExistentialSignatures.find(existential);
5014+
auto found = getImpl().ExistentialSignatures.find(constraint);
50135015
if (found != getImpl().ExistentialSignatures.end())
50145016
return found->second;
50155017

50165018
auto genericParam =
50175019
GenericTypeParamType::get(/*type sequence*/ false,
50185020
/*depth*/ 0, /*index*/ 0, *this);
50195021
Requirement requirement(RequirementKind::Conformance, genericParam,
5020-
existential);
5022+
constraint);
50215023
auto genericSig = buildGenericSignature(*this,
50225024
GenericSignature(),
50235025
{genericParam},
@@ -5026,7 +5028,7 @@ CanGenericSignature ASTContext::getOpenedArchetypeSignature(Type type) {
50265028
CanGenericSignature canGenericSig(genericSig);
50275029

50285030
auto result = getImpl().ExistentialSignatures.insert(
5029-
std::make_pair(existential, canGenericSig));
5031+
std::make_pair(constraint, canGenericSig));
50305032
assert(result.second);
50315033
(void) result;
50325034

lib/AST/GenericSignatureBuilder.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -4500,7 +4500,8 @@ ConstraintResult GenericSignatureBuilder::addTypeRequirement(
45004500
}
45014501

45024502
// Check whether we have a reasonable constraint type at all.
4503-
if (!constraintType->isExistentialType() &&
4503+
if (!constraintType->is<ProtocolType>() &&
4504+
!constraintType->is<ProtocolCompositionType>() &&
45044505
!constraintType->getClassOrBoundGenericClass()) {
45054506
if (source.getLoc().isValid() && !constraintType->hasError()) {
45064507
Impl->HadAnyError = true;

lib/SILGen/SILGenPoly.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -3052,8 +3052,13 @@ buildThunkSignature(SILGenFunction &SGF,
30523052
// Add a new generic parameter to replace the opened existential.
30533053
auto *newGenericParam =
30543054
GenericTypeParamType::get(/*type sequence*/ false, depth, 0, ctx);
3055+
3056+
auto constraint = openedExistential->getOpenedExistentialType();
3057+
if (auto existential = constraint->getAs<ExistentialType>())
3058+
constraint = existential->getConstraintType();
3059+
30553060
Requirement newRequirement(RequirementKind::Conformance, newGenericParam,
3056-
openedExistential->getOpenedExistentialType());
3061+
constraint);
30573062

30583063
auto genericSig = buildGenericSignature(ctx, baseGenericSig,
30593064
{ newGenericParam },

lib/SILOptimizer/Differentiation/Thunk.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,13 @@ CanGenericSignature buildThunkSignature(SILFunction *fn, bool inheritGenericSig,
6666
// Add a new generic parameter to replace the opened existential.
6767
auto *newGenericParam =
6868
GenericTypeParamType::get(/*type sequence*/ false, depth, 0, ctx);
69+
70+
auto constraint = openedExistential->getOpenedExistentialType();
71+
if (auto existential = constraint->getAs<ExistentialType>())
72+
constraint = existential->getConstraintType();
73+
6974
Requirement newRequirement(RequirementKind::Conformance, newGenericParam,
70-
openedExistential->getOpenedExistentialType());
75+
constraint);
7176

7277
auto genericSig = buildGenericSignature(ctx, baseGenericSig,
7378
{ newGenericParam },

lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -304,12 +304,17 @@ void ExistentialTransform::convertExistentialArgTypesToGenericArgTypes(
304304
auto &param = params[Idx];
305305
auto PType = param.getArgumentType(M, FTy, F->getTypeExpansionContext());
306306
assert(PType.isExistentialType());
307+
308+
CanType constraint = PType;
309+
if (auto existential = PType->getAs<ExistentialType>())
310+
constraint = existential->getConstraintType()->getCanonicalType();
311+
307312
/// Generate new generic parameter.
308313
auto *NewGenericParam =
309314
GenericTypeParamType::get(/*type sequence*/ false, Depth, GPIdx++, Ctx);
310315
genericParams.push_back(NewGenericParam);
311316
Requirement NewRequirement(RequirementKind::Conformance, NewGenericParam,
312-
PType);
317+
constraint);
313318
requirements.push_back(NewRequirement);
314319
ArgToGenericTypeMap.insert(
315320
std::pair<int, GenericTypeParamType *>(Idx, NewGenericParam));

test/type/explicit_existential.swift

+2
Original file line numberDiff line numberDiff line change
@@ -162,3 +162,5 @@ func testMetatypes() {
162162
let _: any P1.Type = ConcreteComposition.self
163163
let _: any (P1 & P2).Type = ConcreteComposition.self
164164
}
165+
166+
func generic<T: any P1>(_ t: T) {} // expected-error {{type 'T' constrained to non-protocol, non-class type 'any P1'}}

0 commit comments

Comments
 (0)