mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
214 lines
8.0 KiB
C++
214 lines
8.0 KiB
C++
//===--- 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 "swift/AST/Expr.h"
|
|
#include "swift/AST/Type.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 (as! ";
|
|
name += DowncastTo->getString();
|
|
name += ")";
|
|
return name.c_str();
|
|
}
|
|
|
|
bool ForceDowncast::diagnose(Expr *expr, bool asNote) const {
|
|
MissingExplicitConversionFailure failure(expr, getConstraintSystem(),
|
|
getLocator(), DowncastTo);
|
|
return failure.diagnose(asNote);
|
|
}
|
|
|
|
ForceDowncast *ForceDowncast::create(ConstraintSystem &cs, Type toType,
|
|
ConstraintLocator *locator) {
|
|
return new (cs.getAllocator()) ForceDowncast(cs, toType, locator);
|
|
}
|
|
|
|
bool ForceOptional::diagnose(Expr *root, bool asNote) const {
|
|
MissingOptionalUnwrapFailure failure(root, getConstraintSystem(),
|
|
getLocator());
|
|
return failure.diagnose(asNote);
|
|
}
|
|
|
|
ForceOptional *ForceOptional::create(ConstraintSystem &cs,
|
|
ConstraintLocator *locator) {
|
|
return new (cs.getAllocator()) ForceOptional(cs, 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 {
|
|
MissingAddressOfFailure failure(root, getConstraintSystem(), getLocator());
|
|
return failure.diagnose(asNote);
|
|
}
|
|
|
|
AddAddressOf *AddAddressOf::create(ConstraintSystem &cs,
|
|
ConstraintLocator *locator) {
|
|
return new (cs.getAllocator()) AddAddressOf(cs, 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(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 {
|
|
MissingConformanceFailure failure(root, getConstraintSystem(), getLocator(),
|
|
{NonConformingType, Protocol});
|
|
return failure.diagnose(asNote);
|
|
}
|
|
|
|
MissingConformance *MissingConformance::create(ConstraintSystem &cs, Type type,
|
|
ProtocolDecl *protocol,
|
|
ConstraintLocator *locator) {
|
|
return new (cs.getAllocator())
|
|
MissingConformance(cs, type, protocol, 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 AutoClosureForwarding::diagnose(Expr *root, bool asNote) const {
|
|
return false;
|
|
}
|
|
|
|
AutoClosureForwarding *AutoClosureForwarding::create(ConstraintSystem &cs,
|
|
ConstraintLocator *locator) {
|
|
return new (cs.getAllocator()) AutoClosureForwarding(cs, locator);
|
|
}
|