Skip to content

Commit 76e5166

Browse files
authored
[Serialization] Mark decls that can never be cross-referenced (#17302)
This allows us to filter them out in cases that would otherwise be ambiguous. The particular prompting situation looks a lot like the test case: a protocol, plus a forward-declared class with the same name. (Normally we ignore forward-declared classes, but SourceKit's module interface generation feature makes dummy ClassDecls for them instead.) https://bugs.swift.org/browse/SR-4851 (cherry picked from commit 05d0a2d)
1 parent aeb7826 commit 76e5166

File tree

9 files changed

+35
-0
lines changed

9 files changed

+35
-0
lines changed

include/swift/AST/Attr.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,11 @@ SIMPLE_DECL_ATTR(_weakLinked, WeakLinked,
348348

349349
SIMPLE_DECL_ATTR(_frozen, Frozen, OnEnum | UserInaccessible, 76)
350350

351+
SIMPLE_DECL_ATTR(_forbidSerializingReference, ForbidSerializingReference,
352+
OnAnyDecl |
353+
LongAttribute | RejectByParser | UserInaccessible | NotSerialized,
354+
77)
355+
351356
#undef TYPE_ATTR
352357
#undef DECL_ATTR_ALIAS
353358
#undef CONTEXTUAL_DECL_ATTR_ALIAS

lib/ClangImporter/ImportDecl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4617,6 +4617,8 @@ namespace {
46174617
"This Objective-C class has only been forward-declared; "
46184618
"import its owning module to use it");
46194619
result->getAttrs().add(attr);
4620+
result->getAttrs().add(
4621+
new (Impl.SwiftContext) ForbidSerializingReferenceAttr(true));
46204622
return result;
46214623
}
46224624

lib/Sema/TypeCheckAttr.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class AttributeEarlyChecker : public AttributeVisitor<AttributeEarlyChecker> {
8080
IGNORED_ATTR(Effects)
8181
IGNORED_ATTR(Exported)
8282
IGNORED_ATTR(FixedLayout)
83+
IGNORED_ATTR(ForbidSerializingReference)
8384
IGNORED_ATTR(Frozen)
8485
IGNORED_ATTR(Implements)
8586
IGNORED_ATTR(ImplicitlyUnwrappedOptional)
@@ -804,6 +805,7 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
804805
IGNORED_ATTR(Dynamic)
805806
IGNORED_ATTR(Effects)
806807
IGNORED_ATTR(Exported)
808+
IGNORED_ATTR(ForbidSerializingReference)
807809
IGNORED_ATTR(GKInspectable)
808810
IGNORED_ATTR(IBDesignable)
809811
IGNORED_ATTR(IBInspectable)

lib/Sema/TypeCheckDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5717,6 +5717,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
57175717
UNINTERESTING_ATTR(DynamicMemberLookup)
57185718
UNINTERESTING_ATTR(SILGenName)
57195719
UNINTERESTING_ATTR(Exported)
5720+
UNINTERESTING_ATTR(ForbidSerializingReference)
57205721
UNINTERESTING_ATTR(GKInspectable)
57215722
UNINTERESTING_ATTR(IBAction)
57225723
UNINTERESTING_ATTR(IBDesignable)

lib/Serialization/Deserialization.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,6 +1198,10 @@ static void filterValues(Type expectedTy, ModuleDecl *expectedModule,
11981198
return true;
11991199
if (value->isStatic() != isStatic)
12001200
return true;
1201+
1202+
if (value->getAttrs().hasAttribute<ForbidSerializingReferenceAttr>())
1203+
return true;
1204+
12011205
// FIXME: Should be able to move a value from an extension in a derived
12021206
// module to the original definition in a base module.
12031207
if (expectedModule && !value->hasClangNode() &&

lib/Serialization/Serialization.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,10 @@ DeclID Serializer::addDeclRef(const Decl *D, bool forceSerialization,
609609
isa<PrecedenceGroupDecl>(D)) &&
610610
"cannot cross-reference this decl");
611611

612+
assert((!isDeclXRef(D) ||
613+
!D->getAttrs().hasAttribute<ForbidSerializingReferenceAttr>()) &&
614+
"cannot cross-reference this decl");
615+
612616
assert((allowTypeAliasXRef || !isa<TypeAliasDecl>(D) ||
613617
D->getModuleContext() == M) &&
614618
"cannot cross-reference typealiases directly (use the NameAliasType)");
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@class Confusing;
2+
3+
@protocol Confusing
4+
@end

test/ClangImporter/Inputs/custom-modules/module.map

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,7 @@ module Warnings6 { header "Warnings6.h" }
212212
module Warnings7 { header "Warnings7.h" }
213213
module Warnings8 { header "Warnings8.h" }
214214
module Warnings9 { header "Warnings9.h" }
215+
216+
module ForwardDeclarationsHelper {
217+
header "ForwardDeclarationsHelper.h"
218+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-module -o %t -I %S/Inputs/custom-modules -enable-objc-interop %s
3+
// RUN: %target-swift-ide-test -print-module -module-to-print objc_forward_declarations -I %t -I %S/Inputs/custom-modules -enable-objc-interop -enable-objc-forward-declarations -source-filename x | %FileCheck %s
4+
5+
// CHECK: class Innocuous : Confusing {
6+
7+
import ForwardDeclarationsHelper
8+
9+
public class Innocuous: Confusing {}

0 commit comments

Comments
 (0)