Skip to content

Commit e91b305

Browse files
authored
Merge pull request #37154 from slavapestov/new-redundant-requirements-algorithm-part-2
GSB: New algorithm for computing redundant requirements
2 parents d7a89a7 + e45b566 commit e91b305

13 files changed

+826
-974
lines changed

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "swift/AST/TypeRepr.h"
3232
#include "swift/Basic/Debug.h"
3333
#include "swift/Basic/LLVM.h"
34+
#include "llvm/ADT/DenseSet.h"
3435
#include "llvm/ADT/FoldingSet.h"
3536
#include "llvm/ADT/ilist.h"
3637
#include "llvm/ADT/PointerUnion.h"
@@ -654,11 +655,44 @@ class GenericSignatureBuilder {
654655
bool isRedundantExplicitRequirement(const ExplicitRequirement &req) const;
655656

656657
private:
657-
void computeRedundantRequirements(const ProtocolDecl *requirementSignatureSelfProto);
658+
using GetKindAndRHS = llvm::function_ref<std::pair<RequirementKind, RequirementRHS>()>;
659+
void getBaseRequirements(
660+
GetKindAndRHS getKindAndRHS,
661+
const RequirementSource *source,
662+
const ProtocolDecl *requirementSignatureSelfProto,
663+
SmallVectorImpl<ExplicitRequirement> &result);
664+
665+
/// Determine if an explicit requirement can be derived from the
666+
/// requirement given by \p otherSource and \p otherRHS, using the
667+
/// knowledge of any existing redundant requirements discovered so far.
668+
Optional<ExplicitRequirement>
669+
isValidRequirementDerivationPath(
670+
llvm::SmallDenseSet<ExplicitRequirement, 4> &visited,
671+
RequirementKind otherKind,
672+
const RequirementSource *otherSource,
673+
RequirementRHS otherRHS,
674+
const ProtocolDecl *requirementSignatureSelfProto);
675+
676+
/// Determine if the explicit requirement \p req can be derived from any
677+
/// of the constraints in \p constraints, using the knowledge of any
678+
/// existing redundant requirements discovered so far.
679+
///
680+
/// Use \p filter to screen out less-specific and conflicting constraints
681+
/// if the requirement is a superclass, concrete type or layout requirement.
682+
template<typename T, typename Filter>
683+
void checkIfRequirementCanBeDerived(
684+
const ExplicitRequirement &req,
685+
const std::vector<Constraint<T>> &constraints,
686+
const ProtocolDecl *requirementSignatureSelfProto,
687+
Filter filter);
688+
689+
void computeRedundantRequirements(
690+
const ProtocolDecl *requirementSignatureSelfProto);
658691

659692
void diagnoseRedundantRequirements() const;
660693

661-
void diagnoseConflictingConcreteTypeRequirements() const;
694+
void diagnoseConflictingConcreteTypeRequirements(
695+
const ProtocolDecl *requirementSignatureSelfProto);
662696

663697
/// Describes the relationship between a given constraint and
664698
/// the canonical constraint of the equivalence class.
@@ -707,23 +741,6 @@ class GenericSignatureBuilder {
707741
TypeArrayView<GenericTypeParamType> genericParams,
708742
EquivalenceClass *equivClass);
709743

710-
/// Check the superclass constraints within the equivalence
711-
/// class of the given potential archetype.
712-
void checkSuperclassConstraints(
713-
TypeArrayView<GenericTypeParamType> genericParams,
714-
EquivalenceClass *equivClass);
715-
716-
/// Check conformance constraints within the equivalence class of the
717-
/// given potential archetype.
718-
void checkConformanceConstraints(
719-
TypeArrayView<GenericTypeParamType> genericParams,
720-
EquivalenceClass *equivClass);
721-
722-
/// Check layout constraints within the equivalence class of the given
723-
/// potential archetype.
724-
void checkLayoutConstraints(TypeArrayView<GenericTypeParamType> genericParams,
725-
EquivalenceClass *equivClass);
726-
727744
/// Check same-type constraints within the equivalence class of the
728745
/// given potential archetype.
729746
void checkSameTypeConstraints(
@@ -1242,8 +1259,7 @@ class GenericSignatureBuilder::RequirementSource final
12421259
/// requirement redundant, because without said original requirement, the
12431260
/// derived requirement ceases to hold.
12441261
bool isSelfDerivedSource(GenericSignatureBuilder &builder,
1245-
Type type,
1246-
bool &derivedViaConcrete) const;
1262+
Type type) const;
12471263

12481264
/// For a requirement source that describes the requirement \c type:proto,
12491265
/// retrieve the minimal subpath of this requirement source that will
@@ -1255,8 +1271,7 @@ class GenericSignatureBuilder::RequirementSource final
12551271
const RequirementSource *getMinimalConformanceSource(
12561272
GenericSignatureBuilder &builder,
12571273
Type type,
1258-
ProtocolDecl *proto,
1259-
bool &derivedViaConcrete) const;
1274+
ProtocolDecl *proto) const;
12601275

12611276
/// Retrieve a source location that corresponds to the requirement.
12621277
SourceLoc getLoc() const;

include/swift/Basic/Statistics.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,13 @@ FRONTEND_STATISTIC(Sema, NumAccessorBodiesSynthesized)
224224
/// amount of work the GSB does analyzing type signatures.
225225
FRONTEND_STATISTIC(Sema, NumGenericSignatureBuilders)
226226

227+
/// Number of steps in the GSB's redundant requirements algorithm, which is in
228+
/// the worst-case exponential.
229+
FRONTEND_STATISTIC(Sema, NumRedundantRequirementSteps)
230+
231+
/// Number of conformance access paths we had to compute.
232+
FRONTEND_STATISTIC(Sema, NumConformanceAccessPathsRecorded)
233+
227234
/// Number of lazy requirement signatures registered.
228235
FRONTEND_STATISTIC(Sema, NumLazyRequirementSignatures)
229236

0 commit comments

Comments
 (0)