Skip to content

Commit 3c0401c

Browse files
committed
[CSDiagnostics] NFC: Prioritize sequence element over other contextual element diagnostics
1 parent 91c013c commit 3c0401c

File tree

2 files changed

+29
-23
lines changed

2 files changed

+29
-23
lines changed

Diff for: lib/Sema/CSDiagnostics.cpp

+23-23
Original file line numberDiff line numberDiff line change
@@ -5787,6 +5787,29 @@ bool CollectionElementContextualFailure::diagnoseAsError() {
57875787
}
57885788
};
57895789

5790+
if (locator->isForSequenceElementType()) {
5791+
auto purpose = FailureDiagnostic::getContextualTypePurpose(getAnchor());
5792+
// If this is a conversion failure related to binding of `for-each`
5793+
// statement it has to be diagnosed as pattern match if there are
5794+
// holes present in the contextual type.
5795+
if ((purpose == ContextualTypePurpose::CTP_ForEachStmt ||
5796+
purpose == ContextualTypePurpose::CTP_ForEachSequence) &&
5797+
contextualType->hasUnresolvedType()) {
5798+
auto diagnostic = emitDiagnostic(
5799+
(contextualType->is<TupleType>() && !eltType->is<TupleType>())
5800+
? diag::cannot_match_expr_tuple_pattern_with_nontuple_value
5801+
: diag::cannot_match_unresolved_expr_pattern_with_value,
5802+
eltType);
5803+
(void)trySequenceSubsequenceFixIts(diagnostic);
5804+
} else {
5805+
diagnoseSingleElement(contextualType->isExistentialType()
5806+
? diag::cannot_convert_sequence_element_protocol
5807+
: diag::cannot_convert_sequence_element_value,
5808+
eltType, contextualType);
5809+
}
5810+
return true;
5811+
}
5812+
57905813
auto isFixedToDictionary = [&](ArrayExpr *anchor) {
57915814
return llvm::any_of(getSolution().Fixes, [&](ConstraintFix *fix) {
57925815
auto *fixAnchor = getAsExpr<ArrayExpr>(fix->getAnchor());
@@ -5839,29 +5862,6 @@ bool CollectionElementContextualFailure::diagnoseAsError() {
58395862
}
58405863
}
58415864

5842-
if (locator->isForSequenceElementType()) {
5843-
auto purpose = FailureDiagnostic::getContextualTypePurpose(getAnchor());
5844-
// If this is a conversion failure related to binding of `for-each`
5845-
// statement it has to be diagnosed as pattern match if there are
5846-
// holes present in the contextual type.
5847-
if ((purpose == ContextualTypePurpose::CTP_ForEachStmt ||
5848-
purpose == ContextualTypePurpose::CTP_ForEachSequence) &&
5849-
contextualType->hasUnresolvedType()) {
5850-
auto diagnostic = emitDiagnostic(
5851-
(contextualType->is<TupleType>() && !eltType->is<TupleType>())
5852-
? diag::cannot_match_expr_tuple_pattern_with_nontuple_value
5853-
: diag::cannot_match_unresolved_expr_pattern_with_value,
5854-
eltType);
5855-
(void)trySequenceSubsequenceFixIts(diagnostic);
5856-
} else {
5857-
diagnoseSingleElement(contextualType->isExistentialType()
5858-
? diag::cannot_convert_sequence_element_protocol
5859-
: diag::cannot_convert_sequence_element_value,
5860-
eltType, contextualType);
5861-
}
5862-
return true;
5863-
}
5864-
58655865
return false;
58665866
}
58675867

Diff for: test/stmt/foreach.swift

+6
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,9 @@ do {
262262
for (x, y) in (0, 0) {}
263263
// expected-error@-1 {{for-in loop requires '(Int, Int)' to conform to 'Sequence'}}
264264
}
265+
266+
// rdar://100343275 - Sema is accepting incorrect code which leads to a crash in SILGen
267+
do {
268+
for (x, y, z) in [] { // expected-error {{tuple pattern cannot match values of non-tuple type 'Any'}}
269+
}
270+
}

0 commit comments

Comments
 (0)