@@ -124,6 +124,8 @@ STATISTIC(NumRewriteRhsSimplifiedToLhs,
124124 " # of rewrite rule right-hand sides simplified to lhs (and removed)" );
125125STATISTIC (NumRewriteRulesRedundant,
126126 " # of rewrite rules that are redundant (and removed)" );
127+ STATISTIC (NumSignaturesRebuiltWithoutRedundantRequirements,
128+ " # of generic signatures which had a concretized conformance requirement" );
127129
128130namespace {
129131
@@ -616,6 +618,11 @@ class GenericSignatureBuilder::ExplicitRequirement {
616618
617619 return true ;
618620 }
621+
622+ friend bool operator !=(const ExplicitRequirement &lhs,
623+ const ExplicitRequirement &rhs) {
624+ return !(lhs == rhs);
625+ }
619626};
620627
621628namespace llvm {
@@ -690,8 +697,13 @@ struct GenericSignatureBuilder::Implementation {
690697 // / Whether there were any errors.
691698 bool HadAnyError = false ;
692699
693- // / The set of computed redundant explicit requirements.
694- llvm::DenseSet<ExplicitRequirement> RedundantRequirements;
700+ // / A mapping of redundant explicit requirements to the best root requirement
701+ // / that implies them.
702+ using RedundantRequirementMap =
703+ llvm::DenseMap<ExplicitRequirement,
704+ llvm::SmallDenseSet<ExplicitRequirement, 2 >>;
705+
706+ RedundantRequirementMap RedundantRequirements;
695707
696708#ifndef NDEBUG
697709 // / Whether we've already computed redundant requiremnts.
@@ -1865,7 +1877,6 @@ FloatingRequirementSource FloatingRequirementSource::asInferred(
18651877}
18661878
18671879bool FloatingRequirementSource::isRecursive (
1868- Type rootType,
18691880 GenericSignatureBuilder &builder) const {
18701881 llvm::SmallSet<std::pair<CanType, ProtocolDecl *>, 32 > visitedAssocReqs;
18711882 for (auto storedSource = storage.dyn_cast <const RequirementSource *>();
@@ -3983,12 +3994,12 @@ auto GenericSignatureBuilder::resolve(UnresolvedType paOrT,
39833994 return ResolvedType (pa);
39843995
39853996 // Determine what kind of resolution we want.
3986- Type type = paOrT.get <Type>();
39873997 ArchetypeResolutionKind resolutionKind =
39883998 ArchetypeResolutionKind::WellFormed;
3989- if (!source.isExplicit () && source.isRecursive (type, *this ))
3999+ if (!source.isExplicit () && source.isRecursive (*this ))
39904000 resolutionKind = ArchetypeResolutionKind::AlreadyKnown;
39914001
4002+ Type type = paOrT.get <Type>();
39924003 return maybeResolveEquivalenceClass (type, resolutionKind,
39934004 /* wantExactPotentialArchetype=*/ true );
39944005}
@@ -4636,7 +4647,7 @@ ConstraintResult GenericSignatureBuilder::addTypeRequirement(
46364647 unresolvedHandling);
46374648 }
46384649
4639- // If the resolved subject is a type , there may be things we can infer (if it
4650+ // If the resolved subject is concrete , there may be things we can infer (if it
46404651 // conditionally conforms to the protocol), and we can probably perform
46414652 // diagnostics here.
46424653 if (auto subjectType = resolvedSubject.getAsConcreteType ()) {
@@ -5625,8 +5636,8 @@ class RedundantRequirementGraph {
56255636
56265637 SmallVector<Vertex, 2 > vertices;
56275638
5628- ComponentID nextComponent = 0 ;
5629- VertexID nextIndex = 0 ;
5639+ ComponentID componentCount = 0 ;
5640+ VertexID vertexCount = 0 ;
56305641
56315642 SmallVector<VertexID, 2 > stack;
56325643
@@ -5785,11 +5796,11 @@ class RedundantRequirementGraph {
57855796 void strongConnect (VertexID v) {
57865797 // Set the depth index for v to the smallest unused index.
57875798 assert (vertices[v].index == Vertex::UndefinedIndex);
5788- vertices[v].index = nextIndex ;
5799+ vertices[v].index = vertexCount ;
57895800 assert (vertices[v].lowLink == Vertex::UndefinedIndex);
5790- vertices[v].lowLink = nextIndex ;
5801+ vertices[v].lowLink = vertexCount ;
57915802
5792- nextIndex ++;
5803+ vertexCount ++;
57935804
57945805 stack.push_back (v);
57955806 assert (!vertices[v].onStack );
@@ -5827,40 +5838,60 @@ class RedundantRequirementGraph {
58275838 vertices[w].onStack = false ;
58285839 assert (vertices[w].component == Vertex::UndefinedComponent);
58295840
5830- vertices[w].component = nextComponent ;
5841+ vertices[w].component = componentCount ;
58315842 } while (v != w);
58325843
5833- nextComponent ++;
5844+ componentCount ++;
58345845 }
58355846 }
58365847
58375848public:
5849+ using RedundantRequirementMap =
5850+ llvm::DenseMap<ExplicitRequirement,
5851+ llvm::SmallDenseSet<ExplicitRequirement, 2 >>;
5852+
58385853 void computeRedundantRequirements (SourceManager &SM,
5839- llvm::DenseSet<ExplicitRequirement> &redundant) {
5854+ RedundantRequirementMap &redundant) {
58405855 // First, compute SCCs.
58415856 computeSCCs ();
58425857
5843- // The number of edges from other connected components to this one.
5844- SmallVector<unsigned , 2 > inboundComponentEdges;
5845- inboundComponentEdges.resize (nextComponent);
5858+ // The set of edges pointing to each connected component.
5859+ SmallVector<SmallVector<ComponentID, 2 >, 2 > inboundComponentEdges;
5860+ inboundComponentEdges.resize (componentCount);
5861+
5862+ // The set of edges originating from this connected component.
5863+ SmallVector<SmallVector<ComponentID, 2 >, 2 > outboundComponentEdges;
5864+ outboundComponentEdges.resize (componentCount);
58465865
5847- // Visit all vertices and count inter-component edges.
5866+ // Visit all vertices and build the adjacency sets for the connected
5867+ // component graph.
58485868 for (const auto &vertex : vertices) {
58495869 assert (vertex.component != Vertex::UndefinedComponent);
58505870 for (auto successor : vertex.successors ) {
58515871 ComponentID otherComponent = vertices[successor].component ;
5852- if (vertex.component != otherComponent)
5853- ++inboundComponentEdges[otherComponent];
5872+ if (vertex.component != otherComponent) {
5873+ inboundComponentEdges[otherComponent].push_back (vertex.component );
5874+ outboundComponentEdges[vertex.component ].push_back (otherComponent);
5875+ }
58545876 }
58555877 }
58565878
5857- // The best explicit requirement for each root SCC.
5879+ auto isRootComponent = [&](ComponentID component) -> bool {
5880+ return inboundComponentEdges[component].empty ();
5881+ };
5882+
5883+ // The set of root components.
5884+ llvm::SmallDenseSet<ComponentID, 2 > rootComponents;
5885+
5886+ // The best explicit requirement for each root component.
58585887 SmallVector<Optional<ExplicitRequirement>, 2 > bestExplicitReq;
5859- bestExplicitReq.resize (nextComponent );
5888+ bestExplicitReq.resize (componentCount );
58605889
5861- // Visit all vertices and find the best requirement for each root SCC .
5890+ // Visit all vertices and find the best requirement for each root component .
58625891 for (const auto &vertex : vertices) {
5863- if (inboundComponentEdges[vertex.component ] == 0 ) {
5892+ if (isRootComponent (vertex.component )) {
5893+ rootComponents.insert (vertex.component );
5894+
58645895 // If this vertex is part of a root SCC, see if the requirement is
58655896 // better than the one we have so far.
58665897 auto &best = bestExplicitReq[vertex.component ];
@@ -5869,26 +5900,61 @@ class RedundantRequirementGraph {
58695900 }
58705901 }
58715902
5872- // Compute the set of redundant requirements.
5873- for (const auto &vertex : vertices) {
5874- if (inboundComponentEdges[vertex.component ] == 0 ) {
5875- // We have a root SCC. This requirement is redundant unless
5876- // it is the best requirement for this SCC.
5877- auto best = bestExplicitReq[vertex.component ];
5878- assert (best.hasValue () &&
5879- " Did not record best requirement for root SCC?" );
5903+ // The set of root components that each component is reachable from.
5904+ SmallVector<llvm::SmallDenseSet<ComponentID, 2 >, 2 > reachableFromRoot;
5905+ reachableFromRoot.resize (componentCount);
58805906
5881- if (vertex.req == *best)
5882- continue ;
5907+ // Traverse the graph of connected components starting from the roots.
5908+ for (auto rootComponent : rootComponents) {
5909+ SmallVector<ComponentID, 2 > worklist;
5910+
5911+ auto addToWorklist = [&](ComponentID nextComponent) {
5912+ if (!reachableFromRoot[nextComponent].count (rootComponent))
5913+ worklist.push_back (nextComponent);
5914+ };
5915+
5916+ addToWorklist (rootComponent);
5917+
5918+ while (!worklist.empty ()) {
5919+ auto component = worklist.back ();
5920+ worklist.pop_back ();
5921+
5922+ reachableFromRoot[component].insert (rootComponent);
5923+
5924+ for (auto nextComponent : outboundComponentEdges[component])
5925+ addToWorklist (nextComponent);
5926+ }
5927+ }
5928+
5929+ // Compute the mapping of redundant requirements to the best root
5930+ // requirement that implies them.
5931+ for (const auto &vertex : vertices) {
5932+ if (isRootComponent (vertex.component )) {
5933+ // A root component is reachable from itself, and itself only.
5934+ assert (reachableFromRoot[vertex.component ].size () == 1 );
5935+ assert (reachableFromRoot[vertex.component ].count (vertex.component ) == 1 );
58835936 } else {
5884- // We have a non-root SCC. This requirement is always
5885- // redundant.
58865937 assert (!bestExplicitReq[vertex.component ].hasValue () &&
58875938 " Recorded best requirement for non-root SCC?" );
58885939 }
58895940
5890- auto inserted = redundant.insert (vertex.req );
5891- assert (inserted.second && " Saw the same vertex twice?" );
5941+ // We have a non-root component. This requirement is always
5942+ // redundant.
5943+ auto reachableFromRootSet = reachableFromRoot[vertex.component ];
5944+ assert (reachableFromRootSet.size () > 0 );
5945+
5946+ for (auto rootComponent : reachableFromRootSet) {
5947+ assert (isRootComponent (rootComponent));
5948+
5949+ auto best = bestExplicitReq[rootComponent];
5950+ assert (best.hasValue () &&
5951+ " Did not record best requirement for root SCC?" );
5952+
5953+ assert (vertex.req != *best || vertex.component == rootComponent);
5954+ if (vertex.req != *best) {
5955+ redundant[vertex.req ].insert (*best);
5956+ }
5957+ }
58925958 }
58935959 }
58945960
@@ -8108,9 +8174,60 @@ static void checkGenericSignature(CanGenericSignature canSig,
81088174}
81098175#endif
81108176
8177+ bool GenericSignatureBuilder::hasExplicitConformancesImpliedByConcrete () const {
8178+ for (auto pair : Impl->RedundantRequirements ) {
8179+ if (pair.first .getKind () != RequirementKind::Conformance)
8180+ continue ;
8181+
8182+ for (auto impliedByReq : pair.second ) {
8183+ if (impliedByReq.getKind () == RequirementKind::Superclass)
8184+ return true ;
8185+
8186+ if (impliedByReq.getKind () == RequirementKind::SameType)
8187+ return true ;
8188+ }
8189+ }
8190+
8191+ return false ;
8192+ }
8193+
8194+ static Type stripBoundDependentMemberTypes (Type t) {
8195+ if (auto *depMemTy = t->getAs <DependentMemberType>()) {
8196+ return DependentMemberType::get (
8197+ stripBoundDependentMemberTypes (depMemTy->getBase ()),
8198+ depMemTy->getName ());
8199+ }
8200+
8201+ return t;
8202+ }
8203+
8204+ static Requirement stripBoundDependentMemberTypes (Requirement req) {
8205+ auto subjectType = stripBoundDependentMemberTypes (req.getFirstType ());
8206+
8207+ switch (req.getKind ()) {
8208+ case RequirementKind::Conformance:
8209+ return Requirement (RequirementKind::Conformance, subjectType,
8210+ req.getSecondType ());
8211+
8212+ case RequirementKind::Superclass:
8213+ case RequirementKind::SameType:
8214+ return Requirement (req.getKind (), subjectType,
8215+ req.getSecondType ().transform ([](Type t) {
8216+ return stripBoundDependentMemberTypes (t);
8217+ }));
8218+
8219+ case RequirementKind::Layout:
8220+ return Requirement (RequirementKind::Conformance, subjectType,
8221+ req.getLayoutConstraint ());
8222+ }
8223+
8224+ llvm_unreachable (" Bad requirement kind" );
8225+ }
8226+
81118227GenericSignature GenericSignatureBuilder::computeGenericSignature (
81128228 bool allowConcreteGenericParams,
8113- bool allowBuilderToMove) && {
8229+ bool buildingRequirementSignature,
8230+ bool rebuildingWithoutRedundantConformances) && {
81148231 // Finalize the builder, producing any necessary diagnostics.
81158232 finalize (getGenericParams (), allowConcreteGenericParams);
81168233
@@ -8121,6 +8238,43 @@ GenericSignature GenericSignatureBuilder::computeGenericSignature(
81218238 // Form the generic signature.
81228239 auto sig = GenericSignature::get (getGenericParams (), requirements);
81238240
8241+ // If any of our explicit conformance requirements were implied by
8242+ // superclass or concrete same-type requirements, we have to build the
8243+ // signature again, since dropping the redundant conformance requirements
8244+ // changes the canonical type computation.
8245+ //
8246+ // However, if we already diagnosed an error, don't do this, because
8247+ // we might end up emitting duplicate diagnostics.
8248+ //
8249+ // Also, don't do this when building a requirement signature.
8250+ if (!buildingRequirementSignature &&
8251+ !Impl->HadAnyError &&
8252+ hasExplicitConformancesImpliedByConcrete ()) {
8253+ NumSignaturesRebuiltWithoutRedundantRequirements++;
8254+
8255+ if (rebuildingWithoutRedundantConformances) {
8256+ llvm::errs () << " Rebuilt signature still has "
8257+ << " redundant conformance requirements: " ;
8258+ llvm::errs () << sig << " \n " ;
8259+ abort ();
8260+ }
8261+
8262+ GenericSignatureBuilder newBuilder (Context);
8263+
8264+ for (auto param : sig->getGenericParams ())
8265+ newBuilder.addGenericParameter (param);
8266+
8267+ for (auto &req : sig->getRequirements ()) {
8268+ newBuilder.addRequirement (stripBoundDependentMemberTypes (req),
8269+ FloatingRequirementSource::forAbstract (), nullptr );
8270+ }
8271+
8272+ return std::move (newBuilder).computeGenericSignature (
8273+ allowConcreteGenericParams,
8274+ buildingRequirementSignature,
8275+ /* rebuildingWithoutRedundantConformances=*/ true );
8276+ }
8277+
81248278#ifndef NDEBUG
81258279 if (!Impl->HadAnyError ) {
81268280 checkGenericSignature (sig.getCanonicalSignature (), *this );
@@ -8132,7 +8286,9 @@ GenericSignature GenericSignatureBuilder::computeGenericSignature(
81328286 // will produce the same thing.
81338287 //
81348288 // We cannot do this when there were errors.
8135- if (allowBuilderToMove && !Impl->HadAnyError ) {
8289+ //
8290+ // Also, we cannot do this when building a requirement signature.
8291+ if (!buildingRequirementSignature && !Impl->HadAnyError ) {
81368292 // Register this generic signature builder as the canonical builder for the
81378293 // given signature.
81388294 Context.registerGenericSignatureBuilder (sig, std::move (*this ));
0 commit comments