Skip to content

Commit 05d0a2d

Browse files
authored
[Serialization] Mark decls that can never be cross-referenced (#17223)
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
1 parent c16d9ce commit 05d0a2d

File tree

9 files changed

+34
-0
lines changed

9 files changed

+34
-0
lines changed

include/swift/AST/Attr.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,10 @@ SIMPLE_DECL_ATTR(_frozen, Frozen,
373373
OnEnum |
374374
UserInaccessible,
375375
76)
376+
SIMPLE_DECL_ATTR(_forbidSerializingReference, ForbidSerializingReference,
377+
OnAnyDecl |
378+
LongAttribute | RejectByParser | UserInaccessible | NotSerialized,
379+
77)
376380

377381
#undef TYPE_ATTR
378382
#undef DECL_ATTR_ALIAS

lib/ClangImporter/ImportDecl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4621,6 +4621,8 @@ namespace {
46214621
"This Objective-C class has only been forward-declared; "
46224622
"import its owning module to use it");
46234623
result->getAttrs().add(attr);
4624+
result->getAttrs().add(
4625+
new (Impl.SwiftContext) ForbidSerializingReferenceAttr(true));
46244626
return result;
46254627
}
46264628

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)
@@ -805,6 +806,7 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
805806
IGNORED_ATTR(Dynamic)
806807
IGNORED_ATTR(Effects)
807808
IGNORED_ATTR(Exported)
809+
IGNORED_ATTR(ForbidSerializingReference)
808810
IGNORED_ATTR(GKInspectable)
809811
IGNORED_ATTR(IBDesignable)
810812
IGNORED_ATTR(IBInspectable)

lib/Sema/TypeCheckDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5813,6 +5813,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
58135813
UNINTERESTING_ATTR(DynamicMemberLookup)
58145814
UNINTERESTING_ATTR(SILGenName)
58155815
UNINTERESTING_ATTR(Exported)
5816+
UNINTERESTING_ATTR(ForbidSerializingReference)
58165817
UNINTERESTING_ATTR(GKInspectable)
58175818
UNINTERESTING_ATTR(IBAction)
58185819
UNINTERESTING_ATTR(IBDesignable)

lib/Serialization/Deserialization.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,6 +1226,10 @@ static void filterValues(Type expectedTy, ModuleDecl *expectedModule,
12261226
return true;
12271227
if (value->isStatic() != isStatic)
12281228
return true;
1229+
1230+
if (value->getAttrs().hasAttribute<ForbidSerializingReferenceAttr>())
1231+
return true;
1232+
12291233
// FIXME: Should be able to move a value from an extension in a derived
12301234
// module to the original definition in a base module.
12311235
if (expectedModule && !value->hasClangNode() &&

lib/Serialization/Serialization.cpp

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

606+
assert((!isDeclXRef(D) ||
607+
!D->getAttrs().hasAttribute<ForbidSerializingReferenceAttr>()) &&
608+
"cannot cross-reference this decl");
609+
606610
assert((allowTypeAliasXRef || !isa<TypeAliasDecl>(D) ||
607611
D->getModuleContext() == M) &&
608612
"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
@@ -216,4 +216,8 @@ module Warnings9 { header "Warnings9.h" }
216216
module ConditionallyFoo {
217217
header "ConditionallyFoo.h"
218218
config_macros [exhaustive] WANT_FOO
219+
}
220+
221+
module ForwardDeclarationsHelper {
222+
header "ForwardDeclarationsHelper.h"
219223
}
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)