Skip to content

[ConstraintSystem] Remove rudimental TMF_ApplyingOperatorParameter #19587

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions lib/Sema/CSApply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7916,11 +7916,8 @@ Expr *TypeChecker::callWitness(Expr *base, DeclContext *dc,
// Add the conversion from the argument to the function parameter type.
auto openedFuncType = openedType->castTo<FunctionType>();
::matchCallArguments(
cs, /*isOperator=*/false,
args,
openedFuncType->getParams(),
cs.getConstraintLocator(call,
ConstraintLocator::ApplyArgument));
cs, args, openedFuncType->getParams(),
cs.getConstraintLocator(call, ConstraintLocator::ApplyArgument));

// Solve the system.
SmallVector<Solution, 1> solutions;
Expand Down
5 changes: 2 additions & 3 deletions lib/Sema/CSGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1340,9 +1340,8 @@ namespace {
AnyFunctionType::decomposeInput(constrParamType, params);

::matchCallArguments(
CS, /*isOperator=*/false, args, params,
CS.getConstraintLocator(expr,
ConstraintLocator::ApplyArgument));
CS, args, params,
CS.getConstraintLocator(expr, ConstraintLocator::ApplyArgument));

Type result = tv;
if (constr->getFailability() != OTK_None)
Expand Down
55 changes: 18 additions & 37 deletions lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -756,11 +756,9 @@ class ArgumentFailureTracker : public MatchCallArgumentListener {
};

// Match the argument of a call to the parameter.
ConstraintSystem::TypeMatchResult
constraints::matchCallArguments(ConstraintSystem &cs, bool isOperator,
ArrayRef<AnyFunctionType::Param> args,
ArrayRef<AnyFunctionType::Param> params,
ConstraintLocatorBuilder locator) {
ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
ConstraintSystem &cs, ArrayRef<AnyFunctionType::Param> args,
ArrayRef<AnyFunctionType::Param> params, ConstraintLocatorBuilder locator) {
// Extract the parameters.
ValueDecl *callee;
unsigned calleeLevel;
Expand Down Expand Up @@ -821,6 +819,15 @@ constraints::matchCallArguments(ConstraintSystem &cs, bool isOperator,
// Check the argument types for each of the parameters.
ConstraintSystem::TypeMatchOptions subflags =
ConstraintSystem::TMF_GenerateConstraints;

// If this application is part of an operator, then we allow an implicit
// lvalue to be compatible with inout arguments. This is used by
// assignment operators.
auto *anchor = locator.getAnchor();
assert(anchor && "locator without anchor expression?");
bool isOperator = (isa<PrefixUnaryExpr>(anchor) ||
isa<PostfixUnaryExpr>(anchor) || isa<BinaryExpr>(anchor));

ConstraintKind subKind = (isOperator
? ConstraintKind::OperatorArgumentConversion
: ConstraintKind::ArgumentConversion);
Expand All @@ -841,15 +848,6 @@ constraints::matchCallArguments(ConstraintSystem &cs, bool isOperator,
getApplyArgToParam(argIdx,
paramIdx));
auto argTy = argsWithLabels[argIdx].getOldType();

// FIXME: This should be revisited. If one of argTy or paramTy
// is a type variable, matchTypes() will add a constraint, and
// when the constraint is later solved, we will have lost the
// value of 'subflags'.
if (isOperator) {
subflags |= ConstraintSystem::TMF_ApplyingOperatorParameter;
}

auto result = cs.matchTypes(argTy, paramTy, subKind, subflags, loc);
if (result.isFailure())
return result;
Expand Down Expand Up @@ -2196,11 +2194,9 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
ConversionRestrictionKind::InoutToPointer);
}
}

if (!flags.contains(TMF_ApplyingOperatorParameter) &&
// Operators cannot use these implicit conversions.
kind == ConstraintKind::ArgumentConversion) {

// Operators cannot use these implicit conversions.
if (kind == ConstraintKind::ArgumentConversion) {
// We can potentially convert from an UnsafeMutablePointer
// of a different type, if we're a void pointer.
Type unwrappedType1 = type1;
Expand Down Expand Up @@ -3846,7 +3842,6 @@ ConstraintSystem::simplifyBridgingConstraint(Type type1,

// Explicit bridging from a value type to an Objective-C class type.
if (unwrappedFromType->isPotentiallyBridgedValueType() &&
!flags.contains(TMF_ApplyingOperatorParameter) &&
(unwrappedToType->isBridgeableObjectType() ||
(unwrappedToType->isExistentialType() &&
!unwrappedToType->isAny()))) {
Expand Down Expand Up @@ -4450,19 +4445,11 @@ ConstraintSystem::simplifyApplicableFnConstraint(
// For a function, bind the output and convert the argument to the input.
auto func1 = type1->castTo<FunctionType>();
if (auto func2 = dyn_cast<FunctionType>(desugar2)) {
// If this application is part of an operator, then we allow an implicit
// lvalue to be compatible with inout arguments. This is used by
// assignment operators.
bool isOperator = (isa<PrefixUnaryExpr>(anchor) ||
isa<PostfixUnaryExpr>(anchor) ||
isa<BinaryExpr>(anchor));

// The argument type must be convertible to the input type.
if (::matchCallArguments(*this, isOperator,
func1->getParams(),
func2->getParams(),
outerLocator.withPathElement(
ConstraintLocator::ApplyArgument)).isFailure())
if (::matchCallArguments(
*this, func1->getParams(), func2->getParams(),
outerLocator.withPathElement(ConstraintLocator::ApplyArgument))
.isFailure())
return SolutionKind::Error;

// The result types are equivalent.
Expand Down Expand Up @@ -4565,12 +4552,6 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
return SolutionKind::Unsolved;
};

// We'll apply user conversions for operator arguments at the application
// site.
if (matchKind == ConstraintKind::OperatorArgumentConversion) {
flags |= TMF_ApplyingOperatorParameter;
}

TypeMatchOptions subflags = getDefaultDecompositionOptions(flags);

switch (restriction) {
Expand Down
11 changes: 11 additions & 0 deletions lib/Sema/ConstraintLocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,17 @@ class ConstraintLocatorBuilder {
return nullptr;
}

/// Get anchor expression associated with this locator builder.
Expr *getAnchor() const {
for (auto prev = this; prev;
prev = prev->previous.dyn_cast<ConstraintLocatorBuilder *>()) {
if (auto *locator = prev->previous.dyn_cast<ConstraintLocator *>())
return locator->getAnchor();
}

return nullptr;
}

/// \brief Retrieve the components of the complete locator, which includes
/// the anchor expression and the path.
Expr *getLocatorParts(SmallVectorImpl<LocatorPathElt> &path) const {
Expand Down
4 changes: 0 additions & 4 deletions lib/Sema/ConstraintSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -2006,9 +2006,6 @@ class ConstraintSystem {

/// Indicates that we are applying a fix.
TMF_ApplyingFix = 0x02,

/// Indicates we're matching an operator parameter.
TMF_ApplyingOperatorParameter = 0x4,
};

/// Options that govern how type matching should proceed.
Expand Down Expand Up @@ -3305,7 +3302,6 @@ bool matchCallArguments(ArrayRef<AnyFunctionType::Param> args,

ConstraintSystem::TypeMatchResult
matchCallArguments(ConstraintSystem &cs,
bool isOperator,
ArrayRef<AnyFunctionType::Param> args,
ArrayRef<AnyFunctionType::Param> params,
ConstraintLocatorBuilder locator);
Expand Down