Skip to content

Commit aa212d5

Browse files
committed
[ConstraintSystem] Add a fix to ignore contextual type mismatch
Ignore contextual type mismatch to allow solver to make progress towards solution and diagnose the problem later.
1 parent c88407f commit aa212d5

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

lib/Sema/CSFix.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,3 +743,17 @@ bool AllowTupleSplatForSingleParameter::attempt(
743743

744744
return cs.recordFix(fix);
745745
}
746+
747+
bool IgnoreContextualType::diagnose(Expr *root, bool asNote) const {
748+
auto &cs = getConstraintSystem();
749+
ContextualFailure failure(root, cs, getFromType(), getToType(), getLocator());
750+
return failure.diagnose(asNote);
751+
}
752+
753+
IgnoreContextualType *IgnoreContextualType::create(ConstraintSystem &cs,
754+
Type resultTy,
755+
Type specifiedTy,
756+
ConstraintLocator *locator) {
757+
return new (cs.getAllocator())
758+
IgnoreContextualType(cs, resultTy, specifiedTy, locator);
759+
}

lib/Sema/CSFix.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,6 +1282,23 @@ class AllowTupleSplatForSingleParameter final : public ConstraintFix {
12821282
ConstraintLocatorBuilder locator);
12831283
};
12841284

1285+
class IgnoreContextualType : public ContextualMismatch {
1286+
IgnoreContextualType(ConstraintSystem &cs, Type resultTy, Type specifiedTy,
1287+
ConstraintLocator *locator)
1288+
: ContextualMismatch(cs, resultTy, specifiedTy, locator) {}
1289+
1290+
public:
1291+
std::string getName() const override {
1292+
return "ignore specified contextual type";
1293+
}
1294+
1295+
bool diagnose(Expr *root, bool asNote = false) const override;
1296+
1297+
static IgnoreContextualType *create(ConstraintSystem &cs, Type resultTy,
1298+
Type specifiedTy,
1299+
ConstraintLocator *locator);
1300+
};
1301+
12851302
} // end namespace constraints
12861303
} // end namespace swift
12871304

lib/Sema/CSSimplify.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2530,7 +2530,27 @@ bool ConstraintSystem::repairFailures(
25302530
auto *fix = AllowTupleTypeMismatch::create(*this, lhs, rhs,
25312531
getConstraintLocator(locator));
25322532
conversionsOrFixes.push_back(fix);
2533+
break;
25332534
}
2535+
2536+
// If either side is not yet resolved, it's too early for this fix.
2537+
if (lhs->isTypeVariableOrMember() || rhs->isTypeVariableOrMember())
2538+
break;
2539+
2540+
// If contextual type is an existential value, it's handled
2541+
// after conversion restriction is attempted.
2542+
if (rhs->isExistentialType())
2543+
break;
2544+
2545+
// TODO(diagnostics): This is a problem related to `inout` mismatch,
2546+
// in argument position, and we got here from CSDiag. Once
2547+
// argument-to-pararameter conversion failures are implemented,
2548+
// this check could be removed.
2549+
if (lhs->is<InOutType>() || rhs->is<InOutType>())
2550+
break;
2551+
2552+
conversionsOrFixes.push_back(IgnoreContextualType::create(
2553+
*this, lhs, rhs, getConstraintLocator(locator)));
25342554
break;
25352555
}
25362556

@@ -7103,7 +7123,6 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
71037123
case FixKind::RemoveAddressOf:
71047124
case FixKind::SkipSameTypeRequirement:
71057125
case FixKind::SkipSuperclassRequirement:
7106-
case FixKind::ContextualMismatch:
71077126
case FixKind::AddMissingArguments:
71087127
case FixKind::DefaultArgumentTypeMismatch:
71097128
case FixKind::SkipUnhandledConstructInFunctionBuilder:
@@ -7112,6 +7131,24 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
71127131
return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved;
71137132
}
71147133

7134+
case FixKind::ContextualMismatch: {
7135+
if (recordFix(fix))
7136+
return SolutionKind::Error;
7137+
7138+
// If type produced by expression is a function type
7139+
// with result type matching contextual, it should have
7140+
// been diagnosed as "missing explicit call", let's
7141+
// increase the score to make sure that we don't impede that.
7142+
if (auto *fnType = type1->getAs<FunctionType>()) {
7143+
auto result =
7144+
matchTypes(fnType->getResult(), type2, matchKind, subflags, locator);
7145+
if (result == SolutionKind::Solved)
7146+
increaseScore(SK_Fix);
7147+
}
7148+
7149+
return SolutionKind::Solved;
7150+
}
7151+
71157152
case FixKind::UseSubscriptOperator:
71167153
case FixKind::ExplicitlyEscaping:
71177154
case FixKind::CoerceToCheckedCast:

0 commit comments

Comments
 (0)