[Serialization] Distinguish between protocol/extension for types too. (#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
This commit is contained in:
Jordan Rose
2017-02-28 10:36:46 -08:00
committed by GitHub
parent 48c10aa00b
commit 3639343c53
6 changed files with 14 additions and 10 deletions

View File

@@ -54,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0;
/// in source control, you should also update the comment to briefly /// in source control, you should also update the comment to briefly
/// describe what change you made. The content of this comment isn't important; /// describe what change you made. The content of this comment isn't important;
/// it just ensures a conflict if two people change the module format. /// it just ensures a conflict if two people change the module format.
const uint16_t VERSION_MINOR = 320; // Last change: inherited protocols const uint16_t VERSION_MINOR = 321; // Last change: restrict to extension
using DeclID = PointerEmbeddedInt<unsigned, 31>; using DeclID = PointerEmbeddedInt<unsigned, 31>;
using DeclIDField = BCFixed<31>; using DeclIDField = BCFixed<31>;
@@ -1181,7 +1181,7 @@ namespace decls_block {
using XRefTypePathPieceLayout = BCRecordLayout< using XRefTypePathPieceLayout = BCRecordLayout<
XREF_TYPE_PATH_PIECE, XREF_TYPE_PATH_PIECE,
IdentifierIDField, // name IdentifierIDField, // name
BCFixed<1> // only in nominal BCFixed<1> // restrict to protocol extension
>; >;
using XRefValuePathPieceLayout = BCRecordLayout< using XRefValuePathPieceLayout = BCRecordLayout<

View File

@@ -1321,11 +1321,10 @@ Decl *ModuleFile::resolveCrossReference(ModuleDecl *baseModule,
IdentifierID IID; IdentifierID IID;
TypeID TID = 0; TypeID TID = 0;
bool isType = (recordID == XREF_TYPE_PATH_PIECE); bool isType = (recordID == XREF_TYPE_PATH_PIECE);
bool onlyInNominal = false;
bool inProtocolExt = false; bool inProtocolExt = false;
bool isStatic = false; bool isStatic = false;
if (isType) if (isType)
XRefTypePathPieceLayout::readRecord(scratch, IID, onlyInNominal); XRefTypePathPieceLayout::readRecord(scratch, IID, inProtocolExt);
else else
XRefValuePathPieceLayout::readRecord(scratch, TID, IID, inProtocolExt, XRefValuePathPieceLayout::readRecord(scratch, TID, IID, inProtocolExt,
isStatic); isStatic);
@@ -1496,13 +1495,12 @@ Decl *ModuleFile::resolveCrossReference(ModuleDecl *baseModule,
Identifier memberName; Identifier memberName;
Optional<swift::CtorInitializerKind> ctorInit; Optional<swift::CtorInitializerKind> ctorInit;
bool isType = false; bool isType = false;
bool onlyInNominal = false;
bool inProtocolExt = false; bool inProtocolExt = false;
bool isStatic = false; bool isStatic = false;
switch (recordID) { switch (recordID) {
case XREF_TYPE_PATH_PIECE: { case XREF_TYPE_PATH_PIECE: {
IdentifierID IID; IdentifierID IID;
XRefTypePathPieceLayout::readRecord(scratch, IID, onlyInNominal); XRefTypePathPieceLayout::readRecord(scratch, IID, inProtocolExt);
memberName = getIdentifier(IID); memberName = getIdentifier(IID);
isType = true; isType = true;
break; break;
@@ -1548,7 +1546,7 @@ Decl *ModuleFile::resolveCrossReference(ModuleDecl *baseModule,
return nullptr; return nullptr;
} }
auto members = nominal->lookupDirect(memberName, onlyInNominal); auto members = nominal->lookupDirect(memberName);
values.append(members.begin(), members.end()); values.append(members.begin(), members.end());
filterValues(filterTy, M, genericSig, isType, inProtocolExt, isStatic, filterValues(filterTy, M, genericSig, isType, inProtocolExt, isStatic,
ctorInit, values); ctorInit, values);

View File

@@ -1803,18 +1803,17 @@ void Serializer::writeCrossReference(const Decl *D) {
return; return;
} }
bool isProtocolExt = D->getDeclContext()->getAsProtocolExtensionContext();
if (auto type = dyn_cast<TypeDecl>(D)) { if (auto type = dyn_cast<TypeDecl>(D)) {
abbrCode = DeclTypeAbbrCodes[XRefTypePathPieceLayout::Code]; abbrCode = DeclTypeAbbrCodes[XRefTypePathPieceLayout::Code];
XRefTypePathPieceLayout::emitRecord(Out, ScratchRecord, abbrCode, XRefTypePathPieceLayout::emitRecord(Out, ScratchRecord, abbrCode,
addIdentifierRef(type->getName()), addIdentifierRef(type->getName()),
isa<ProtocolDecl>( isProtocolExt);
type->getDeclContext()));
return; return;
} }
auto val = cast<ValueDecl>(D); auto val = cast<ValueDecl>(D);
auto ty = val->getInterfaceType()->getCanonicalType(); auto ty = val->getInterfaceType()->getCanonicalType();
bool isProtocolExt = D->getDeclContext()->getAsProtocolExtensionContext();
abbrCode = DeclTypeAbbrCodes[XRefValuePathPieceLayout::Code]; abbrCode = DeclTypeAbbrCodes[XRefValuePathPieceLayout::Code];
XRefValuePathPieceLayout::emitRecord(Out, ScratchRecord, abbrCode, XRefValuePathPieceLayout::emitRecord(Out, ScratchRecord, abbrCode,
addTypeRef(ty), addTypeRef(ty),

View File

@@ -26,3 +26,8 @@ public struct Base {
} }
} }
public typealias BaseAlias = Base public typealias BaseAlias = Base
public protocol ProtoWrapper {}
extension ProtoWrapper {
public typealias Boolean = Bool
}

View File

@@ -3,6 +3,7 @@ import has_alias
public func numeric(_ x: MyInt64) {} public func numeric(_ x: MyInt64) {}
public func conditional(_ x: AliasWrapper.Boolean) {} public func conditional(_ x: AliasWrapper.Boolean) {}
public func conditional2(_ x: ProtoWrapper.Boolean) {}
public func longInt(_ x: Int.EspeciallyMagicalInt) {} public func longInt(_ x: Int.EspeciallyMagicalInt) {}
public func numericArray(_ x: IntSlice) {} public func numericArray(_ x: IntSlice) {}

View File

@@ -14,6 +14,7 @@ import has_xref
numeric(42) numeric(42)
conditional(true) conditional(true)
conditional2(true)
longInt(42) longInt(42)
numericArray([42]) numericArray([42])