//===--- CSFix.cpp - Constraint Fixes -------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 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 implements the \c ConstraintFix class and its related types,
// which is used by constraint solver to attempt to fix constraints to be
// able to produce a solution which is easily diagnosable.
//
//===----------------------------------------------------------------------===//

#include "CSFix.h"
#include "CSDiagnostics.h"
#include "ConstraintLocator.h"
#include "ConstraintSystem.h"
#include "OverloadChoice.h"
#include "swift/AST/Expr.h"
#include "swift/AST/Type.h"
#include "swift/AST/Types.h"
#include "swift/Basic/SourceManager.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/raw_ostream.h"
#include <string>

using namespace swift;
using namespace constraints;

ConstraintFix::~ConstraintFix() {}

Expr *ConstraintFix::getAnchor() const { return getLocator()->getAnchor(); }

void ConstraintFix::print(llvm::raw_ostream &Out) const {
  Out << "[fix: ";
  Out << getName();
  Out << ']';
  Out << " @ ";
  getLocator()->dump(&CS.getASTContext().SourceMgr, Out);
}

void ConstraintFix::dump() const {print(llvm::errs()); }

std::string ForceDowncast::getName() const {
  llvm::SmallString<16> name;
  name += "force downcast (";
  name += getFromType()->getString();
  name += " as! ";
  name += getToType()->getString();
  name += ")";
  return name.c_str();
}

bool ForceDowncast::diagnose(Expr *expr, bool asNote) const {
  auto &cs = getConstraintSystem();
  MissingExplicitConversionFailure failure(expr, cs, getFromType(), getToType(),
                                           getLocator());
  return failure.diagnose(asNote);
}

ForceDowncast *ForceDowncast::create(ConstraintSystem &cs, Type fromType,
                                     Type toType, ConstraintLocator *locator) {
  return new (cs.getAllocator()) ForceDowncast(cs, fromType, toType, locator);
}

bool ForceOptional::diagnose(Expr *root, bool asNote) const {
  MissingOptionalUnwrapFailure failure(root, getConstraintSystem(), BaseType,
                                       UnwrappedType, getLocator());
  return failure.diagnose(asNote);
}

ForceOptional *ForceOptional::create(ConstraintSystem &cs, Type baseType,
                                     Type unwrappedType,
                                     ConstraintLocator *locator) {
  return new (cs.getAllocator())
      ForceOptional(cs, baseType, unwrappedType, locator);
}

bool UnwrapOptionalBase::diagnose(Expr *root, bool asNote) const {
  bool resultIsOptional =
      getKind() == FixKind::UnwrapOptionalBaseWithOptionalResult;
  MemberAccessOnOptionalBaseFailure failure(
      root, getConstraintSystem(), getLocator(), MemberName, resultIsOptional);
  return failure.diagnose(asNote);
}

UnwrapOptionalBase *UnwrapOptionalBase::create(ConstraintSystem &cs,
                                               DeclName member,
                                               ConstraintLocator *locator) {
  return new (cs.getAllocator())
      UnwrapOptionalBase(cs, FixKind::UnwrapOptionalBase, member, locator);
}

UnwrapOptionalBase *UnwrapOptionalBase::createWithOptionalResult(
    ConstraintSystem &cs, DeclName member, ConstraintLocator *locator) {
  return new (cs.getAllocator()) UnwrapOptionalBase(
      cs, FixKind::UnwrapOptionalBaseWithOptionalResult, member, locator);
}

bool AddAddressOf::diagnose(Expr *root, bool asNote) const {
  auto &cs = getConstraintSystem();
  MissingAddressOfFailure failure(root, cs, getFromType(), getToType(),
                                  getLocator());
  return failure.diagnose(asNote);
}

AddAddressOf *AddAddressOf::create(ConstraintSystem &cs, Type argTy,
                                   Type paramTy, ConstraintLocator *locator) {
  return new (cs.getAllocator()) AddAddressOf(cs, argTy, paramTy, locator);
}

bool TreatRValueAsLValue::diagnose(Expr *root, bool asNote) const {
  RValueTreatedAsLValueFailure failure(getConstraintSystem(), getLocator());
  return failure.diagnose(asNote);
}

TreatRValueAsLValue *TreatRValueAsLValue::create(ConstraintSystem &cs,
                                   ConstraintLocator *locator) {
  return new (cs.getAllocator()) TreatRValueAsLValue(cs, locator);
}

bool CoerceToCheckedCast::diagnose(Expr *root, bool asNote) const {
  MissingForcedDowncastFailure failure(root, getConstraintSystem(),
                                       getLocator());
  return failure.diagnose(asNote);
}

CoerceToCheckedCast *CoerceToCheckedCast::create(ConstraintSystem &cs,
                                                 ConstraintLocator *locator) {
  return new (cs.getAllocator()) CoerceToCheckedCast(cs, locator);
}

bool MarkExplicitlyEscaping::diagnose(Expr *root, bool asNote) const {
  NoEscapeFuncToTypeConversionFailure failure(root, getConstraintSystem(),
                                              getLocator(), ConvertTo);
  return failure.diagnose(asNote);
}

MarkExplicitlyEscaping *
MarkExplicitlyEscaping::create(ConstraintSystem &cs, ConstraintLocator *locator,
                               Type convertingTo) {
  return new (cs.getAllocator())
      MarkExplicitlyEscaping(cs, locator, convertingTo);
}

bool RelabelArguments::diagnose(Expr *root, bool asNote) const {
  LabelingFailure failure(root, getConstraintSystem(), getLocator(),
                          getLabels());
  return failure.diagnose(asNote);
}

RelabelArguments *
RelabelArguments::create(ConstraintSystem &cs,
                         llvm::ArrayRef<Identifier> correctLabels,
                         ConstraintLocator *locator) {
  unsigned size = totalSizeToAlloc<Identifier>(correctLabels.size());
  void *mem = cs.getAllocator().Allocate(size, alignof(RelabelArguments));
  return new (mem) RelabelArguments(cs, correctLabels, locator);
}

bool MissingConformance::diagnose(Expr *root, bool asNote) const {
  auto &cs = getConstraintSystem();
  auto *locator = getLocator();

  if (IsContextual) {
    auto context = cs.getContextualTypePurpose();
    MissingContextualConformanceFailure failure(
        root, cs, context, NonConformingType, ProtocolType, locator);
    return failure.diagnose(asNote);
  }

  MissingConformanceFailure failure(
      root, cs, locator, std::make_pair(NonConformingType, ProtocolType));
  return failure.diagnose(asNote);
}

MissingConformance *
MissingConformance::forContextual(ConstraintSystem &cs, Type type,
                                  Type protocolType,
                                  ConstraintLocator *locator) {
  return new (cs.getAllocator()) MissingConformance(
      cs, /*isContextual=*/true, type, protocolType, locator);
}

MissingConformance *
MissingConformance::forRequirement(ConstraintSystem &cs, Type type,
                                   Type protocolType,
                                   ConstraintLocator *locator) {
  return new (cs.getAllocator()) MissingConformance(
      cs, /*isContextual=*/false, type, protocolType, locator);
}

bool SkipSameTypeRequirement::diagnose(Expr *root, bool asNote) const {
  SameTypeRequirementFailure failure(root, getConstraintSystem(), LHS, RHS,
                                     getLocator());
  return failure.diagnose(asNote);
}

SkipSameTypeRequirement *
SkipSameTypeRequirement::create(ConstraintSystem &cs, Type lhs, Type rhs,
                                ConstraintLocator *locator) {
  return new (cs.getAllocator()) SkipSameTypeRequirement(cs, lhs, rhs, locator);
}

bool SkipSuperclassRequirement::diagnose(Expr *root, bool asNote) const {
  SuperclassRequirementFailure failure(root, getConstraintSystem(), LHS, RHS,
                                       getLocator());
  return failure.diagnose(asNote);
}

SkipSuperclassRequirement *
SkipSuperclassRequirement::create(ConstraintSystem &cs, Type lhs, Type rhs,
                                  ConstraintLocator *locator) {
  return new (cs.getAllocator())
      SkipSuperclassRequirement(cs, lhs, rhs, locator);
}

bool ContextualMismatch::diagnose(Expr *root, bool asNote) const {
  auto failure = ContextualFailure(root, getConstraintSystem(), getFromType(),
                                   getToType(), getLocator());
  return failure.diagnose(asNote);
}

ContextualMismatch *ContextualMismatch::create(ConstraintSystem &cs, Type lhs,
                                               Type rhs,
                                               ConstraintLocator *locator) {
  return new (cs.getAllocator()) ContextualMismatch(cs, lhs, rhs, locator);
}

bool AllowTupleTypeMismatch::diagnose(Expr *root, bool asNote) const {
  auto failure = TupleContextualFailure(
      root, getConstraintSystem(), getFromType(), getToType(), getLocator());
  return failure.diagnose(asNote);
}

AllowTupleTypeMismatch *
AllowTupleTypeMismatch::create(ConstraintSystem &cs, Type lhs, Type rhs,
                               ConstraintLocator *locator) {
  assert(lhs->is<TupleType>() && rhs->is<TupleType>() &&
         "lhs and rhs must be tuple types");
  return new (cs.getAllocator()) AllowTupleTypeMismatch(cs, lhs, rhs, locator);
}

bool GenericArgumentsMismatch::diagnose(Expr *root, bool asNote) const {
  auto &cs = getConstraintSystem();
  GenericArgumentsMismatchFailure failure(root, cs, getFromType(), getToType(),
                                          getMismatches(), getLocator());
  return failure.diagnose(asNote);
}

GenericArgumentsMismatch *GenericArgumentsMismatch::create(
    ConstraintSystem &cs, Type actual, Type required,
    llvm::ArrayRef<unsigned> mismatches, ConstraintLocator *locator) {
  unsigned size = totalSizeToAlloc<unsigned>(mismatches.size());
  void *mem =
      cs.getAllocator().Allocate(size, alignof(GenericArgumentsMismatch));
  return new (mem)
      GenericArgumentsMismatch(cs, actual, required, mismatches, locator);
}

bool AutoClosureForwarding::diagnose(Expr *root, bool asNote) const {
  auto failure =
      AutoClosureForwardingFailure(getConstraintSystem(), getLocator());
  return failure.diagnose(asNote);
}

AutoClosureForwarding *AutoClosureForwarding::create(ConstraintSystem &cs,
                                                     ConstraintLocator *locator) {
  return new (cs.getAllocator()) AutoClosureForwarding(cs, locator);
}

bool AllowAutoClosurePointerConversion::diagnose(Expr *root, bool asNote) const {
  auto failure = AutoClosurePointerConversionFailure(root, getConstraintSystem(),
      getFromType(), getToType(), getLocator());
  return failure.diagnose(asNote);
}

AllowAutoClosurePointerConversion *
AllowAutoClosurePointerConversion::create(ConstraintSystem &cs, Type pointeeType,
                                          Type pointerType,
                                          ConstraintLocator *locator) {
  return new (cs.getAllocator())
      AllowAutoClosurePointerConversion(cs, pointeeType, pointerType, locator);
}

bool RemoveUnwrap::diagnose(Expr *root, bool asNote) const {
  auto failure = NonOptionalUnwrapFailure(root, getConstraintSystem(), BaseType,
                                          getLocator());
  return failure.diagnose(asNote);
}

RemoveUnwrap *RemoveUnwrap::create(ConstraintSystem &cs, Type baseType,
                                   ConstraintLocator *locator) {
  return new (cs.getAllocator()) RemoveUnwrap(cs, baseType, locator);
}

bool InsertExplicitCall::diagnose(Expr *root, bool asNote) const {
  auto failure = MissingCallFailure(root, getConstraintSystem(), getLocator());
  return failure.diagnose(asNote);
}

InsertExplicitCall *InsertExplicitCall::create(ConstraintSystem &cs,
                                               ConstraintLocator *locator) {
  return new (cs.getAllocator()) InsertExplicitCall(cs, locator);
}

bool UsePropertyWrapper::diagnose(Expr *root, bool asNote) const {
  auto &cs = getConstraintSystem();
  auto failure = ExtraneousPropertyWrapperUnwrapFailure(
      root, cs, Wrapped, UsingStorageWrapper, Base, Wrapper, getLocator());
  return failure.diagnose(asNote);
}

UsePropertyWrapper *UsePropertyWrapper::create(ConstraintSystem &cs,
                                               VarDecl *wrapped,
                                               bool usingStorageWrapper,
                                               Type base, Type wrapper,
                                               ConstraintLocator *locator) {
  return new (cs.getAllocator()) UsePropertyWrapper(
      cs, wrapped, usingStorageWrapper, base, wrapper, locator);
}

bool UseWrappedValue::diagnose(Expr *root, bool asNote) const {
  auto &cs = getConstraintSystem();
  auto failure = MissingPropertyWrapperUnwrapFailure(
      root, cs, PropertyWrapper, usingStorageWrapper(), Base, Wrapper,
      getLocator());
  return failure.diagnose(asNote);
}

UseWrappedValue *UseWrappedValue::create(ConstraintSystem &cs,
                                         VarDecl *propertyWrapper, Type base,
                                         Type wrapper,
                                         ConstraintLocator *locator) {
  return new (cs.getAllocator())
      UseWrappedValue(cs, propertyWrapper, base, wrapper, locator);
}

bool UseSubscriptOperator::diagnose(Expr *root, bool asNote) const {
  auto failure = SubscriptMisuseFailure(root, getConstraintSystem(), getLocator());
  return failure.diagnose(asNote);
}

UseSubscriptOperator *UseSubscriptOperator::create(ConstraintSystem &cs,
                                                   ConstraintLocator *locator) {
  return new (cs.getAllocator()) UseSubscriptOperator(cs, locator);
}

bool DefineMemberBasedOnUse::diagnose(Expr *root, bool asNote) const {
  auto failure = MissingMemberFailure(root, getConstraintSystem(), BaseType,
                                      Name, getLocator());
  return failure.diagnose(asNote);
}

DefineMemberBasedOnUse *
DefineMemberBasedOnUse::create(ConstraintSystem &cs, Type baseType,
                               DeclName member, ConstraintLocator *locator) {
  return new (cs.getAllocator())
      DefineMemberBasedOnUse(cs, baseType, member, locator);
}

AllowMemberRefOnExistential *
AllowMemberRefOnExistential::create(ConstraintSystem &cs, Type baseType,
                                    ValueDecl *member, DeclName memberName,
                                    ConstraintLocator *locator) {
  return new (cs.getAllocator())
      AllowMemberRefOnExistential(cs, baseType, memberName, member, locator);
}

bool AllowMemberRefOnExistential::diagnose(Expr *root, bool asNote) const {
  auto failure =
      InvalidMemberRefOnExistential(root, getConstraintSystem(), getBaseType(),
                                    getMemberName(), getLocator());
  return failure.diagnose(asNote);
}

bool AllowTypeOrInstanceMember::diagnose(Expr *root, bool asNote) const {
  auto failure = AllowTypeOrInstanceMemberFailure(
      root, getConstraintSystem(), getBaseType(), getMember(), getMemberName(),
      getLocator());
  return failure.diagnose(asNote);
}

AllowTypeOrInstanceMember *
AllowTypeOrInstanceMember::create(ConstraintSystem &cs, Type baseType,
                                  ValueDecl *member, DeclName usedName,
                                  ConstraintLocator *locator) {
  return new (cs.getAllocator())
      AllowTypeOrInstanceMember(cs, baseType, member, usedName, locator);
}

bool AllowInvalidPartialApplication::diagnose(Expr *root, bool asNote) const {
  auto failure = PartialApplicationFailure(root, isWarning(),
                                           getConstraintSystem(), getLocator());
  return failure.diagnose(asNote);
}

AllowInvalidPartialApplication *
AllowInvalidPartialApplication::create(bool isWarning, ConstraintSystem &cs,
                                       ConstraintLocator *locator) {
  return new (cs.getAllocator())
      AllowInvalidPartialApplication(isWarning, cs, locator);
}

bool AllowInvalidInitRef::diagnose(Expr *root, bool asNote) const {
  switch (Kind) {
  case RefKind::DynamicOnMetatype: {
    InvalidDynamicInitOnMetatypeFailure failure(
        root, getConstraintSystem(), BaseType, Init, BaseRange, getLocator());
    return failure.diagnose(asNote);
  }

  case RefKind::ProtocolMetatype: {
    InitOnProtocolMetatypeFailure failure(root, getConstraintSystem(), BaseType,
                                          Init, IsStaticallyDerived, BaseRange,
                                          getLocator());
    return failure.diagnose(asNote);
  }

  case RefKind::NonConstMetatype: {
    ImplicitInitOnNonConstMetatypeFailure failure(root, getConstraintSystem(),
                                                  BaseType, Init, getLocator());
    return failure.diagnose(asNote);
  }
  }
  llvm_unreachable("covered switch");
}

AllowInvalidInitRef *AllowInvalidInitRef::dynamicOnMetatype(
    ConstraintSystem &cs, Type baseTy, ConstructorDecl *init,
    SourceRange baseRange, ConstraintLocator *locator) {
  return create(RefKind::DynamicOnMetatype, cs, baseTy, init,
                /*isStaticallyDerived=*/false, baseRange, locator);
}

AllowInvalidInitRef *AllowInvalidInitRef::onProtocolMetatype(
    ConstraintSystem &cs, Type baseTy, ConstructorDecl *init,
    bool isStaticallyDerived, SourceRange baseRange,
    ConstraintLocator *locator) {
  return create(RefKind::ProtocolMetatype, cs, baseTy, init,
                isStaticallyDerived, baseRange, locator);
}

AllowInvalidInitRef *
AllowInvalidInitRef::onNonConstMetatype(ConstraintSystem &cs, Type baseTy,
                                        ConstructorDecl *init,
                                        ConstraintLocator *locator) {
  return create(RefKind::NonConstMetatype, cs, baseTy, init,
                /*isStaticallyDerived=*/false, SourceRange(), locator);
}

AllowInvalidInitRef *
AllowInvalidInitRef::create(RefKind kind, ConstraintSystem &cs, Type baseTy,
                            ConstructorDecl *init, bool isStaticallyDerived,
                            SourceRange baseRange, ConstraintLocator *locator) {
  return new (cs.getAllocator()) AllowInvalidInitRef(
      cs, kind, baseTy, init, isStaticallyDerived, baseRange, locator);
}

bool AllowClosureParamDestructuring::diagnose(Expr *root, bool asNote) const {
  ClosureParamDestructuringFailure failure(root, getConstraintSystem(),
                                           ContextualType, getLocator());
  return failure.diagnose(asNote);
}

AllowClosureParamDestructuring *
AllowClosureParamDestructuring::create(ConstraintSystem &cs,
                                       FunctionType *contextualType,
                                       ConstraintLocator *locator) {
  return new (cs.getAllocator())
      AllowClosureParamDestructuring(cs, contextualType, locator);
}

bool AddMissingArguments::diagnose(Expr *root, bool asNote) const {
  auto &cs = getConstraintSystem();
  MissingArgumentsFailure failure(root, cs, getSynthesizedArguments(),
                                  getLocator());
  return failure.diagnose(asNote);
}

AddMissingArguments *
AddMissingArguments::create(ConstraintSystem &cs,
                            llvm::ArrayRef<Param> synthesizedArgs,
                            ConstraintLocator *locator) {
  unsigned size = totalSizeToAlloc<Param>(synthesizedArgs.size());
  void *mem = cs.getAllocator().Allocate(size, alignof(AddMissingArguments));
  return new (mem) AddMissingArguments(cs, synthesizedArgs, locator);
}

bool MoveOutOfOrderArgument::diagnose(Expr *root, bool asNote) const {
  OutOfOrderArgumentFailure failure(root, getConstraintSystem(), ArgIdx,
                                    PrevArgIdx, Bindings, getLocator());
  return failure.diagnose(asNote);
}

MoveOutOfOrderArgument *MoveOutOfOrderArgument::create(
    ConstraintSystem &cs, unsigned argIdx, unsigned prevArgIdx,
    ArrayRef<ParamBinding> bindings, ConstraintLocator *locator) {
  return new (cs.getAllocator())
      MoveOutOfOrderArgument(cs, argIdx, prevArgIdx, bindings, locator);
}

bool AllowInaccessibleMember::diagnose(Expr *root, bool asNote) const {
  InaccessibleMemberFailure failure(root, getConstraintSystem(), getMember(),
                                    getLocator());
  return failure.diagnose(asNote);
}

AllowInaccessibleMember *
AllowInaccessibleMember::create(ConstraintSystem &cs, Type baseType,
                                ValueDecl *member, DeclName name,
                                ConstraintLocator *locator) {
  return new (cs.getAllocator())
      AllowInaccessibleMember(cs, baseType, member, name, locator);
}

bool AllowAnyObjectKeyPathRoot::diagnose(Expr *root, bool asNote) const {
  AnyObjectKeyPathRootFailure failure(root, getConstraintSystem(),
                                      getLocator());
  return failure.diagnose(asNote);
}

AllowAnyObjectKeyPathRoot *
AllowAnyObjectKeyPathRoot::create(ConstraintSystem &cs,
                                  ConstraintLocator *locator) {
  return new (cs.getAllocator()) AllowAnyObjectKeyPathRoot(cs, locator);
}

bool TreatKeyPathSubscriptIndexAsHashable::diagnose(Expr *root,
                                                    bool asNote) const {
  KeyPathSubscriptIndexHashableFailure failure(root, getConstraintSystem(),
                                               NonConformingType, getLocator());
  return failure.diagnose(asNote);
}

TreatKeyPathSubscriptIndexAsHashable *
TreatKeyPathSubscriptIndexAsHashable::create(ConstraintSystem &cs, Type type,
                                             ConstraintLocator *locator) {
  return new (cs.getAllocator())
      TreatKeyPathSubscriptIndexAsHashable(cs, type, locator);
}

bool AllowInvalidRefInKeyPath::diagnose(Expr *root, bool asNote) const {
  switch (Kind) {
  case RefKind::StaticMember: {
    InvalidStaticMemberRefInKeyPath failure(root, getConstraintSystem(), Member,
                                            getLocator());
    return failure.diagnose(asNote);
  }

  case RefKind::MutatingGetter: {
    InvalidMemberWithMutatingGetterInKeyPath failure(
        root, getConstraintSystem(), Member, getLocator());
    return failure.diagnose(asNote);
  }

  case RefKind::Method: {
    InvalidMethodRefInKeyPath failure(root, getConstraintSystem(), Member,
                                      getLocator());
    return failure.diagnose(asNote);
  }
  }
  llvm_unreachable("covered switch");
}

AllowInvalidRefInKeyPath *
AllowInvalidRefInKeyPath::forRef(ConstraintSystem &cs, ValueDecl *member,
                                 ConstraintLocator *locator) {
  // Referencing (instance or static) methods in key path is
  // not currently allowed.
  if (isa<FuncDecl>(member))
    return AllowInvalidRefInKeyPath::create(cs, RefKind::Method, member,
                                            locator);

  // Referencing static members in key path is not currently allowed.
  if (member->isStatic())
    return AllowInvalidRefInKeyPath::create(cs, RefKind::StaticMember, member,
                                            locator);

  if (auto *storage = dyn_cast<AbstractStorageDecl>(member)) {
    // Referencing members with mutating getters in key path is not
    // currently allowed.
    if (storage->isGetterMutating())
      return AllowInvalidRefInKeyPath::create(cs, RefKind::MutatingGetter,
                                              member, locator);
  }

  return nullptr;
}

AllowInvalidRefInKeyPath *
AllowInvalidRefInKeyPath::create(ConstraintSystem &cs, RefKind kind,
                                 ValueDecl *member,
                                 ConstraintLocator *locator) {
  return new (cs.getAllocator())
      AllowInvalidRefInKeyPath(cs, kind, member, locator);
}

KeyPathContextualMismatch *
KeyPathContextualMismatch::create(ConstraintSystem &cs, Type lhs, Type rhs,
                                  ConstraintLocator *locator) {
  return new (cs.getAllocator())
      KeyPathContextualMismatch(cs, lhs, rhs, locator);
}

bool RemoveAddressOf::diagnose(Expr *root, bool asNote) const {
  InvalidUseOfAddressOf failure(root, getConstraintSystem(), getFromType(),
                                getToType(), getLocator());
  return failure.diagnose(asNote);
}

RemoveAddressOf *RemoveAddressOf::create(ConstraintSystem &cs, Type lhs, Type rhs,
                                         ConstraintLocator *locator) {
  return new (cs.getAllocator()) RemoveAddressOf(cs, lhs, rhs, locator);
}

bool RemoveReturn::diagnose(Expr *root, bool asNote) const {
  ExtraneousReturnFailure failure(root, getConstraintSystem(), getLocator());
  return failure.diagnose(asNote);
}

RemoveReturn *RemoveReturn::create(ConstraintSystem &cs,
                                   ConstraintLocator *locator) {
  return new (cs.getAllocator()) RemoveReturn(cs, locator);
}

bool CollectionElementContextualMismatch::diagnose(Expr *root,
                                                   bool asNote) const {
  CollectionElementContextualFailure failure(
      root, getConstraintSystem(), getFromType(), getToType(), getLocator());
  return failure.diagnose(asNote);
}

CollectionElementContextualMismatch *
CollectionElementContextualMismatch::create(ConstraintSystem &cs, Type srcType,
                                            Type dstType,
                                            ConstraintLocator *locator) {
  return new (cs.getAllocator())
      CollectionElementContextualMismatch(cs, srcType, dstType, locator);
}

bool ExplicitlySpecifyGenericArguments::diagnose(Expr *root,
                                                 bool asNote) const {
  auto &cs = getConstraintSystem();
  MissingGenericArgumentsFailure failure(root, cs, getParameters(),
                                         getLocator());
  return failure.diagnose(asNote);
}

ExplicitlySpecifyGenericArguments *ExplicitlySpecifyGenericArguments::create(
    ConstraintSystem &cs, ArrayRef<GenericTypeParamType *> params,
    ConstraintLocator *locator) {
  unsigned size = totalSizeToAlloc<GenericTypeParamType *>(params.size());
  void *mem = cs.getAllocator().Allocate(
      size, alignof(ExplicitlySpecifyGenericArguments));
  return new (mem) ExplicitlySpecifyGenericArguments(cs, params, locator);
}

SkipUnhandledConstructInFunctionBuilder *
SkipUnhandledConstructInFunctionBuilder::create(ConstraintSystem &cs,
                                                UnhandledNode unhandled,
                                                NominalTypeDecl *builder,
                                                ConstraintLocator *locator) {
  return new (cs.getAllocator())
    SkipUnhandledConstructInFunctionBuilder(cs, unhandled, builder, locator);
}

bool SkipUnhandledConstructInFunctionBuilder::diagnose(Expr *root,
                                                       bool asNote) const {
  SkipUnhandledConstructInFunctionBuilderFailure failure(
      root, getConstraintSystem(), unhandled, builder, getLocator());
  return failure.diagnose(asNote);
}

bool AllowMutatingMemberOnRValueBase::diagnose(Expr *root, bool asNote) const {
  auto &cs = getConstraintSystem();
  MutatingMemberRefOnImmutableBase failure(root, cs, getMember(), getLocator());
  return failure.diagnose(asNote);
}

AllowMutatingMemberOnRValueBase *
AllowMutatingMemberOnRValueBase::create(ConstraintSystem &cs, Type baseType,
                                        ValueDecl *member, DeclName name,
                                        ConstraintLocator *locator) {
  return new (cs.getAllocator())
      AllowMutatingMemberOnRValueBase(cs, baseType, member, name, locator);
}

bool AllowTupleSplatForSingleParameter::diagnose(Expr *root, bool asNote) const {
  auto &cs = getConstraintSystem();
  InvalidTupleSplatWithSingleParameterFailure failure(root, cs, ParamType,
                                                      getLocator());
  return failure.diagnose(asNote);
}

bool AllowTupleSplatForSingleParameter::attempt(
    ConstraintSystem &cs, SmallVectorImpl<Param> &args, ArrayRef<Param> params,
    SmallVectorImpl<SmallVector<unsigned, 1>> &bindings,
    ConstraintLocatorBuilder locator) {
  if (params.size() != 1 || args.size() <= 1)
    return true;

  const auto &param = params.front();

  if (param.isInOut() || param.isVariadic() || param.isAutoClosure())
    return true;

  auto paramTy = param.getOldType();

  // Parameter type has to be either a tuple (with the same arity as
  // argument list), or a type variable.
  if (!(paramTy->is<TupleType>() &&
        paramTy->castTo<TupleType>()->getNumElements() == args.size()) &&
      !paramTy->is<TypeVariableType>())
    return true;

  SmallVector<TupleTypeElt, 4> argElts;

  for (unsigned index : indices(args)) {
    const auto &arg = args[index];

    auto label = arg.getLabel();
    auto flags = arg.getParameterFlags();

    // In situations where there is a single labeled parameter
    // we need to form a tuple with omits first label e.g.
    //
    // func foo<T>(x: T) {}
    // foo(x: 0, 1)
    //
    // We'd want to suggest argument list to be `x: (0, 1)` instead
    // of `(x: 0, 1)` which would be incorrect.
    if (index == 0 && param.getLabel() == label)
      label = Identifier();

    // Tuple can't have `inout` elements.
    if (flags.isInOut())
      return true;

    argElts.push_back({arg.getPlainType(), label});
  }

  bindings[0].clear();
  bindings[0].push_back(0);

  auto newArgType = TupleType::get(argElts, cs.getASTContext());

  args.clear();
  args.push_back(AnyFunctionType::Param(newArgType, param.getLabel()));

  auto *fix = new (cs.getAllocator()) AllowTupleSplatForSingleParameter(
      cs, paramTy, cs.getConstraintLocator(locator));

  return cs.recordFix(fix);
}

bool DropThrowsAttribute::diagnose(Expr *root, bool asNote) const {
  auto &cs = getConstraintSystem();
  ThrowingFunctionConversionFailure failure(root, cs, getFromType(),
                                            getToType(), getLocator());
  return failure.diagnose(asNote);
}

DropThrowsAttribute *DropThrowsAttribute::create(ConstraintSystem &cs,
                                                 FunctionType *fromType,
                                                 FunctionType *toType,
                                                 ConstraintLocator *locator) {
  return new (cs.getAllocator())
      DropThrowsAttribute(cs, fromType, toType, locator);
}

bool IgnoreContextualType::diagnose(Expr *root, bool asNote) const {
  auto &cs = getConstraintSystem();
  ContextualFailure failure(root, cs, getFromType(), getToType(), getLocator());
  return failure.diagnose(asNote);
}

IgnoreContextualType *IgnoreContextualType::create(ConstraintSystem &cs,
                                                   Type resultTy,
                                                   Type specifiedTy,
                                                   ConstraintLocator *locator) {
  return new (cs.getAllocator())
      IgnoreContextualType(cs, resultTy, specifiedTy, locator);
}

bool IgnoreAssignmentDestinationType::diagnose(Expr *root, bool asNote) const {
  auto &cs = getConstraintSystem();
  auto *AE = cast<AssignExpr>(getAnchor());
  auto CTP = isa<SubscriptExpr>(AE->getDest()) ? CTP_SubscriptAssignSource
                                               : CTP_AssignSource;

  ContextualFailure failure(
      root, cs, CTP, getFromType(), getToType(),
      cs.getConstraintLocator(AE->getSrc(), LocatorPathElt::ContextualType()));
  return failure.diagnose(asNote);
}

IgnoreAssignmentDestinationType *
IgnoreAssignmentDestinationType::create(ConstraintSystem &cs, Type sourceTy,
                                        Type destTy,
                                        ConstraintLocator *locator) {
  return new (cs.getAllocator())
      IgnoreAssignmentDestinationType(cs, sourceTy, destTy, locator);
}

bool AllowInOutConversion::diagnose(Expr *root, bool asNote) const {
  auto &cs = getConstraintSystem();
  InOutConversionFailure failure(root, cs, getFromType(), getToType(),
                                 getLocator());
  return failure.diagnose(asNote);
}

AllowInOutConversion *AllowInOutConversion::create(ConstraintSystem &cs,
                                                   Type argType, Type paramType,
                                                   ConstraintLocator *locator) {
  return new (cs.getAllocator())
      AllowInOutConversion(cs, argType, paramType, locator);
}

/// Check whether given `value` type is indeed a the same type as a `RawValue`
/// type of a given raw representable type.
static bool isValueOfRawRepresentable(ConstraintSystem &cs,
                                      Type rawRepresentableType,
                                      Type valueType) {
  auto rawType = isRawRepresentable(cs, rawRepresentableType);
  if (!rawType)
    return false;

  KnownProtocolKind protocols[] = {
      KnownProtocolKind::ExpressibleByStringLiteral,
      KnownProtocolKind::ExpressibleByIntegerLiteral};

  for (auto protocol : protocols) {
    if (conformsToKnownProtocol(cs, valueType, protocol) &&
        valueType->isEqual(rawType))
      return true;
  }

  return false;
}

ExpandArrayIntoVarargs *
ExpandArrayIntoVarargs::attempt(ConstraintSystem &cs, Type argType,
                                Type paramType,
                                ConstraintLocatorBuilder locator) {
  auto constraintLocator = cs.getConstraintLocator(locator);
  auto elementType = cs.isArrayType(argType);
  if (elementType &&
      constraintLocator->getLastElementAs<LocatorPathElt::ApplyArgToParam>()
          ->getParameterFlags()
          .isVariadic()) {
    auto options = ConstraintSystem::TypeMatchOptions(
        ConstraintSystem::TypeMatchFlags::TMF_ApplyingFix |
        ConstraintSystem::TypeMatchFlags::TMF_GenerateConstraints);
    auto result =
        cs.matchTypes(*elementType, paramType,
                      ConstraintKind::ArgumentConversion, options, locator);
    if (result.isSuccess())
      return new (cs.getAllocator())
          ExpandArrayIntoVarargs(cs, argType, paramType, constraintLocator);
  }

  return nullptr;
}

bool ExpandArrayIntoVarargs::diagnose(Expr *root, bool asNote) const {
  ExpandArrayIntoVarargsFailure failure(
      root, getConstraintSystem(), getFromType(), getToType(), getLocator());
  return failure.diagnose(asNote);
}

ExplicitlyConstructRawRepresentable *
ExplicitlyConstructRawRepresentable::attempt(ConstraintSystem &cs, Type argType,
                                             Type paramType,
                                             ConstraintLocatorBuilder locator) {
  auto rawRepresentableType = paramType->lookThroughAllOptionalTypes();
  auto valueType = argType->lookThroughAllOptionalTypes();

  if (isValueOfRawRepresentable(cs, rawRepresentableType, valueType))
    return new (cs.getAllocator()) ExplicitlyConstructRawRepresentable(
        cs, valueType, rawRepresentableType, cs.getConstraintLocator(locator));

  return nullptr;
}

UseValueTypeOfRawRepresentative *
UseValueTypeOfRawRepresentative::attempt(ConstraintSystem &cs, Type argType,
                                         Type paramType,
                                         ConstraintLocatorBuilder locator) {
  auto rawRepresentableType = argType->lookThroughAllOptionalTypes();
  auto valueType = paramType->lookThroughAllOptionalTypes();

  if (isValueOfRawRepresentable(cs, rawRepresentableType, valueType))
    return new (cs.getAllocator()) UseValueTypeOfRawRepresentative(
        cs, rawRepresentableType, valueType, cs.getConstraintLocator(locator));

  return nullptr;
}

bool AllowArgumentMismatch::diagnose(Expr *root, bool asNote) const {
  auto &cs = getConstraintSystem();
  ArgumentMismatchFailure failure(root, cs, getFromType(), getToType(),
                                  getLocator());
  return failure.diagnose(asNote);
}

AllowArgumentMismatch *
AllowArgumentMismatch::create(ConstraintSystem &cs, Type argType,
                              Type paramType, ConstraintLocator *locator) {
  return new (cs.getAllocator())
      AllowArgumentMismatch(cs, argType, paramType, locator);
}
