@@ -7722,11 +7722,69 @@ void swift::printEnumElementsAsCases(
7722
7722
OS << " : " << getCodePlaceholder () << " \n " ;
7723
7723
});
7724
7724
}
7725
+ // / For a protocol, don't consult getInherited() at all. Instead, rebuild
7726
+ // / the inherited types from getInheritedProtocols(), getSuperclass(), and
7727
+ // / the inverse requirement transform.
7728
+ // /
7729
+ // / FIXME: This seems generally useful and should be moved elsewhere.
7730
+ static void getSyntacticInheritanceClause (const ProtocolDecl *proto,
7731
+ llvm::SmallVectorImpl<InheritedEntry> &Results) {
7732
+ auto &ctx = proto->getASTContext ();
7733
+
7734
+ if (auto superclassTy = proto->getSuperclass ()) {
7735
+ Results.emplace_back (TypeLoc::withoutLoc (superclassTy),
7736
+ /* isUnchecked=*/ false ,
7737
+ /* isRetroactive=*/ false ,
7738
+ /* isPreconcurrency=*/ false );
7739
+ }
7740
+
7741
+ InvertibleProtocolSet inverses = InvertibleProtocolSet::full ();
7742
+
7743
+ for (auto *inherited : proto->getInheritedProtocols ()) {
7744
+ if (ctx.LangOpts .hasFeature (Feature::NoncopyableGenerics)) {
7745
+ if (auto ip = inherited->getInvertibleProtocolKind ()) {
7746
+ inverses.remove (*ip);
7747
+ continue ;
7748
+ }
7749
+
7750
+ for (auto ip : InvertibleProtocolSet::full ()) {
7751
+ auto *proto = ctx.getProtocol (getKnownProtocolKind (ip));
7752
+ if (inherited->inheritsFrom (proto))
7753
+ inverses.remove (ip);
7754
+ }
7755
+ }
7756
+
7757
+ Results.emplace_back (TypeLoc::withoutLoc (inherited->getDeclaredInterfaceType ()),
7758
+ /* isUnchecked=*/ false ,
7759
+ /* isRetroactive=*/ false ,
7760
+ /* isPreconcurrency=*/ false );
7761
+ }
7762
+
7763
+ if (ctx.LangOpts .hasFeature (Feature::NoncopyableGenerics)) {
7764
+ for (auto ip : inverses) {
7765
+ InvertibleProtocolSet singleton;
7766
+ singleton.insert (ip);
7767
+
7768
+ auto inverseTy = ProtocolCompositionType::get (
7769
+ ctx, ArrayRef<Type>(), singleton,
7770
+ /* hasExplicitAnyObject=*/ false );
7771
+ Results.emplace_back (TypeLoc::withoutLoc (inverseTy),
7772
+ /* isUnchecked=*/ false ,
7773
+ /* isRetroactive=*/ false ,
7774
+ /* isPreconcurrency=*/ false );
7775
+ }
7776
+ }
7777
+ }
7725
7778
7726
7779
void
7727
7780
swift::getInheritedForPrinting (
7728
7781
const Decl *decl, const PrintOptions &options,
7729
7782
llvm::SmallVectorImpl<InheritedEntry> &Results) {
7783
+ if (auto *proto = dyn_cast<ProtocolDecl>(decl)) {
7784
+ getSyntacticInheritanceClause (proto, Results);
7785
+ return ;
7786
+ }
7787
+
7730
7788
InheritedTypes inherited = InheritedTypes (decl);
7731
7789
7732
7790
// Collect explicit inherited types.
@@ -7753,6 +7811,10 @@ swift::getInheritedForPrinting(
7753
7811
llvm::TinyPtrVector<ProtocolDecl *> uncheckedProtocols;
7754
7812
for (auto attr : decl->getAttrs ().getAttributes <SynthesizedProtocolAttr>()) {
7755
7813
if (auto *proto = attr->getProtocol ()) {
7814
+ // FIXME: Reconstitute inverses here
7815
+ if (proto->getInvertibleProtocolKind ())
7816
+ continue ;
7817
+
7756
7818
// The SerialExecutor conformance is only synthesized on the root
7757
7819
// actor class, so we can just test resilience immediately.
7758
7820
if (proto->isSpecificProtocol (KnownProtocolKind::SerialExecutor) &&
@@ -7788,6 +7850,10 @@ swift::getInheritedForPrinting(
7788
7850
continue ;
7789
7851
}
7790
7852
7853
+ // FIXME: Reconstitute inverses here
7854
+ if (proto->getInvertibleProtocolKind ())
7855
+ continue ;
7856
+
7791
7857
Results.push_back ({TypeLoc::withoutLoc (proto->getDeclaredInterfaceType ()),
7792
7858
isUnchecked,
7793
7859
/* isRetroactive=*/ false ,
0 commit comments