mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[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:
@@ -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<
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -26,3 +26,8 @@ public struct Base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public typealias BaseAlias = Base
|
public typealias BaseAlias = Base
|
||||||
|
|
||||||
|
public protocol ProtoWrapper {}
|
||||||
|
extension ProtoWrapper {
|
||||||
|
public typealias Boolean = Bool
|
||||||
|
}
|
||||||
|
|||||||
@@ -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) {}
|
||||||
|
|||||||
@@ -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])
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user