Skip to content

Commit d61c21b

Browse files
authored
Merge pull request #80304 from slavapestov/not-so-abstract-anymore
AST: Check subject type in ProtocolConformanceRef::forAbstract()
2 parents 09a4e16 + cc05e1e commit d61c21b

File tree

3 files changed

+30
-19
lines changed

3 files changed

+30
-19
lines changed

lib/AST/ASTContext.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5748,10 +5748,28 @@ ProtocolConformanceRef ProtocolConformanceRef::forAbstract(
57485748
Type conformingType, ProtocolDecl *proto) {
57495749
ASTContext &ctx = proto->getASTContext();
57505750

5751+
auto kind = conformingType->getDesugaredType()->getKind();
5752+
switch (kind) {
5753+
case TypeKind::GenericTypeParam:
5754+
case TypeKind::TypeVariable:
5755+
case TypeKind::DependentMember:
5756+
case TypeKind::Unresolved:
5757+
case TypeKind::Placeholder:
5758+
case TypeKind::PrimaryArchetype:
5759+
case TypeKind::PackArchetype:
5760+
case TypeKind::OpaqueTypeArchetype:
5761+
case TypeKind::ExistentialArchetype:
5762+
case TypeKind::ElementArchetype:
5763+
break;
5764+
5765+
default:
5766+
llvm::errs() << "Abstract conformance with bad subject type:\n";
5767+
conformingType->dump(llvm::errs());
5768+
abort();
5769+
}
5770+
57515771
// Figure out which arena this should go in.
5752-
RecursiveTypeProperties properties;
5753-
if (conformingType)
5754-
properties |= conformingType->getRecursiveProperties();
5772+
auto properties = conformingType->getRecursiveProperties();
57555773
auto arena = getArena(properties);
57565774

57575775
// Form the folding set key.

lib/AST/ProtocolConformanceRef.cpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,8 @@ bool ProtocolConformanceRef::isCanonical() const {
312312
if (isPack())
313313
return getPack()->isCanonical();
314314

315-
if (isAbstract()) {
316-
Type conformingType = getType();
317-
return !conformingType || conformingType->isCanonical();
318-
}
315+
if (isAbstract())
316+
return getType()->isCanonical();
319317

320318
return getConcrete()->isCanonical();
321319
}
@@ -328,12 +326,8 @@ ProtocolConformanceRef::getCanonicalConformanceRef() const {
328326
if (isPack())
329327
return ProtocolConformanceRef(getPack()->getCanonicalConformance());
330328

331-
if (isAbstract()) {
332-
Type conformingType = getType();
333-
if (conformingType)
334-
conformingType = conformingType->getCanonicalType();
335-
return forAbstract(conformingType, getProtocol());
336-
}
329+
if (isAbstract())
330+
return forAbstract(getType()->getCanonicalType(), getProtocol());
337331

338332
return ProtocolConformanceRef(getConcrete()->getCanonicalConformance());
339333
}

lib/AST/TypeSubstitution.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,18 +136,17 @@ operator()(CanType dependentType, Type conformingReplacementType,
136136
PackConformance::get(conformingPack, conformedProtocol, conformances));
137137
}
138138

139-
assert((conformingReplacementType->is<ErrorType>() ||
140-
conformingReplacementType->is<SubstitutableType>() ||
141-
conformingReplacementType->is<DependentMemberType>() ||
142-
conformingReplacementType->hasTypeVariable()) &&
143-
"replacement requires looking up a concrete conformance");
139+
if (conformingReplacementType->is<ErrorType>())
140+
return ProtocolConformanceRef::forInvalid();
141+
144142
// A class-constrained archetype might conform to the protocol
145143
// concretely.
146144
if (auto *archetypeType = conformingReplacementType->getAs<ArchetypeType>()) {
147-
if (auto superclassType = archetypeType->getSuperclass()) {
145+
if (archetypeType->getSuperclass()) {
148146
return lookupConformance(archetypeType, conformedProtocol);
149147
}
150148
}
149+
151150
return ProtocolConformanceRef::forAbstract(
152151
conformingReplacementType, conformedProtocol);
153152
}

0 commit comments

Comments
 (0)