Skip to content

Commit c74824e

Browse files
committed
[CSDiagnostics] Diagnose situations when value pack expansion does expect a tuple argument
Diagnose situation when a single argument to tuple type is passed to a value pack expansion parameter that expects distinct N elements: ```swift struct S<each T> { func test(x: Int, _: repeat each T) {} } S<Int, String>().test(x: 42, (2, "b")) ```
1 parent b9ef2ca commit c74824e

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5423,6 +5423,14 @@ ERROR(tuple_duplicate_label,none,
54235423
"cannot create a tuple with a duplicate element label", ())
54245424
ERROR(multiple_ellipsis_in_tuple,none,
54255425
"only a single element can be variadic", ())
5426+
ERROR(cannot_convert_tuple_into_pack_expansion_parameter,none,
5427+
"value pack expansion at parameter #%0 expects %1 separate arguments"
5428+
"%select{|; remove extra parentheses to change tuple into separate arguments}2",
5429+
(unsigned, unsigned, bool))
5430+
NOTE(cannot_convert_tuple_into_pack_expansion_parameter_note,none,
5431+
"value pack expansion at parameter #%0 expects %1 separate arguments",
5432+
(unsigned, unsigned))
5433+
54265434

54275435
ERROR(expansion_not_same_shape,none,
54285436
"pack expansion %0 requires that %1 and %2 have the same shape",

lib/Sema/CSDiagnostics.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8859,3 +8859,45 @@ bool GlobalActorFunctionMismatchFailure::diagnoseAsError() {
88598859
emitDiagnostic(message, getFromType(), getToType());
88608860
return true;
88618861
}
8862+
8863+
bool DestructureTupleToUseWithPackExpansionParameter::diagnoseAsError() {
8864+
auto *locator = getLocator();
8865+
auto argLoc = locator->castLastElementTo<LocatorPathElt::ApplyArgToParam>();
8866+
8867+
{
8868+
auto diagnostic =
8869+
emitDiagnostic(diag::cannot_convert_tuple_into_pack_expansion_parameter,
8870+
argLoc.getParamIdx(), ParamShape->getNumElements(),
8871+
isExpr<TupleExpr>(getAnchor()));
8872+
8873+
if (auto *tupleExpr = getAsExpr<TupleExpr>(getAnchor())) {
8874+
diagnostic.fixItRemove(tupleExpr->getLParenLoc());
8875+
diagnostic.fixItRemove(tupleExpr->getRParenLoc());
8876+
}
8877+
}
8878+
8879+
auto selectedOverload = getCalleeOverloadChoiceIfAvailable(getLocator());
8880+
if (!selectedOverload)
8881+
return true;
8882+
8883+
if (auto *decl = selectedOverload->choice.getDeclOrNull()) {
8884+
emitDiagnosticAt(decl, diag::decl_declared_here, decl->getName());
8885+
}
8886+
8887+
return true;
8888+
}
8889+
8890+
bool DestructureTupleToUseWithPackExpansionParameter::diagnoseAsNote() {
8891+
auto selectedOverload = getCalleeOverloadChoiceIfAvailable(getLocator());
8892+
if (!selectedOverload || !selectedOverload->choice.isDecl())
8893+
return false;
8894+
8895+
auto *choice = selectedOverload->choice.getDecl();
8896+
auto argLoc =
8897+
getLocator()->castLastElementTo<LocatorPathElt::ApplyArgToParam>();
8898+
8899+
emitDiagnosticAt(
8900+
choice, diag::cannot_convert_tuple_into_pack_expansion_parameter_note,
8901+
argLoc.getParamIdx(), ParamShape->getNumElements());
8902+
return true;
8903+
}

lib/Sema/CSDiagnostics.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2976,6 +2976,30 @@ class GlobalActorFunctionMismatchFailure final : public ContextualFailure {
29762976
bool diagnoseTupleElement();
29772977
};
29782978

2979+
/// Diagnose situation when a single argument to tuple type is passed to
2980+
/// a value pack expansion parameter that expects distinct N elements:
2981+
///
2982+
/// ```swift
2983+
/// struct S<each T> {
2984+
/// func test(x: Int, _: repeat each T) {}
2985+
/// }
2986+
///
2987+
/// S<Int, String>().test(x: 42, (2, "b"))
2988+
/// ```
2989+
class DestructureTupleToUseWithPackExpansionParameter final
2990+
: public FailureDiagnostic {
2991+
PackType *ParamShape;
2992+
2993+
public:
2994+
DestructureTupleToUseWithPackExpansionParameter(const Solution &solution,
2995+
PackType *paramShape,
2996+
ConstraintLocator *locator)
2997+
: FailureDiagnostic(solution, locator), ParamShape(paramShape) {}
2998+
2999+
bool diagnoseAsError() override;
3000+
bool diagnoseAsNote() override;
3001+
};
3002+
29793003
} // end namespace constraints
29803004
} // end namespace swift
29813005

0 commit comments

Comments
 (0)