[NCGenerics] fix Combine issue

The solution is to add the unconditional conformances when building the
conformance lookup table for each nominal, instead of waiting until
conformance lookup infers it.

At the moment, because the stdlib isn't being built with Copyable
conformances injected into it, we still end up needing to infer Copyable
conformances for nominals like `Int` from the stdlib when trying to test
the feature, since it loads those nominals, but they lack conformance.

That should go away once we do enable NoncopyableGenerics for the stdlib
by default, and we'll be left with only inferring the conditional
conformance in TypeCheckInvertible.
This commit is contained in:
Kavon Farvardin
2024-01-18 18:20:47 -08:00
parent 58480c3be1
commit c7c9d80520
3 changed files with 32 additions and 3 deletions

View File

@@ -23,6 +23,7 @@
#include "swift/AST/FileUnit.h"
#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/InFlightSubstitution.h"
#include "swift/AST/InverseMarking.h"
#include "swift/AST/LazyResolver.h"
#include "swift/AST/Module.h"
#include "swift/AST/PackConformance.h"
@@ -1091,6 +1092,16 @@ void NominalTypeDecl::prepareConformanceTable() const {
}
};
// Synthesize the unconditional conformances to invertible protocols.
// For conditional ones, see findSynthesizedConformances .
if (haveNoncopyableGenerics) {
for (auto ip : InvertibleProtocolSet::full()) {
auto invertible = getMarking(ip);
if (!invertible.getInverse() || bool(invertible.getPositive()))
addSynthesized(ctx.getProtocol(getKnownProtocolKind(ip)));
}
}
// Add protocols for any synthesized protocol attributes.
for (auto attr : getAttrs().getAttributes<SynthesizedProtocolAttr>()) {
addSynthesized(attr->getProtocol());
@@ -1263,9 +1274,12 @@ static SmallVector<ProtocolConformance *, 2> findSynthesizedConformances(
if (!isa<ProtocolDecl>(nominal)) {
trySynthesize(KnownProtocolKind::Sendable);
if (nominal->getASTContext().LangOpts.hasFeature(Feature::NoncopyableGenerics)) {
trySynthesize(KnownProtocolKind::Copyable);
trySynthesize(KnownProtocolKind::Escapable);
// Triggers synthesis of a possibly conditional conformance.
// For the unconditional ones, see NominalTypeDecl::prepareConformanceTable
if (nominal->getASTContext().LangOpts.hasFeature(
Feature::NoncopyableGenerics)) {
for (auto ip : InvertibleProtocolSet::full())
trySynthesize(getKnownProtocolKind(ip));
}
if (nominal->getASTContext().LangOpts.hasFeature(