Skip to content

Commit 3639343

Browse files
authored
[Serialization] Distinguish between protocol/extension for types too. (swiftlang#7794)
Replace an existing flag for cross-references to member types (that wasn't getting much use) with one consistent with how we lookup values. This fixes the case where someone actually has a useful type as a member of a protocol extension, and that type gets referenced in another module; Dispatch does exactly this. Because you can currently only define typealiases in protocol extensions, not new types, there's always a workaround for someone hitting this issue: just use the underlying type. https://bugs.swift.org/browse/SR-4076
1 parent 48c10aa commit 3639343

File tree

6 files changed

+14
-10
lines changed

6 files changed

+14
-10
lines changed

include/swift/Serialization/ModuleFormat.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0;
5454
/// in source control, you should also update the comment to briefly
5555
/// describe what change you made. The content of this comment isn't important;
5656
/// it just ensures a conflict if two people change the module format.
57-
const uint16_t VERSION_MINOR = 320; // Last change: inherited protocols
57+
const uint16_t VERSION_MINOR = 321; // Last change: restrict to extension
5858

5959
using DeclID = PointerEmbeddedInt<unsigned, 31>;
6060
using DeclIDField = BCFixed<31>;
@@ -1181,7 +1181,7 @@ namespace decls_block {
11811181
using XRefTypePathPieceLayout = BCRecordLayout<
11821182
XREF_TYPE_PATH_PIECE,
11831183
IdentifierIDField, // name
1184-
BCFixed<1> // only in nominal
1184+
BCFixed<1> // restrict to protocol extension
11851185
>;
11861186

11871187
using XRefValuePathPieceLayout = BCRecordLayout<

lib/Serialization/Deserialization.cpp

+3-5
Original file line numberDiff line numberDiff line change
@@ -1321,11 +1321,10 @@ Decl *ModuleFile::resolveCrossReference(ModuleDecl *baseModule,
13211321
IdentifierID IID;
13221322
TypeID TID = 0;
13231323
bool isType = (recordID == XREF_TYPE_PATH_PIECE);
1324-
bool onlyInNominal = false;
13251324
bool inProtocolExt = false;
13261325
bool isStatic = false;
13271326
if (isType)
1328-
XRefTypePathPieceLayout::readRecord(scratch, IID, onlyInNominal);
1327+
XRefTypePathPieceLayout::readRecord(scratch, IID, inProtocolExt);
13291328
else
13301329
XRefValuePathPieceLayout::readRecord(scratch, TID, IID, inProtocolExt,
13311330
isStatic);
@@ -1496,13 +1495,12 @@ Decl *ModuleFile::resolveCrossReference(ModuleDecl *baseModule,
14961495
Identifier memberName;
14971496
Optional<swift::CtorInitializerKind> ctorInit;
14981497
bool isType = false;
1499-
bool onlyInNominal = false;
15001498
bool inProtocolExt = false;
15011499
bool isStatic = false;
15021500
switch (recordID) {
15031501
case XREF_TYPE_PATH_PIECE: {
15041502
IdentifierID IID;
1505-
XRefTypePathPieceLayout::readRecord(scratch, IID, onlyInNominal);
1503+
XRefTypePathPieceLayout::readRecord(scratch, IID, inProtocolExt);
15061504
memberName = getIdentifier(IID);
15071505
isType = true;
15081506
break;
@@ -1548,7 +1546,7 @@ Decl *ModuleFile::resolveCrossReference(ModuleDecl *baseModule,
15481546
return nullptr;
15491547
}
15501548

1551-
auto members = nominal->lookupDirect(memberName, onlyInNominal);
1549+
auto members = nominal->lookupDirect(memberName);
15521550
values.append(members.begin(), members.end());
15531551
filterValues(filterTy, M, genericSig, isType, inProtocolExt, isStatic,
15541552
ctorInit, values);

lib/Serialization/Serialization.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -1803,18 +1803,17 @@ void Serializer::writeCrossReference(const Decl *D) {
18031803
return;
18041804
}
18051805

1806+
bool isProtocolExt = D->getDeclContext()->getAsProtocolExtensionContext();
18061807
if (auto type = dyn_cast<TypeDecl>(D)) {
18071808
abbrCode = DeclTypeAbbrCodes[XRefTypePathPieceLayout::Code];
18081809
XRefTypePathPieceLayout::emitRecord(Out, ScratchRecord, abbrCode,
18091810
addIdentifierRef(type->getName()),
1810-
isa<ProtocolDecl>(
1811-
type->getDeclContext()));
1811+
isProtocolExt);
18121812
return;
18131813
}
18141814

18151815
auto val = cast<ValueDecl>(D);
18161816
auto ty = val->getInterfaceType()->getCanonicalType();
1817-
bool isProtocolExt = D->getDeclContext()->getAsProtocolExtensionContext();
18181817
abbrCode = DeclTypeAbbrCodes[XRefValuePathPieceLayout::Code];
18191818
XRefValuePathPieceLayout::emitRecord(Out, ScratchRecord, abbrCode,
18201819
addTypeRef(ty),

test/Serialization/Inputs/alias.swift

+5
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,8 @@ public struct Base {
2626
}
2727
}
2828
public typealias BaseAlias = Base
29+
30+
public protocol ProtoWrapper {}
31+
extension ProtoWrapper {
32+
public typealias Boolean = Bool
33+
}

test/Serialization/Inputs/has_xref.swift

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import has_alias
33

44
public func numeric(_ x: MyInt64) {}
55
public func conditional(_ x: AliasWrapper.Boolean) {}
6+
public func conditional2(_ x: ProtoWrapper.Boolean) {}
67
public func longInt(_ x: Int.EspeciallyMagicalInt) {}
78

89
public func numericArray(_ x: IntSlice) {}

test/Serialization/xref.swift

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import has_xref
1414

1515
numeric(42)
1616
conditional(true)
17+
conditional2(true)
1718
longInt(42)
1819
numericArray([42])
1920

0 commit comments

Comments
 (0)