Skip to content

Commit 730603a

Browse files
committed
Provide a version of getTypeLinkage that works.
Smaller values of FormalLinkage are actually wider scopes, so std::min'ing with PublicUnique actually just gives you a result that's always PublicUnique. And we need to start with PublicNonUnique because even things derived solely from uniquely-emitted types are not themselves generally unique. I don't want to immediately open the can of worms that fixing this for everyone would entail, so I'm just adding the new version in parallel and moving new clients to it gradually.
1 parent 03ac6b2 commit 730603a

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

include/swift/SIL/FormalLinkage.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ enum class FormalLinkage {
4545

4646
FormalLinkage getDeclLinkage(const ValueDecl *decl);
4747
FormalLinkage getTypeLinkage(CanType formalType);
48+
FormalLinkage getTypeLinkage_correct(CanType formalType);
4849
FormalLinkage getGenericSignatureLinkage(CanGenericSignature signature);
4950
SILLinkage getSILLinkage(FormalLinkage linkage,
5051
ForDefinition_t forDefinition);

lib/SIL/IR/SIL.cpp

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,10 @@ bool SILModule::isTypeMetadataAccessible(CanType type) {
148148
}
149149

150150
/// Return the formal linkage of the component restrictions of this
151-
/// generic signature. Never returns PublicUnique.
151+
/// generic signature. This is the appropriate linkage for a lazily-
152+
/// emitted entity derived from the generic signature.
153+
///
154+
/// This function never returns PublicUnique.
152155
FormalLinkage swift::getGenericSignatureLinkage(CanGenericSignature sig) {
153156
// This can only be PublicNonUnique or HiddenUnique. Signatures can
154157
// never be PublicUnique in the first place, and we short-circuit on
@@ -166,7 +169,7 @@ FormalLinkage swift::getGenericSignatureLinkage(CanGenericSignature sig) {
166169
case RequirementKind::Conformance:
167170
case RequirementKind::SameType:
168171
case RequirementKind::Superclass:
169-
switch (getTypeLinkage(CanType(req.getSecondType()))) {
172+
switch (getTypeLinkage_correct(CanType(req.getSecondType()))) {
170173
case FormalLinkage::PublicUnique:
171174
case FormalLinkage::PublicNonUnique:
172175
continue;
@@ -183,22 +186,43 @@ FormalLinkage swift::getGenericSignatureLinkage(CanGenericSignature sig) {
183186
return linkage;
184187
}
185188

186-
/// Return the minimum linkage structurally required to reference the given formal type.
189+
/// Return the formal linkage of the given formal type.
190+
///
191+
/// Note that this function is buggy and generally should not be
192+
/// used in new code; we should migrate all callers to
193+
/// getTypeLinkage_correct and then consolidate them.
187194
FormalLinkage swift::getTypeLinkage(CanType t) {
188195
assert(t->isLegalFormalType());
196+
// Due to a bug, this always returns PublicUnique.
197+
// It's a bit late in the 5.7 timeline to be changing that, but
198+
// we can optimize it!
199+
return FormalLinkage::PublicUnique;
200+
}
201+
202+
/// Return the formal linkage of the given formal type.
203+
/// This in the appropriate linkage for a lazily-emitted entity
204+
/// derived from the type.
205+
///
206+
/// This function never returns PublicUnique, which means that,
207+
/// even if a type is simply a reference to a non-generic
208+
/// uniquely-emitted nominal type, the formal linkage of that
209+
/// type may differ from the formal linkage of the underlying
210+
/// type declaration.
211+
FormalLinkage swift::getTypeLinkage_correct(CanType t) {
212+
assert(t->isLegalFormalType());
189213

190214
class Walker : public TypeWalker {
191215
public:
192216
FormalLinkage Linkage;
193-
Walker() : Linkage(FormalLinkage::PublicUnique) {}
217+
Walker() : Linkage(FormalLinkage::PublicNonUnique) {}
194218

195219
Action walkToTypePre(Type ty) override {
196220
// Non-nominal types are always available.
197221
auto decl = ty->getNominalOrBoundGenericNominal();
198222
if (!decl)
199223
return Action::Continue;
200224

201-
Linkage = std::min(Linkage, getDeclLinkage(decl));
225+
Linkage = std::max(Linkage, getDeclLinkage(decl));
202226
return Action::Continue;
203227
}
204228
};

0 commit comments

Comments
 (0)