diff --git a/lib/Sema/CSBindings.cpp b/lib/Sema/CSBindings.cpp index f23248160de..64e2b304bee 100644 --- a/lib/Sema/CSBindings.cpp +++ b/lib/Sema/CSBindings.cpp @@ -2550,14 +2550,12 @@ TypeVariableBinding::fixForHole(ConstraintSystem &cs) const { } if (dstLocator->isLastElement()) { - // A hole appears as an element of generic pack params ConstraintFix *Fix = SpecifyPackElementType::create(cs, dstLocator); return std::make_pair(Fix, defaultImpact); } return std::nullopt; - return std::nullopt; } bool TypeVariableBinding::attempt(ConstraintSystem &cs) const { diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index 8a2bb54d1c0..e03c4ff4d8b 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -8188,49 +8188,46 @@ bool UnableToInferClosureReturnType::diagnoseAsError() { } bool UnableToInferGenericPackElementType::diagnoseAsError() { - - const auto* locator = getLocator(); + auto *locator = getLocator(); auto path = locator->getPath(); - if (path.size() > 1) { - - const auto applyArgToParamElt = (path.end() - 2)->getAs(); - const auto packElementElt = (path.end() - 1)->getAs(); - - if (!applyArgToParamElt) - return false; - - auto anchor = getAnchor(); - - // `nil` appears as an element of generic pack params, let's record a - // specify contextual type for nil fix. - if (isExpr(anchor)) { - emitDiagnostic(diag::unresolved_nil_literal); - } - else { - // unable to infer the type of an element of generic pack params - emitDiagnostic(diag::could_not_infer_pack_element, packElementElt->getIndex()); - } - - // emit callee side diagnostics - auto applyExpr = castToExpr(locator->getAnchor()); - if (auto* Fn = applyExpr->getFn()) { - if (const auto DeclRef = Fn->getReferencedDecl()) { - auto paramDecl = getParameterAt(DeclRef, applyArgToParamElt->getParamIdx()); - emitDiagnosticAt( - paramDecl->getLoc(), diag::note_in_opening_pack_element, - packElementElt->getIndex() + 1, paramDecl->getNameStr()); - } - } - - return true; + const auto applyArgToParamElt = + (path.end() - 2)->getAs(); + const auto packElementElt = + (path.end() - 1)->getAs(); + if (!applyArgToParamElt || !packElementElt) { + return false; } - return false; + if (isExpr(getAnchor())) { + // `nil` appears as an element of generic pack params, let's record a + // specify contextual type for nil fix. + emitDiagnostic(diag::unresolved_nil_literal); + } else { + // unable to infer the type of an element of generic pack params + emitDiagnostic(diag::could_not_infer_pack_element, + packElementElt->getIndex()); + } + + if (isExpr(locator->getAnchor())) { + // emit callee side diagnostics + if (auto *calleeLocator = getSolution().getCalleeLocator(locator)) { + if (const auto choice = getOverloadChoiceIfAvailable(calleeLocator)) { + if (auto *decl = choice->choice.getDeclOrNull()) { + if (auto paramDecl = + getParameterAt(decl, applyArgToParamElt->getParamIdx())) { + emitDiagnosticAt( + paramDecl->getLoc(), diag::note_in_opening_pack_element, + packElementElt->getIndex() + 1, paramDecl->getNameStr()); + } + } + } + } + } + + return true; } - - static std::pair getImportModuleAndDefaultType(const ASTContext &ctx, const ObjectLiteralExpr *expr) { diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp index 9c7eac79f30..1273fcaa479 100644 --- a/lib/Sema/ConstraintSystem.cpp +++ b/lib/Sema/ConstraintSystem.cpp @@ -5881,28 +5881,24 @@ void constraints::simplifyLocator(ASTNode &anchor, if (!elt) break; - // If the 3rd element is an PackElement, add the index of pack element within - // packs to locate the correct element. - bool hasEltPack = false; - unsigned eltPackIdx = 0; + // If the 3rd element is an PackElement, add the index of pack element + // within packs to locate the correct element. + std::optional eltPackIdx; if (path.size() > 2) { - auto eltPack = path[2].getAs(); - if (eltPack) { - hasEltPack = true; + if (auto eltPack = path[2].getAs()) { eltPackIdx = eltPack->getIndex(); } } // Extract application argument. if (auto *args = anchorExpr->getArgs()) { - if (hasEltPack) { - if (elt->getArgIdx() + eltPackIdx < args->size()) { - anchor = args->getExpr(elt->getArgIdx() + eltPackIdx); + if (eltPackIdx.has_value()) { + if (elt->getArgIdx() + eltPackIdx.value() < args->size()) { + anchor = args->getExpr(elt->getArgIdx() + eltPackIdx.value()); path = path.slice(3); continue; } - } - else if (elt->getArgIdx() < args->size()) { + } else if (elt->getArgIdx() < args->size()) { anchor = args->getExpr(elt->getArgIdx()); path = path.slice(2); continue; diff --git a/test/Constraints/variadic_generic_functions.swift b/test/Constraints/variadic_generic_functions.swift index a95b37ee52d..878e41d0261 100644 --- a/test/Constraints/variadic_generic_functions.swift +++ b/test/Constraints/variadic_generic_functions.swift @@ -97,4 +97,11 @@ do { bar(1, 2, 3, nil, "Hello", u: 3, w: 4, 8, nil) // expected-error {{'nil' requires a contextual type}} // expected-error@-1 {{'nil' requires a contextual type}} + + func fooWithOverload(_ value: Int) {} + func fooWithOverload(_ value: repeat each T) {} + // expected-note@-1 {{in inferring pack element #5 of 'value'}} + + fooWithOverload(0, 1, 2, 3, nil) // expected-error {{'nil' requires a contextual type}} + } \ No newline at end of file