//===--- RequirementMachine.h - Generics with term rewriting ----*- C++ -*-===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2021 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// #ifndef SWIFT_REQUIREMENTMACHINE_H #define SWIFT_REQUIREMENTMACHINE_H #include "swift/AST/GenericSignature.h" #include "llvm/ADT/DenseMap.h" #include #include "PropertyMap.h" #include "RewriteContext.h" #include "RewriteSystem.h" namespace llvm { class raw_ostream; } namespace swift { class AbstractGenericSignatureRequestRQM; class ASTContext; class AssociatedTypeDecl; class CanType; class GenericTypeParamType; class InferredGenericSignatureRequestRQM; class LayoutConstraint; class ProtocolDecl; class Requirement; class Type; class UnifiedStatsReporter; namespace rewriting { class RewriteContext; /// Wraps a rewrite system with higher-level operations in terms of /// generic signatures and interface types. class RequirementMachine final { friend class swift::ASTContext; friend class swift::rewriting::RewriteContext; friend class swift::AbstractGenericSignatureRequestRQM; friend class swift::InferredGenericSignatureRequestRQM; CanGenericSignature Sig; SmallVector Params; ArrayRef Protos; RewriteContext &Context; RewriteSystem System; PropertyMap Map; bool Dump = false; bool Complete = false; unsigned RequirementMachineStepLimit; unsigned RequirementMachineDepthLimit; UnifiedStatsReporter *Stats; /// All conformance access paths computed so far. llvm::DenseMap, ConformanceAccessPath> ConformanceAccessPaths; /// Conformance access paths computed during the last round. All elements /// have the same length. If a conformance access path of greater length /// is requested, we refill CurrentConformanceAccessPaths with all paths of /// length N+1, and add them to the ConformanceAccessPaths map. std::vector> CurrentConformanceAccessPaths; explicit RequirementMachine(RewriteContext &rewriteCtx); RequirementMachine(const RequirementMachine &) = delete; RequirementMachine(RequirementMachine &&) = delete; RequirementMachine &operator=(const RequirementMachine &) = delete; RequirementMachine &operator=(RequirementMachine &&) = delete; void initWithGenericSignature(CanGenericSignature sig); void initWithProtocols(ArrayRef protos); void initWithAbstractRequirements( ArrayRef genericParams, ArrayRef requirements); void initWithWrittenRequirements( ArrayRef genericParams, ArrayRef requirements); bool isComplete() const; void computeCompletion(RewriteSystem::ValidityPolicy policy); MutableTerm getLongestValidPrefix(const MutableTerm &term) const; std::vector buildRequirementsFromRules( ArrayRef rules, TypeArrayView genericParams) const; TypeArrayView getGenericParams() const { return TypeArrayView( ArrayRef(Params)); } public: ~RequirementMachine(); // Generic signature queries. Generally you shouldn't have to construct a // RequirementMachine instance; instead, call the corresponding methods on // GenericSignature, which lazily create a RequirementMachine for you. GenericSignature::LocalRequirements getLocalRequirements(Type depType, TypeArrayView genericParams) const; bool requiresClass(Type depType) const; LayoutConstraint getLayoutConstraint(Type depType) const; bool requiresProtocol(Type depType, const ProtocolDecl *proto) const; GenericSignature::RequiredProtocols getRequiredProtocols(Type depType) const; Type getSuperclassBound(Type depType, TypeArrayView genericParams) const; bool isConcreteType(Type depType) const; Type getConcreteType(Type depType, TypeArrayView genericParams) const; bool areSameTypeParameterInContext(Type depType1, Type depType2) const; bool isCanonicalTypeInContext(Type type) const; Type getCanonicalTypeInContext(Type type, TypeArrayView genericParams) const; ConformanceAccessPath getConformanceAccessPath(Type type, ProtocolDecl *protocol); TypeDecl *lookupNestedType(Type depType, Identifier name) const; llvm::DenseMap> computeMinimalProtocolRequirements(); std::vector computeMinimalGenericSignatureRequirements(); bool hadError() const; void verify(const MutableTerm &term) const; void dump(llvm::raw_ostream &out) const; DebugOptions getDebugOptions() const { return Context.getDebugOptions(); } }; } // end namespace rewriting } // end namespace swift #endif