text: //===--- Constraint.h - Constraint in the Type Checker ----------*- 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 provides the \c Constraint class and its related types,
  // which is used by the constraint-based type checker to describe a
  // constraint that must be solved.
  //
  //===----------------------------------------------------------------------===//
  #ifndef SWIFT_SEMA_CONSTRAINT_H
  #define SWIFT_SEMA_CONSTRAINT_H
  
  #include "swift/AST/FunctionRefKind.h"
  #include "swift/AST/Identifier.h"
  #include "swift/AST/Type.h"
  #include "swift/Basic/Debug.h"
  #include "swift/Sema/OverloadChoice.h"
  #include "llvm/ADT/ArrayRef.h"
  #include "llvm/ADT/ilist.h"
  #include "llvm/ADT/ilist_node.h"
  #include "llvm/Support/TrailingObjects.h"
  
  namespace llvm {
  
  class raw_ostream;
  
  }
  
  namespace swift {
  
  class ProtocolDecl;
  class SourceManager;
  class TypeVariableType;
  
  namespace constraints {
  
  class ConstraintFix;
  class ConstraintLocator;
  class ConstraintSystem;
  enum class TrailingClosureMatching;
  
  /// Describes the kind of constraint placed on one or more types.
  enum class ConstraintKind : char {
    /// The two types must be bound to the same type. This is the only
    /// truly symmetric constraint.
    Bind,
    /// The two types must be bound to the same type, dropping
    /// lvalueness when comparing a type variable to a type.
    Equal,
    /// The first type is the type of a function parameter; the second
    /// type is the type of a reference to that parameter from within the
    /// function body. Specifically, the left type is an inout type iff the right
    /// type is an lvalue type with the same object type. Otherwise, the two
    /// types must be the same type.
    BindParam,
    /// Binds the first type to the element type of the second type.
    BindToPointerType,
    /// The first type is a subtype of the second type, i.e., a value
    /// of the type of the first type can be used wherever a value of the
    /// second type is expected.
    Subtype,
    /// The first type is convertible to the second type.
    Conversion,
    /// The first type can be bridged to the second type.
    BridgingConversion,
    /// The first type is the element of an argument tuple that is
    /// convertible to the second type (which represents the corresponding
    /// parameter type).
    ArgumentConversion,
    /// The first type is convertible to the second type, including inout.
    OperatorArgumentConversion,
    /// The first type must conform to the second type (which is a
    /// protocol type).
    ConformsTo,
    /// The first type describes a literal that conforms to the second
    /// type, which is one of the known expressible-by-literal protocols.
    LiteralConformsTo,
    /// A checked cast from the first type to the second.
    CheckedCast,
    /// The first type can act as the Self type of the second type (which
    /// is a protocol).
    ///
    /// This constraint is slightly looser than a conforms-to constraint, because
    /// an existential can be used as the Self of any protocol within the
    /// existential, even if it doesn't conform to that protocol (e.g., due to
    /// the use of associated types).
    SelfObjectOfProtocol,
    /// Both types are function types. The first function type's
    /// input is the value being passed to the function and its output
    /// is a type variable that describes the output. The second
    /// function type is expected to become a function type. Note, we
    /// do not require the function type attributes to match.
    ApplicableFunction,
    /// The first type is a function type whose input is the value passed
    /// to the function and whose output is a type variable describing the output.
    /// The second type is either a `@dynamicCallable` nominal type or the
    /// function type of a `dynamicallyCall` method defined on a
    /// `@dynamicCallable` nominal type.
    DynamicCallableApplicableFunction,
    /// The first type is the type of the dynamicType member of the
    /// second type.
    DynamicTypeOf,
    /// Binds the left-hand type to a particular overload choice.
    BindOverload,
    /// The first type has a member with the given name, and the
    /// type of that member, when referenced as a value, is the second type.
    ValueMember,
    /// The first type (which is implicit) has a member with the given
    /// name, and the type of that member, when referenced as a value, is the
    /// second type.
    UnresolvedValueMember,
    /// The first type conforms to the protocol in which the member requirement
    /// resides. Once the conformance is resolved, the value witness will be
    /// determined, and the type of that witness, when referenced as a value,
    /// will be bound to the second type.
    ValueWitness,
    /// The first type can be defaulted to the second (which currently
    /// cannot be dependent).  This is more like a type property than a
    /// relational constraint.
    Defaultable,
    /// A disjunction constraint that specifies that one or more of the
    /// stored constraints must hold.
    Disjunction,
    /// The first type is an optional type whose object type is the second
    /// type, preserving lvalue-ness.
    OptionalObject,
    /// The first type is the same function type as the second type, but
    /// made @escaping.
    EscapableFunctionOf,
    /// The first type is an opened type from the second type (which is
    /// an existential).
    OpenedExistentialOf,
    /// A relation between three types. The first is the key path type,
    /// the second is the root type, and the third is the projected value type.
    /// The second and third types can be lvalues depending on the kind of key
    /// path.
    KeyPathApplication,
    /// A relation between three types. The first is the key path type,
    /// the second is its root type, and the third is the projected value type.
    /// The key path type is chosen based on the selection of overloads for the
    /// member references along the path.
    KeyPath,
    /// The first type is a function type, the second is the function's
    /// input type.
    FunctionInput,
    /// The first type is a function type, the second is the function's
    /// result type.
    FunctionResult,
    /// The first type is a type that's a candidate to be the underlying type of
    /// the second opaque archetype.
    OpaqueUnderlyingType,
    /// The first type will be equal to the second type, but only when the
    /// second type has been fully determined (and mapped down to a concrete
    /// type). At that point, this constraint will be treated like an `Equal`
    /// constraint.
    OneWayEqual,
    /// The second type is the type of a function parameter, and the first type
    /// is the type of a reference to that function parameter within the body.
    /// Once the second type has been fully determined (and mapped down to a
    /// concrete type), this constraint will be treated like a 'BindParam'
    /// constraint.
    OneWayBindParam,
    /// If there is no contextual info e.g. `_ = { 42 }` default first type
    /// to a second type (inferred closure type). This is effectively a
    /// `Defaultable` constraint which a couple of differences:
    ///
    /// - References inferred closure type and all of the outer parameters
    ///   referenced by closure body.
    /// - Handled specially by binding inference, specifically contributes
    ///   to the bindings only if there are no contextual types available.
    DefaultClosureType,
  };
  
  /// Classification of the different kinds of constraints.
  enum class ConstraintClassification : char {
    /// A relational constraint, which relates two types.
    Relational,
  
    /// A member constraint, which names a member of a type and assigns
    /// it a reference type.
    Member,
  
    /// A property of a single type, such as whether it is defaultable to
    /// a particular type.
    TypeProperty,
  
    /// A disjunction constraint.
    Disjunction
  };
  
  /// Specifies a restriction on the kind of conversion that should be
  /// performed between the types in a constraint.
  ///
  /// It's common for there to be multiple potential conversions that can
  /// apply between two types, e.g., given class types A and B, there might be
  /// a superclass conversion from A to B or there might be a user-defined
  /// conversion from A to B. The solver may need to explore both paths.
  enum class ConversionRestrictionKind {
    /// Deep equality comparison.
    DeepEquality,
    /// Subclass-to-superclass conversion.
    Superclass,
    /// Class metatype to AnyObject conversion.
    ClassMetatypeToAnyObject,
    /// Existential metatype to AnyObject conversion.
    ExistentialMetatypeToAnyObject,
    /// Protocol value metatype to Protocol class conversion.
    ProtocolMetatypeToProtocolClass,
    /// Inout-to-pointer conversion.
    InoutToPointer,
    /// Array-to-pointer conversion.
    ArrayToPointer,
    /// String-to-pointer conversion.
    StringToPointer,
    /// Pointer-to-pointer conversion.
    PointerToPointer,
    /// Value to existential value conversion, or existential erasure.
    Existential,
    /// Metatype to existential metatype conversion.
    MetatypeToExistentialMetatype,
    /// Existential metatype to metatype conversion.
    ExistentialMetatypeToMetatype,
    /// T -> U? value to optional conversion (or to implicitly unwrapped
    /// optional).
    ValueToOptional,
    /// T? -> U? optional to optional conversion (or unchecked to unchecked).
    OptionalToOptional,
    /// Implicit upcast conversion of array types.
    ArrayUpcast,
    /// Implicit upcast conversion of dictionary types, which includes
    /// bridging.
    DictionaryUpcast,
    /// Implicit upcast conversion of set types, which includes bridging.
    SetUpcast,
    /// T:Hashable -> AnyHashable conversion.
    HashableToAnyHashable,
    /// Implicit conversion from a CF type to its toll-free-bridged Objective-C
    /// class type.
    CFTollFreeBridgeToObjC,
    /// Implicit conversion from an Objective-C class type to its
    /// toll-free-bridged CF type.
    ObjCTollFreeBridgeToCF,
  };
  
  /// Specifies whether a given conversion requires the creation of a temporary
  /// value which is only valid for a limited scope. For example, the
  /// array-to-pointer conversion produces a pointer that is only valid for the
  /// duration of the call that it's passed to. Such ephemeral conversions cannot
  /// be passed to non-ephemeral parameters.
  enum class ConversionEphemeralness {
    /// The conversion requires the creation of a temporary value.
    Ephemeral,
    /// The conversion does not require the creation of a temporary value.
    NonEphemeral,
    /// It is not currently known whether the conversion will produce a temporary
    /// value or not. This can occur for example with an inout-to-pointer
    /// conversion of a member whose base type is an unresolved type variable.
    Unresolved,
  };
  
  /// Return a string representation of a conversion restriction.
  llvm::StringRef getName(ConversionRestrictionKind kind);
  
  /// Should we record which choice was taken in this disjunction for
  /// the purposes of applying it later?
  enum RememberChoice_t : bool {
    ForgetChoice = false,
    RememberChoice = true
  };
  
  /// A constraint between two type variables.
  class Constraint final : public llvm::ilist_node<Constraint>,
      private llvm::TrailingObjects<Constraint, TypeVariableType *> {
    friend TrailingObjects;
  
    /// The kind of constraint.
    ConstraintKind Kind : 8;
  
    /// The kind of restriction placed on this constraint.
    ConversionRestrictionKind Restriction : 8;
  
    /// The fix to be applied to the constraint before visiting it.
    ConstraintFix *TheFix = nullptr;
  
    /// Whether the \c Restriction field is valid.
    unsigned HasRestriction : 1;
  
    /// Whether this constraint is currently active, i.e., stored in the worklist.
    unsigned IsActive : 1;
  
    /// Was this constraint was determined to be inconsistent with the
    /// constraint graph during constraint propagation?
    unsigned IsDisabled : 1;
  
    /// Whether the choice of this disjunction should be recorded in the
    /// solver state.
    unsigned RememberChoice : 1;
    
    /// Whether or not this constraint is 'favored' in the sense that, if
    /// successfully applied, it should be preferred over any other constraints
    /// in its disjunction.
    unsigned IsFavored : 1;
  
    /// The number of type variables referenced by this constraint.
    ///
    /// The type variables themselves are tail-allocated.
    unsigned NumTypeVariables : 11;
  
    /// The kind of function reference, for member references.
    unsigned TheFunctionRefKind : 2;
  
    /// The trailing closure matching for an applicable function constraint,
    /// if any. 0 = None, 1 = Forward, 2 = Backward.
    unsigned trailingClosureMatching : 2;
  
    union {
      struct {
        /// The first type.
        Type First;
  
        /// The second type.
        Type Second;
  
        /// The third type, if any.
        Type Third;
      } Types;
  
      struct {
        /// The type of the base.
        Type First;
  
        /// The type of the member.
        Type Second;
  
        union {
          /// If non-null, the name of a member of the first type is that
          /// being related to the second type.
          ///
          /// Used for ValueMember an UnresolvedValueMember constraints.
          DeclNameRef Name;
  
          /// If non-null, the member being referenced.
          ///
          /// Used for ValueWitness constraints.
          ValueDecl *Ref;
        } Member;
  
        /// The DC in which the use appears.
        DeclContext *UseDC;
      } Member;
  
      /// The set of constraints for a disjunction.
      ArrayRef<Constraint *> Nested;
  
      struct {
        /// The first type
        Type First;
  
        /// The overload choice
        OverloadChoice Choice;
  
        /// The DC in which the use appears.
        DeclContext *UseDC;
      } Overload;
    };
  
    /// The locator that describes where in the expression this
    /// constraint applies.
    ConstraintLocator *Locator;
  
    /// Constraints are always allocated within a given constraint
    /// system.
    void *operator new(size_t) = delete;
  
    Constraint(ConstraintKind kind, ArrayRef<Constraint *> constraints,
               ConstraintLocator *locator, ArrayRef<TypeVariableType *> typeVars);
  
    /// Construct a new constraint.
    Constraint(ConstraintKind kind, Type first, Type second,
               ConstraintLocator *locator,
               ArrayRef<TypeVariableType *> typeVars);
  
    /// Construct a new constraint.
    Constraint(ConstraintKind kind, Type first, Type second, Type third,
               ConstraintLocator *locator,
               ArrayRef<TypeVariableType *> typeVars);
  
    /// Construct a new member constraint.
    Constraint(ConstraintKind kind, Type first, Type second, DeclNameRef member,
               DeclContext *useDC, FunctionRefKind functionRefKind,
               ConstraintLocator *locator,
               ArrayRef<TypeVariableType *> typeVars);
  
    /// Construct a new value witness constraint.
    Constraint(ConstraintKind kind, Type first, Type second,
               ValueDecl *requirement, DeclContext *useDC,
               FunctionRefKind functionRefKind, ConstraintLocator *locator,
               ArrayRef<TypeVariableType *> typeVars);
  
    /// Construct a new overload-binding constraint, which might have a fix.
    Constraint(Type type, OverloadChoice choice, DeclContext *useDC,
               ConstraintFix *fix, ConstraintLocator *locator,
               ArrayRef<TypeVariableType *> typeVars);
  
    /// Construct a restricted constraint.
    Constraint(ConstraintKind kind, ConversionRestrictionKind restriction,
               Type first, Type second, ConstraintLocator *locator,
               ArrayRef<TypeVariableType *> typeVars);
    
    /// Construct a relational constraint with a fix.
    Constraint(ConstraintKind kind, ConstraintFix *fix, Type first, Type second,
               ConstraintLocator *locator, ArrayRef<TypeVariableType *> typeVars);
  
    /// Retrieve the type variables buffer, for internal mutation.
    MutableArrayRef<TypeVariableType *> getTypeVariablesBuffer() {
      return { getTrailingObjects<TypeVariableType *>(), NumTypeVariables };
    }
  
  public:
    /// Create a new constraint.
    static Constraint *create(ConstraintSystem &cs, ConstraintKind Kind,
                              Type First, Type Second, ConstraintLocator *locator,
                              ArrayRef<TypeVariableType *> extraTypeVars = {});
  
    /// Create a new constraint.
    static Constraint *create(ConstraintSystem &cs, ConstraintKind Kind, 
                              Type First, Type Second, Type Third,
                              ConstraintLocator *locator,
                              ArrayRef<TypeVariableType *> extraTypeVars = { });
  
    /// Create a new member constraint, or a disjunction of that with the outer
    /// alternatives.
    static Constraint *createMemberOrOuterDisjunction(
        ConstraintSystem &cs, ConstraintKind kind, Type first, Type second,
        DeclNameRef member, DeclContext *useDC, FunctionRefKind functionRefKind,
        ArrayRef<OverloadChoice> outerAlternatives, ConstraintLocator *locator);
  
    /// Create a new member constraint.
    static Constraint *createMember(ConstraintSystem &cs, ConstraintKind kind,
                                    Type first, Type second, DeclNameRef member,
                                    DeclContext *useDC,
                                    FunctionRefKind functionRefKind,
                                    ConstraintLocator *locator);
  
    /// Create a new value witness constraint.
    static Constraint *createValueWitness(
        ConstraintSystem &cs, ConstraintKind kind, Type first, Type second,
        ValueDecl *requirement, DeclContext *useDC,
        FunctionRefKind functionRefKind, ConstraintLocator *locator);
  
    /// Create an overload-binding constraint.
    static Constraint *createBindOverload(ConstraintSystem &cs, Type type, 
                                          OverloadChoice choice, 
                                          DeclContext *useDC,
                                          ConstraintLocator *locator);
  
    /// Create a restricted relational constraint.
    static Constraint *createRestricted(ConstraintSystem &cs, ConstraintKind kind,
                                        ConversionRestrictionKind restriction,
                                        Type first, Type second, 
                                        ConstraintLocator *locator);
  
    /// Create a relational constraint with a fix.
    static Constraint *createFixed(ConstraintSystem &cs, ConstraintKind kind,
                                   ConstraintFix *fix, Type first, Type second,
                                   ConstraintLocator *locator);
  
    /// Create a bind overload choice with a fix.
    /// Note: This constraint is going to be disabled by default.
    static Constraint *createFixedChoice(ConstraintSystem &cs, Type type,
                                         OverloadChoice choice,
                                         DeclContext *useDC, ConstraintFix *fix,
                                         ConstraintLocator *locator);
  
    /// Create a new disjunction constraint.
    static Constraint *createDisjunction(ConstraintSystem &cs,
                                         ArrayRef<Constraint *> constraints,
                                         ConstraintLocator *locator,
                                         RememberChoice_t shouldRememberChoice
                                           = ForgetChoice);
  
    /// Create a new Applicable Function constraint.
    static Constraint *createApplicableFunction(
        ConstraintSystem &cs, Type argumentFnType, Type calleeType,
        Optional<TrailingClosureMatching> trailingClosureMatching,
        ConstraintLocator *locator);
  
    /// Determine the kind of constraint.
    ConstraintKind getKind() const { return Kind; }
  
    /// Retrieve the restriction placed on this constraint.
    Optional<ConversionRestrictionKind> getRestriction() const {
      if (!HasRestriction)
        return None;
  
      return Restriction;
    }
  
    /// Retrieve the fix associated with this constraint.
    ConstraintFix *getFix() const { return TheFix; }
  
    /// Whether this constraint is active, i.e., in the worklist.
    bool isActive() const { return IsActive; }
  
    /// Set whether this constraint is active or not.
    void setActive(bool active) {
      assert(!isDisabled() && "Cannot activate a constraint that is disabled!");
      IsActive = active;
    }
  
    /// Whether this constraint is active, i.e., in the worklist.
    bool isDisabled() const { return IsDisabled; }
  
    /// Set whether this constraint is active or not.
    void setDisabled() {
      assert(!isActive() && "Cannot disable constraint marked as active!");
      IsDisabled = true;
    }
  
    void setEnabled() {
      assert(isDisabled() && "Can't re-enable already active constraint!");
      IsDisabled = false;
    }
  
    /// Mark or retrieve whether this constraint should be favored in the system.
    void setFavored(bool favored = true) { IsFavored = favored; }
    bool isFavored() const { return IsFavored; }
  
    /// Whether the solver should remember which choice was taken for
    /// this constraint.
    bool shouldRememberChoice() const { return RememberChoice; }
  
    /// Retrieve the set of type variables referenced by this constraint.
    ArrayRef<TypeVariableType *> getTypeVariables() const {
      return {getTrailingObjects<TypeVariableType*>(), NumTypeVariables};
    }
  
    /// Determine the classification of this constraint, providing
    /// a broader categorization than \c getKind().
    ConstraintClassification getClassification() const {
      switch (Kind) {
      case ConstraintKind::Bind:
      case ConstraintKind::Equal:
      case ConstraintKind::BindParam:
      case ConstraintKind::BindToPointerType:
      case ConstraintKind::Subtype:
      case ConstraintKind::Conversion:
      case ConstraintKind::BridgingConversion:
      case ConstraintKind::ArgumentConversion:
      case ConstraintKind::OperatorArgumentConversion:
      case ConstraintKind::ConformsTo:
      case ConstraintKind::LiteralConformsTo:
      case ConstraintKind::CheckedCast:
      case ConstraintKind::SelfObjectOfProtocol:
      case ConstraintKind::ApplicableFunction:
      case ConstraintKind::DynamicCallableApplicableFunction:
      case ConstraintKind::BindOverload:
      case ConstraintKind::OptionalObject:
      case ConstraintKind::OpaqueUnderlyingType:
      case ConstraintKind::OneWayEqual:
      case ConstraintKind::OneWayBindParam:
      case ConstraintKind::DefaultClosureType:
        return ConstraintClassification::Relational;
  
      case ConstraintKind::ValueMember:
      case ConstraintKind::UnresolvedValueMember:
      case ConstraintKind::ValueWitness:
        return ConstraintClassification::Member;
  
      case ConstraintKind::DynamicTypeOf:
      case ConstraintKind::EscapableFunctionOf:
      case ConstraintKind::OpenedExistentialOf:
      case ConstraintKind::KeyPath:
      case ConstraintKind::KeyPathApplication:
      case ConstraintKind::Defaultable:
      case ConstraintKind::FunctionInput:
      case ConstraintKind::FunctionResult:
        return ConstraintClassification::TypeProperty;
  
      case ConstraintKind::Disjunction:
        return ConstraintClassification::Disjunction;
      }
  
      llvm_unreachable("Unhandled ConstraintKind in switch.");
    }
  
    /// Retrieve the first type in the constraint.
    Type getFirstType() const {
      switch (getKind()) {
      case ConstraintKind::Disjunction:
        llvm_unreachable("disjunction constraints have no type operands");
  
      case ConstraintKind::BindOverload:
        return Overload.First;
  
      case ConstraintKind::ValueMember:
      case ConstraintKind::UnresolvedValueMember:
      case ConstraintKind::ValueWitness:
        return Member.First;
  
      default:
        return Types.First;
      }
    }
  
    /// Retrieve the second type in the constraint.
    Type getSecondType() const {
      switch (getKind()) {
      case ConstraintKind::Disjunction:
      case ConstraintKind::BindOverload:
        llvm_unreachable("constraint has no second type");
  
      case ConstraintKind::ValueMember:
      case ConstraintKind::UnresolvedValueMember:
      case ConstraintKind::ValueWitness:
        return Member.Second;
  
      default:
        return Types.Second;
      }
    }
  
    /// Retrieve the third type in the constraint.
    Type getThirdType() const {
      switch (getKind()) {
      case ConstraintKind::KeyPath:
      case ConstraintKind::KeyPathApplication:
        return Types.Third;
      default:
        llvm_unreachable("no third type");
      }
    }
  
    /// Retrieve the protocol in a conformance constraint.
    ProtocolDecl *getProtocol() const;
  
    /// Retrieve the name of the member for a member constraint.
    DeclNameRef getMember() const {
      assert(Kind == ConstraintKind::ValueMember ||
             Kind == ConstraintKind::UnresolvedValueMember);
      return Member.Member.Name;
    }
  
    /// Retrieve the requirement being referenced by a value witness constraint.
    ValueDecl *getRequirement() const {
      assert(Kind == ConstraintKind::ValueWitness);
      return Member.Member.Ref;
    }
  
    /// Determine the kind of function reference we have for a member reference.
    FunctionRefKind getFunctionRefKind() const {
      if (Kind == ConstraintKind::ValueMember ||
          Kind == ConstraintKind::UnresolvedValueMember ||
          Kind == ConstraintKind::ValueWitness)
        return static_cast<FunctionRefKind>(TheFunctionRefKind);
  
      // Conservative answer: drop all of the labels.
      return FunctionRefKind::Compound;
    }
  
    /// Retrieve the set of constraints in a disjunction.
    ArrayRef<Constraint *> getNestedConstraints() const {
      assert(Kind == ConstraintKind::Disjunction);
      return Nested;
    }
  
    unsigned countFavoredNestedConstraints() const {
      return llvm::count_if(Nested, [](const Constraint *constraint) {
        return constraint->isFavored() && !constraint->isDisabled();
      });
    }
  
    unsigned countActiveNestedConstraints() const {
      return llvm::count_if(Nested, [](const Constraint *constraint) {
        return !constraint->isDisabled();
      });
    }
  
    /// Determine if this constraint represents explicit conversion,
    /// e.g. coercion constraint "as X" which forms a disjunction.
    bool isExplicitConversion() const;
  
    /// Whether this is a one-way constraint.
    bool isOneWayConstraint() const {
      return Kind == ConstraintKind::OneWayEqual ||
          Kind == ConstraintKind::OneWayBindParam;
    }
  
    /// Retrieve the overload choice for an overload-binding constraint.
    OverloadChoice getOverloadChoice() const {
      assert(Kind == ConstraintKind::BindOverload);
      return Overload.Choice;
    }
  
    /// Retrieve the DC in which the overload was used.
    DeclContext *getOverloadUseDC() const {
      assert(Kind == ConstraintKind::BindOverload);
      return Overload.UseDC;
    }
  
    /// Retrieve the DC in which the member was used.
    DeclContext *getMemberUseDC() const {
      assert(Kind == ConstraintKind::ValueMember ||
             Kind == ConstraintKind::UnresolvedValueMember ||
             Kind == ConstraintKind::ValueWitness);
      return Member.UseDC;
    }
  
    /// For an applicable function constraint, retrieve the trailing closure
    /// matching rule.
    Optional<TrailingClosureMatching> getTrailingClosureMatching() const;
  
    /// Retrieve the locator for this constraint.
    ConstraintLocator *getLocator() const { return Locator; }
  
    /// Clone the given constraint.
    Constraint *clone(ConstraintSystem &cs) const;
  
    void print(llvm::raw_ostream &Out, SourceManager *sm) const;
  
    SWIFT_DEBUG_DUMPER(dump(SourceManager *SM));
  
    SWIFT_DEBUG_DUMPER(dump(ConstraintSystem *CS));
  
    void *operator new(size_t bytes, ConstraintSystem& cs,
                       size_t alignment = alignof(Constraint));
  
    inline void operator delete(void *, const ConstraintSystem &cs, size_t) {}
  
    void *operator new(size_t bytes, void *mem) { return mem; }
    void operator delete(void *mem) { }
  };
  
  } // end namespace constraints
  } // end namespace swift
  
  namespace llvm {
  
  /// Specialization of \c ilist_traits for constraints.
  template<>
  struct ilist_traits<swift::constraints::Constraint>
           : public ilist_node_traits<swift::constraints::Constraint> {
    using Element = swift::constraints::Constraint;
  
    static Element *createNode(const Element &V) = delete;
    static void deleteNode(Element *V) { /* never deleted */ }
  };
  
  } // end namespace llvm
  
  #endif // LLVM_SWIFT_SEMA_CONSTRAINT_H
  