Skip to content

Commit b90e579

Browse files
authored
Merge pull request swiftlang#32001 from LucianoPAlmeida/SR-12869-tuple-mismatch-crash
[SR-12869] [Diagnostics] Fixes assertion hit on TupleContextualFailure involving optional tuple type
2 parents 889e84a + e43cd9d commit b90e579

File tree

3 files changed

+40
-9
lines changed

3 files changed

+40
-9
lines changed

lib/Sema/CSFix.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,11 @@ getStructuralTypeContext(const Solution &solution, ConstraintLocator *locator) {
287287
solution.getType(coerceExpr->getSubExpr()),
288288
solution.getType(coerceExpr));
289289
} else if (auto *assignExpr = getAsExpr<AssignExpr>(locator->getAnchor())) {
290-
return std::make_tuple(CTP_AssignSource,
290+
auto CTP = isa<SubscriptExpr>(assignExpr->getDest()) ? CTP_SubscriptAssignSource
291+
: CTP_AssignSource;
292+
return std::make_tuple(CTP,
291293
solution.getType(assignExpr->getSrc()),
292-
solution.getType(assignExpr->getDest()));
294+
solution.getType(assignExpr->getDest())->getRValueType());
293295
} else if (auto *call = getAsExpr<CallExpr>(locator->getAnchor())) {
294296
assert(isa<TypeExpr>(call->getFn()));
295297
return std::make_tuple(
@@ -332,8 +334,10 @@ bool AllowTupleTypeMismatch::coalesceAndDiagnose(
332334
return false;
333335
}
334336

335-
TupleContextualFailure failure(solution, purpose, fromType, toType, indices,
336-
locator);
337+
TupleContextualFailure failure(solution, purpose,
338+
fromType->lookThroughAllOptionalTypes(),
339+
toType->lookThroughAllOptionalTypes(),
340+
indices, locator);
337341
return failure.diagnose(asNote);
338342
}
339343

lib/Sema/CSSimplify.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3356,13 +3356,18 @@ bool ConstraintSystem::repairFailures(
33563356
// related to immutability, otherwise it's a type mismatch.
33573357
auto result = matchTypes(lhs, rhs, ConstraintKind::Conversion,
33583358
TMF_ApplyingFix, locator);
3359-
3359+
3360+
auto *loc = getConstraintLocator(locator);
33603361
if (getType(destExpr)->is<LValueType>() || result.isFailure()) {
3361-
conversionsOrFixes.push_back(IgnoreAssignmentDestinationType::create(
3362-
*this, lhs, rhs, getConstraintLocator(locator)));
3363-
} else {
3362+
// Let this asignment failure be diagnosed by the AllowTupleTypeMismatch
3363+
// fix already recorded.
3364+
if (hasFixFor(loc, FixKind::AllowTupleTypeMismatch))
3365+
return true;
3366+
33643367
conversionsOrFixes.push_back(
3365-
TreatRValueAsLValue::create(*this, getConstraintLocator(locator)));
3368+
IgnoreAssignmentDestinationType::create(*this, lhs, rhs, loc));
3369+
} else {
3370+
conversionsOrFixes.push_back(TreatRValueAsLValue::create(*this, loc));
33663371
}
33673372

33683373
return true;
@@ -8865,6 +8870,11 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
88658870
CoerceToCheckedCast::attempt(*this, fromType, toType, loc))
88668871
return !recordFix(fix, impact);
88678872
}
8873+
8874+
// We already have a fix for this locator indicating a
8875+
// tuple mismatch.
8876+
if (hasFixFor(loc, FixKind::AllowTupleTypeMismatch))
8877+
return true;
88688878

88698879
if (restriction == ConversionRestrictionKind::ValueToOptional ||
88708880
restriction == ConversionRestrictionKind::OptionalToOptional)

test/Constraints/tuple.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,3 +318,20 @@ struct DupLabelSubscript {
318318

319319
let dupLabelSubscriptStruct = DupLabelSubscript()
320320
let _ = dupLabelSubscriptStruct[foo: 5, foo: 5] // ok
321+
322+
// SR-12869
323+
324+
var dict: [String: (Int, Int)] = [:]
325+
let bignum: Int64 = 1337
326+
dict["test"] = (bignum, 1) // expected-error {{cannot assign value of type '(Int64, Int)' to subscript of type '(Int, Int)'}}
327+
328+
var tuple: (Int, Int)
329+
tuple = (bignum, 1) // expected-error {{cannot assign value of type '(Int64, Int)' to type '(Int, Int)'}}
330+
331+
var optionalTuple: (Int, Int)?
332+
var optionalTuple2: (Int64, Int)? = (bignum, 1)
333+
var optionalTuple3: (UInt64, Int)? = (bignum, 1) // expected-error {{cannot convert value of type '(Int64, Int)' to specified type '(UInt64, Int)?'}}
334+
335+
optionalTuple = (bignum, 1) // expected-error {{cannot assign value of type '(Int64, Int)' to type '(Int, Int)'}}
336+
// Optional to Optional
337+
optionalTuple = optionalTuple2 // expected-error {{cannot assign value of type '(Int64, Int)?' to type '(Int, Int)?'}}

0 commit comments

Comments
 (0)