Skip to content

Commit 50abedd

Browse files
committed
[Diagnostics] Keep track of the indices of the tuple elements whose
types do not match in AllowTupleTypeMismatch/TupleContextualFailure.
1 parent 1e013a0 commit 50abedd

File tree

4 files changed

+41
-10
lines changed

4 files changed

+41
-10
lines changed

lib/Sema/CSDiagnostics.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -830,10 +830,16 @@ class InvalidUseOfAddressOf final : public ContextualFailure {
830830

831831
/// Diagnose mismatches relating to tuple destructuring.
832832
class TupleContextualFailure final : public ContextualFailure {
833+
/// Indices of the tuple elements whose types do not match.
834+
llvm::SmallVector<unsigned, 4> Indices;
835+
833836
public:
834837
TupleContextualFailure(ConstraintSystem &cs, ContextualTypePurpose purpose,
835-
Type lhs, Type rhs, ConstraintLocator *locator)
836-
: ContextualFailure(cs, purpose, lhs, rhs, locator) {
838+
Type lhs, Type rhs, llvm::ArrayRef<unsigned> indices,
839+
ConstraintLocator *locator)
840+
: ContextualFailure(cs, purpose, lhs, rhs, locator),
841+
Indices(indices.begin(), indices.end()) {
842+
std::sort(Indices.begin(), Indices.end());
837843
assert(getFromType()->is<TupleType>() && getToType()->is<TupleType>());
838844
}
839845

lib/Sema/CSFix.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,17 @@ ContextualMismatch *ContextualMismatch::create(ConstraintSystem &cs, Type lhs,
257257

258258
bool AllowTupleTypeMismatch::coalesceAndDiagnose(
259259
ArrayRef<ConstraintFix *> fixes, bool asNote) const {
260+
llvm::SmallVector<unsigned, 4> indices;
261+
if (isElementMismatch())
262+
indices.push_back(*Index);
263+
264+
for (auto fix : fixes) {
265+
auto *tupleFix = fix->getAs<AllowTupleTypeMismatch>();
266+
if (!tupleFix || !tupleFix->isElementMismatch())
267+
continue;
268+
indices.push_back(*tupleFix->Index);
269+
}
270+
260271
auto &cs = getConstraintSystem();
261272
auto *locator = getLocator();
262273
auto purpose = cs.getContextualTypePurpose();
@@ -288,7 +299,7 @@ bool AllowTupleTypeMismatch::coalesceAndDiagnose(
288299
return false;
289300
}
290301

291-
TupleContextualFailure failure(cs, purpose, fromType, toType, locator);
302+
TupleContextualFailure failure(cs, purpose, fromType, toType, indices, locator);
292303
return failure.diagnose(asNote);
293304
}
294305

@@ -298,8 +309,10 @@ bool AllowTupleTypeMismatch::diagnose(bool asNote) const {
298309

299310
AllowTupleTypeMismatch *
300311
AllowTupleTypeMismatch::create(ConstraintSystem &cs, Type lhs, Type rhs,
301-
ConstraintLocator *locator) {
302-
return new (cs.getAllocator()) AllowTupleTypeMismatch(cs, lhs, rhs, locator);
312+
ConstraintLocator *locator,
313+
Optional<unsigned> index) {
314+
return new (cs.getAllocator())
315+
AllowTupleTypeMismatch(cs, lhs, rhs, locator, index);
303316
}
304317

305318
bool GenericArgumentsMismatch::diagnose(bool asNote) const {

lib/Sema/CSFix.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -954,14 +954,20 @@ class AllowInvalidInitRef final : public ConstraintFix {
954954
};
955955

956956
class AllowTupleTypeMismatch final : public ContextualMismatch {
957+
/// If this is an element mismatch, \c Index is the element index where the
958+
/// type mismatch occurred. If this is an arity or label mismatch, \c Index
959+
/// will be \c None.
960+
Optional<unsigned> Index;
961+
957962
AllowTupleTypeMismatch(ConstraintSystem &cs, Type lhs, Type rhs,
958-
ConstraintLocator *locator)
963+
ConstraintLocator *locator, Optional<unsigned> index)
959964
: ContextualMismatch(cs, FixKind::AllowTupleTypeMismatch, lhs, rhs,
960-
locator) {}
965+
locator), Index(index) {}
961966

962967
public:
963968
static AllowTupleTypeMismatch *create(ConstraintSystem &cs, Type lhs,
964-
Type rhs, ConstraintLocator *locator);
969+
Type rhs, ConstraintLocator *locator,
970+
Optional<unsigned> index = None);
965971

966972
static bool classof(const ConstraintFix *fix) {
967973
return fix->getKind() == FixKind::AllowTupleTypeMismatch;
@@ -971,6 +977,10 @@ class AllowTupleTypeMismatch final : public ContextualMismatch {
971977
return "fix tuple mismatches in type and arity";
972978
}
973979

980+
bool isElementMismatch() const {
981+
return Index.hasValue();
982+
}
983+
974984
bool coalesceAndDiagnose(ArrayRef<ConstraintFix *> secondaryFixes,
975985
bool asNote = false) const override;
976986

lib/Sema/CSSimplify.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3536,7 +3536,9 @@ bool ConstraintSystem::repairFailures(
35363536
tupleLocator->isLastElement<LocatorPathElt::SequenceElementType>())
35373537
break;
35383538

3539-
auto *fix = AllowTupleTypeMismatch::create(*this, lhs, rhs, tupleLocator);
3539+
auto index = elt.getAs<LocatorPathElt::TupleElement>()->getIndex();
3540+
auto *fix =
3541+
AllowTupleTypeMismatch::create(*this, lhs, rhs, tupleLocator, index);
35403542
conversionsOrFixes.push_back(fix);
35413543
break;
35423544
}
@@ -8435,7 +8437,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
84358437
}
84368438

84378439
case FixKind::AllowTupleTypeMismatch: {
8438-
if (!(type1->is<TupleType>() && type2->is<TupleType>())) {
8440+
if (fix->getAs<AllowTupleTypeMismatch>()->isElementMismatch()) {
84398441
auto *locator = fix->getLocator();
84408442
if (recordFix(fix, /*impact*/locator->isForContextualType() ? 5 : 1))
84418443
return SolutionKind::Error;

0 commit comments

Comments
 (0)