mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
NCGenerics: break cycle with SuperclassTypeRequest
With NoncopyableGenerics, we get a cycle involving
`SuperclassTypeRequest` with this program:
public struct RawMarkupHeader {}
final class RawMarkup: ManagedBuffer<RawMarkupHeader, RawMarkup> { }
Because we generally don't support the following kind of relationship:
class Base<T: P>: P {}
class Derived: Base<Derived> {}
This commit works around the root-cause, which is that Derived's
synthesized conformance to Copyable gets superceded by the inherited one
from Base. Instead of recording conformances in the ConformanceLookup
table at all, create builtin conformances on the fly, since classes
cannot be conditionally Copyable or Escapable.
This commit is contained in:
@@ -102,9 +102,10 @@ switch (getKind()) { \
|
||||
return cast<NormalProtocolConformance>(this)->Method Args; \
|
||||
case ProtocolConformanceKind::Self: \
|
||||
return cast<SelfProtocolConformance>(this)->Method Args; \
|
||||
case ProtocolConformanceKind::Builtin: \
|
||||
return cast<BuiltinProtocolConformance>(this)->Method Args; \
|
||||
case ProtocolConformanceKind::Specialized: \
|
||||
case ProtocolConformanceKind::Inherited: \
|
||||
case ProtocolConformanceKind::Builtin: \
|
||||
llvm_unreachable("not a root conformance"); \
|
||||
} \
|
||||
llvm_unreachable("bad ProtocolConformanceKind");
|
||||
@@ -1090,19 +1091,21 @@ void NominalTypeDecl::prepareConformanceTable() const {
|
||||
// Synthesize the unconditional conformances to invertible protocols.
|
||||
// For conditional ones, see findSynthesizedConformances .
|
||||
if (ctx.LangOpts.hasFeature(Feature::NoncopyableGenerics)) {
|
||||
bool missingOne = false;
|
||||
for (auto ip : InvertibleProtocolSet::full()) {
|
||||
auto invertible = getMarking(ip);
|
||||
if (!invertible.getInverse() || bool(invertible.getPositive()))
|
||||
addSynthesized(ctx.getProtocol(getKnownProtocolKind(ip)));
|
||||
else
|
||||
missingOne = true;
|
||||
// Classes get their conformances during ModuleDecl::lookupConformance.
|
||||
if (!isa<ClassDecl>(this)) {
|
||||
bool missingOne = false;
|
||||
for (auto ip : InvertibleProtocolSet::full()) {
|
||||
auto invertible = getMarking(ip);
|
||||
if (!invertible.getInverse() || bool(invertible.getPositive()))
|
||||
addSynthesized(ctx.getProtocol(getKnownProtocolKind(ip)));
|
||||
else
|
||||
missingOne = true;
|
||||
}
|
||||
|
||||
// FIXME: rdar://122289155 (NCGenerics: convert Equatable, Hashable, and RawRepresentable to ~Copyable.)
|
||||
if (missingOne)
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: rdar://122289155 (NCGenerics: convert Equatable, Hashable, and RawRepresentable to ~Copyable.)
|
||||
if (missingOne)
|
||||
return;
|
||||
|
||||
} else if (!canBeCopyable()) {
|
||||
return; // No synthesized conformances for move-only nominals.
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user