Skip to content

Commit 943290e

Browse files
authored
[Serialization] Drop extensions whose requirements are missing types (#17526)
If, for whatever reason, a type used in an extension's generic requirements is missing, just drop the whole extension. This isn't wonderful recovery, but in practice nothing should be able to use the extension anyway, since the relevant type in question is missing. ...Okay, that's not quite true; there could, for example, be inlinable code that references one of these methods. However, that (1) isn't worse than the behavior for any other inlinable code (which doesn't yet attempt to recover from missing declarations), and (2) is still a strict improvement over the current situation, where we will eagerly abort the compiler trying to load the extension in the first place. rdar://problem/40956460 (cherry picked from commit 7f33f47)
1 parent ff74d8c commit 943290e

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

lib/Serialization/Serialization.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2725,10 +2725,12 @@ void Serializer::writeDecl(const Decl *D) {
27252725
inheritedAndDependencyTypes.push_back(addTypeRef(inherited.getType()));
27262726
size_t numInherited = inheritedAndDependencyTypes.size();
27272727

2728-
// FIXME: Figure out what to do with requirements and such, which the
2729-
// extension also depends on. Right now just do what is safe to drop, which
2730-
// is the base declaration.
2731-
auto dependencies = collectDependenciesFromType(baseTy);
2728+
llvm::SmallSetVector<Type, 4> dependencies;
2729+
collectDependenciesFromType(dependencies, baseTy, /*excluding*/nullptr);
2730+
for (Requirement req : extension->getGenericRequirements()) {
2731+
collectDependenciesFromRequirement(dependencies, req,
2732+
/*excluding*/nullptr);
2733+
}
27322734
for (auto dependencyTy : dependencies)
27332735
inheritedAndDependencyTypes.push_back(addTypeRef(dependencyTy));
27342736

test/Serialization/Recovery/type-removal-objc.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,15 @@ public unowned(unsafe) var someUnownedUnsafeObject: Base = Base()
4343
// CHECK-DAG: weak var someWeakObject: @sil_weak Base
4444
// CHECK-RECOVERY-NEGATIVE-NOT: var someWeakObject:
4545
public weak var someWeakObject: Base? = nil
46+
47+
// CHECK-DAG: struct GenericStruct<T>
48+
// CHECK-RECOVERY-DAG: struct GenericStruct<T>
49+
struct GenericStruct<T> {}
50+
51+
// CHECK-DAG: extension GenericStruct where T : SomeProto
52+
// CHECK-RECOVERY-NEGATIVE-NOT: extension GenericStruct{{.*}}SomeProto
53+
extension GenericStruct where T: SomeProto {
54+
// CHECK-DAG: func someOperation
55+
// CHECK-RECOVERY-NEGATIVE-NOT: someOperation
56+
func someOperation() {}
57+
}

0 commit comments

Comments
 (0)