| //===--- RequirementEnvironment.h - Requirement Environments ----*- C++ -*-===// |
| // |
| // This source file is part of the Swift.org open source project |
| // |
| // Copyright (c) 2014 - 2017 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 |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file defines the RequirementEnvironment class, which is used to |
| // capture how a witness to a protocol requirement maps type parameters. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef SWIFT_AST_REQUIREMENT_ENVIRONMENT_H |
| #define SWIFT_AST_REQUIREMENT_ENVIRONMENT_H |
| |
| #include "swift/AST/SubstitutionMap.h" |
| |
| namespace swift { |
| |
| /// Describes the environment of a requirement that will be used when |
| /// matching witnesses against the requirement and to form the resulting |
| /// \c Witness value. |
| /// |
| /// The produced generic environment will have a fresh set of archetypes that |
| /// describe the combined constraints of the requirement (because those |
| /// are available to all potential witnesses) as well as the constraints from |
| /// the context to which the protocol conformance is ascribed, which may |
| /// include additional constraints beyond those of the extended type if the |
| /// conformance is conditional. The type parameters for the generic |
| /// environment are the type parameters of the conformance context |
| /// (\c conformanceDC) with another (deeper) level of type parameters for |
| /// generic requirements. See the \c Witness class for more information about |
| /// this synthetic environment. |
| class RequirementEnvironment { |
| /// A generic signature that combines the generic parameters of the |
| /// concrete conforming type with the generic parameters of the |
| /// requirement. |
| /// |
| /// |
| /// For example, if you have: |
| /// |
| /// protocol P { func f<T>(_: T) } |
| /// struct S<A, B> : P { func f<T>(_: T) } |
| /// |
| /// The requirement and witness signatures are, respectively: |
| /// |
| /// <Self : P, T> |
| /// <A, B, T> |
| /// |
| /// The synthetic signature in this case is just the witness signature. |
| /// |
| /// It may be that the witness is more generic than the requirement, |
| /// for example: |
| /// |
| /// protocol P { func f(_: Int) } |
| /// struct S<A, B> : P { func f<T>(_: T) { } } |
| /// |
| /// Here, the requirement signature and witness signatures are: |
| /// |
| /// <Self : P> |
| /// <A, B, T> |
| /// |
| /// The synthetic signature is just: |
| /// |
| /// <A, B> |
| /// |
| /// The witness thunk emitted by SILGen uses the synthetic signature. |
| /// Therefore one invariant we preserve is that the witness thunk is |
| /// ABI compatible with the requirement's function type. |
| GenericSignature syntheticSignature = GenericSignature(); |
| GenericEnvironment *syntheticEnvironment = nullptr; |
| |
| /// The generic signature of the protocol requirement member. |
| GenericSignature reqSig = GenericSignature(); |
| |
| /// A substitution map mapping the requirement signature to the |
| /// generic parameters of the synthetic signature. |
| SubstitutionMap reqToSyntheticEnvMap; |
| |
| public: |
| /// Create a new environment for matching the given requirement within a |
| /// particular conformance. |
| /// |
| /// \param conformanceDC The \c DeclContext to which the protocol |
| /// conformance is ascribed, which provides additional constraints. |
| /// |
| /// \param reqSig The generic signature of the requirement for which we |
| /// are creating a generic environment. |
| /// |
| /// \param proto The protocol containing the requirement. |
| /// |
| /// \param conformance The protocol conformance, or null if there is no |
| /// conformance (because we're finding default implementations). |
| RequirementEnvironment(DeclContext *conformanceDC, |
| GenericSignature reqSig, |
| ProtocolDecl *proto, |
| ClassDecl *covariantSelf, |
| ProtocolConformance *conformance); |
| |
| /// Retrieve the synthetic generic environment. |
| GenericEnvironment *getSyntheticEnvironment() const { |
| return syntheticEnvironment; |
| } |
| |
| /// Retrieve the generic signature of the requirement. |
| GenericSignature getRequirementSignature() const { |
| return reqSig; |
| } |
| |
| /// Retrieve the substitution map that maps the interface types of the |
| /// requirement to the interface types of the synthetic environment. |
| SubstitutionMap getRequirementToSyntheticMap() const { |
| return reqToSyntheticEnvMap; |
| } |
| }; |
| |
| } |
| |
| #endif // SWIFT_AST_REQUIREMENT_ENVIRONMENT_H |