diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index d12b61b251394..6a0ec73300919 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -253,6 +253,10 @@ ERROR(no_candidates_match_result_type,none, "no '%0' candidates produce the expected contextual result type %1", (StringRef, Type)) +ERROR(no_candidates_match_argument_type,none, + "no '%0' candidates produce the expected type %1 for parameter #%2", + (StringRef, Type, unsigned)) + ERROR(cannot_infer_closure_parameter_type,none, "unable to infer type of a closure parameter %0 in the current context", (StringRef)) diff --git a/lib/Sema/CSFix.cpp b/lib/Sema/CSFix.cpp index d638fb8c9e10d..409cd6129f40b 100644 --- a/lib/Sema/CSFix.cpp +++ b/lib/Sema/CSFix.cpp @@ -252,6 +252,33 @@ bool ContextualMismatch::diagnose(const Solution &solution, bool asNote) const { return failure.diagnose(asNote); } +bool ContextualMismatch::diagnoseForAmbiguity( + CommonFixesArray commonFixes) const { + auto getTypes = + [&](const std::pair &entry) + -> std::pair { + auto &solution = *entry.first; + auto *fix = static_cast(entry.second); + + return {solution.simplifyType(fix->getFromType()), + solution.simplifyType(fix->getToType())}; + }; + + auto etalonTypes = getTypes(commonFixes.front()); + if (llvm::all_of( + commonFixes, + [&](const std::pair &entry) { + auto types = getTypes(entry); + return etalonTypes.first->isEqual(types.first) && + etalonTypes.second->isEqual(types.second); + })) { + const auto &primary = commonFixes.front(); + return primary.second->diagnose(*primary.first, /*asNote=*/false); + } + + return false; +} + ContextualMismatch *ContextualMismatch::create(ConstraintSystem &cs, Type lhs, Type rhs, ConstraintLocator *locator) { @@ -381,6 +408,57 @@ bool AllowFunctionTypeMismatch::diagnose(const Solution &solution, return coalesceAndDiagnose(solution, {}, asNote); } +bool AllowFunctionTypeMismatch::diagnoseForAmbiguity( + CommonFixesArray commonFixes) const { + if (ContextualMismatch::diagnoseForAmbiguity(commonFixes)) + return true; + + auto *locator = getLocator(); + // If this is a mismatch between two function types at argument + // position, there is a tailored diagnostic for that. + if (auto argConv = + locator->getLastElementAs()) { + auto &cs = getConstraintSystem(); + auto &DE = cs.getASTContext().Diags; + auto &solution = *commonFixes[0].first; + + auto info = getStructuralTypeContext(solution, locator); + if (!info) + return false; + + auto *argLoc = cs.getConstraintLocator(simplifyLocatorToAnchor(locator)); + + auto overload = solution.getOverloadChoiceIfAvailable( + solution.getCalleeLocator(argLoc)); + if (!overload) + return false; + + auto name = overload->choice.getName().getBaseName(); + DE.diagnose(getLoc(getAnchor()), diag::no_candidates_match_argument_type, + name.userFacingName(), std::get<2>(*info), + argConv->getParamIdx()); + + for (auto &entry : commonFixes) { + auto &solution = *entry.first; + auto overload = solution.getOverloadChoiceIfAvailable( + solution.getCalleeLocator(argLoc)); + + if (!(overload && overload->choice.isDecl())) + continue; + + auto *decl = overload->choice.getDecl(); + if (decl->getLoc().isValid()) { + DE.diagnose(decl, diag::found_candidate_type, + solution.simplifyType(overload->openedType)); + } + } + + return true; + } + + return false; +} + AllowFunctionTypeMismatch * AllowFunctionTypeMismatch::create(ConstraintSystem &cs, Type lhs, Type rhs, ConstraintLocator *locator, unsigned index) { @@ -867,14 +945,19 @@ RemoveAddressOf *RemoveAddressOf::create(ConstraintSystem &cs, Type lhs, Type rh return new (cs.getAllocator()) RemoveAddressOf(cs, lhs, rhs, locator); } +RemoveReturn::RemoveReturn(ConstraintSystem &cs, Type resultTy, + ConstraintLocator *locator) + : ContextualMismatch(cs, FixKind::RemoveReturn, resultTy, + cs.getASTContext().TheEmptyTupleType, locator) {} + bool RemoveReturn::diagnose(const Solution &solution, bool asNote) const { ExtraneousReturnFailure failure(solution, getLocator()); return failure.diagnose(asNote); } -RemoveReturn *RemoveReturn::create(ConstraintSystem &cs, +RemoveReturn *RemoveReturn::create(ConstraintSystem &cs, Type resultTy, ConstraintLocator *locator) { - return new (cs.getAllocator()) RemoveReturn(cs, locator); + return new (cs.getAllocator()) RemoveReturn(cs, resultTy, locator); } bool CollectionElementContextualMismatch::diagnose(const Solution &solution, @@ -1079,6 +1162,43 @@ bool IgnoreAssignmentDestinationType::diagnose(const Solution &solution, return failure.diagnose(asNote); } +bool IgnoreAssignmentDestinationType::diagnoseForAmbiguity( + CommonFixesArray commonFixes) const { + auto &cs = getConstraintSystem(); + + // If all of the types are the same let's try to diagnose + // this as if there is no ambiguity. + if (ContextualMismatch::diagnoseForAmbiguity(commonFixes)) + return true; + + auto *commonLocator = getLocator(); + auto *assignment = castToExpr(commonLocator->getAnchor()); + + auto &solution = *commonFixes.front().first; + auto *calleeLocator = solution.getCalleeLocator( + solution.getConstraintLocator(assignment->getSrc())); + auto overload = solution.getOverloadChoiceIfAvailable(calleeLocator); + if (!overload) + return false; + + auto memberName = overload->choice.getName().getBaseName(); + auto destType = solution.getType(assignment->getDest()); + + auto &DE = cs.getASTContext().Diags; + // TODO(diagnostics): It might be good to add a tailored diagnostic + // for cases like this instead of using "contextual" one. + DE.diagnose(assignment->getSrc()->getLoc(), + diag::no_candidates_match_result_type, + memberName.userFacingName(), + solution.simplifyType(destType)->getRValueType()); + + for (auto &entry : commonFixes) { + entry.second->diagnose(*entry.first, /*asNote=*/true); + } + + return true; +} + IgnoreAssignmentDestinationType * IgnoreAssignmentDestinationType::create(ConstraintSystem &cs, Type sourceTy, Type destTy, diff --git a/lib/Sema/CSFix.h b/lib/Sema/CSFix.h index 191bfd7170dcf..bd3cdf8233c5a 100644 --- a/lib/Sema/CSFix.h +++ b/lib/Sema/CSFix.h @@ -369,6 +369,10 @@ class TreatRValueAsLValue final : public ConstraintFix { bool diagnose(const Solution &solution, bool asNote = false) const override; + bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override { + return diagnose(*commonFixes.front().first); + } + static TreatRValueAsLValue *create(ConstraintSystem &cs, ConstraintLocator *locator); }; @@ -522,6 +526,8 @@ class ContextualMismatch : public ConstraintFix { bool diagnose(const Solution &solution, bool asNote = false) const override; + bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override; + static ContextualMismatch *create(ConstraintSystem &cs, Type lhs, Type rhs, ConstraintLocator *locator); }; @@ -798,6 +804,10 @@ class UsePropertyWrapper final : public ConstraintFix { bool diagnose(const Solution &solution, bool asNote = false) const override; + bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override { + return diagnose(*commonFixes.front().first); + } + static UsePropertyWrapper *create(ConstraintSystem &cs, VarDecl *wrapped, bool usingStorageWrapper, Type base, Type wrapper, ConstraintLocator *locator); @@ -825,6 +835,10 @@ class UseWrappedValue final : public ConstraintFix { bool diagnose(const Solution &solution, bool asNote = false) const override; + bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override { + return diagnose(*commonFixes.front().first); + } + static UseWrappedValue *create(ConstraintSystem &cs, VarDecl *propertyWrapper, Type base, Type wrapper, ConstraintLocator *locator); @@ -1103,6 +1117,8 @@ class AllowFunctionTypeMismatch final : public ContextualMismatch { bool asNote = false) const override; bool diagnose(const Solution &solution, bool asNote = false) const override; + + bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override; }; @@ -1399,16 +1415,16 @@ class AllowInvalidRefInKeyPath final : public ConstraintFix { ConstraintLocator *locator); }; -class RemoveReturn final : public ConstraintFix { - RemoveReturn(ConstraintSystem &cs, ConstraintLocator *locator) - : ConstraintFix(cs, FixKind::RemoveReturn, locator) {} +class RemoveReturn final : public ContextualMismatch { + RemoveReturn(ConstraintSystem &cs, Type resultTy, ConstraintLocator *locator); public: std::string getName() const override { return "remove or omit return type"; } bool diagnose(const Solution &solution, bool asNote = false) const override; - static RemoveReturn *create(ConstraintSystem &cs, ConstraintLocator *locator); + static RemoveReturn *create(ConstraintSystem &cs, Type resultTy, + ConstraintLocator *locator); }; class CollectionElementContextualMismatch final : public ContextualMismatch { @@ -1527,10 +1543,6 @@ class IgnoreContextualType : public ContextualMismatch { bool diagnose(const Solution &solution, bool asNote = false) const override; - bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override { - return diagnose(*commonFixes.front().first); - } - static IgnoreContextualType *create(ConstraintSystem &cs, Type resultTy, Type specifiedTy, ConstraintLocator *locator); @@ -1548,6 +1560,8 @@ class IgnoreAssignmentDestinationType final : public ContextualMismatch { bool diagnose(const Solution &solution, bool asNote = false) const override; + bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override; + static IgnoreAssignmentDestinationType *create(ConstraintSystem &cs, Type sourceTy, Type destTy, ConstraintLocator *locator); diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index bea9edfe9a55b..8c7f818476d1d 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -1449,6 +1449,20 @@ assessRequirementFailureImpact(ConstraintSystem &cs, Type requirementType, if (!anchor) return impact; + // If this is a conditional requirement failure associated with a + // call, let's increase impact of the fix to show that such failure + // makes member/function unreachable in current context or with + // given arguments. + if (auto last = locator.last()) { + if (last->isConditionalRequirement()) { + if (auto *expr = getAsExpr(anchor)) { + auto *parent = cs.getParentExpr(expr); + if (parent && isa(parent)) + return 5; + } + } + } + // If this requirement is associated with a member reference and it // was possible to check it before overload choice is bound, that means // types came from the context (most likely Self, or associated type(s)) @@ -1475,9 +1489,12 @@ assessRequirementFailureImpact(ConstraintSystem &cs, Type requirementType, return 10; } - // Increase the impact of a conformance fix for a standard library type, - // as it's unlikely to be a good suggestion. Also do the same for the builtin - // compiler types Any and AnyObject, which cannot conform to protocols. + // Increase the impact of a conformance fix for a standard library + // or foundation type, as it's unlikely to be a good suggestion. + // + // Also do the same for the builtin compiler types Any and AnyObject, + // which cannot conform to protocols. + // // FIXME: We ought not to have the is() condition here, but // removing it currently regresses the diagnostic for the test case for // rdar://60727310. Once we better handle the separation of conformance fixes @@ -1485,7 +1502,8 @@ assessRequirementFailureImpact(ConstraintSystem &cs, Type requirementType, // remove it from the condition. auto resolvedTy = cs.simplifyType(requirementType); if ((requirementType->is() && resolvedTy->isStdlibType()) || - resolvedTy->isAny() || resolvedTy->isAnyObject()) { + resolvedTy->isAny() || resolvedTy->isAnyObject() || + getKnownFoundationEntity(resolvedTy->getString())) { if (auto last = locator.last()) { if (auto requirement = last->getAs()) { auto kind = requirement->getRequirementKind(); @@ -3863,11 +3881,16 @@ bool ConstraintSystem::repairFailures( if (lhs->isTypeVariableOrMember() || rhs->isTypeVariableOrMember()) break; + // If there is already a fix for contextual failure, let's not + // record a duplicate one. + if (hasFixFor(getConstraintLocator(locator))) + return true; + auto purpose = getContextualTypePurpose(anchor); if (rhs->isVoid() && (purpose == CTP_ReturnStmt || purpose == CTP_ReturnSingleExpr)) { conversionsOrFixes.push_back( - RemoveReturn::create(*this, getConstraintLocator(locator))); + RemoveReturn::create(*this, lhs, getConstraintLocator(locator))); return true; } diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp index 7b28796ae60b1..f00bf468baddc 100644 --- a/lib/Sema/ConstraintSystem.cpp +++ b/lib/Sema/ConstraintSystem.cpp @@ -2719,6 +2719,11 @@ SolutionResult ConstraintSystem::salvage() { // Solve the system. solveImpl(viable); + // Before removing any "fixed" solutions, let's check + // if ambiguity is caused by fixes and diagnose if possible. + if (diagnoseAmbiguityWithFixes(viable)) + return SolutionResult::forAmbiguous(viable); + // Check whether we have a best solution; this can happen if we found // a series of fixes that worked. if (auto best = findBestSolution(viable, /*minimize=*/true)) { @@ -2728,11 +2733,6 @@ SolutionResult ConstraintSystem::salvage() { return SolutionResult::forSolved(std::move(viable[0])); } - // Before removing any "fixed" solutions, let's check - // if ambiguity is caused by fixes and diagnose if possible. - if (diagnoseAmbiguityWithFixes(viable)) - return SolutionResult::forAmbiguous(viable); - // FIXME: If we were able to actually fix things along the way, // we may have to hunt for the best solution. For now, we don't care. @@ -2775,7 +2775,8 @@ static void diagnoseOperatorAmbiguity(ConstraintSystem &cs, Identifier operatorName, ArrayRef solutions, ConstraintLocator *locator) { - auto &DE = cs.getASTContext().Diags; + auto &ctx = cs.getASTContext(); + auto &DE = ctx.Diags; auto *anchor = castToExpr(locator->getAnchor()); auto *applyExpr = cast(cs.getParentExpr(anchor)); @@ -2814,6 +2815,9 @@ static void diagnoseOperatorAmbiguity(ConstraintSystem &cs, operatorName.str()); return; } + } else if (operatorName == ctx.Id_MatchOperator) { + DE.diagnose(anchor->getLoc(), diag::cannot_match_expr_pattern_with_value, + lhsType, rhsType); } else { DE.diagnose(anchor->getLoc(), diag::cannot_apply_binop_to_args, operatorName.str(), lhsType, rhsType) @@ -3062,104 +3066,129 @@ diagnoseAmbiguityWithEphemeralPointers(ConstraintSystem &cs, return cs.diagnoseAmbiguity(solutions); } -bool ConstraintSystem::diagnoseAmbiguityWithFixes( - SmallVectorImpl &solutions) { - if (solutions.empty()) +static bool diagnoseAmbiguityWithContextualType( + ConstraintSystem &cs, SolutionDiff &solutionDiff, + ArrayRef> aggregateFix, + ArrayRef solutions) { + // Diagnose only if contextual failure is associated with every solution. + if (aggregateFix.size() < solutions.size()) return false; - SolutionDiff solutionDiff(solutions); + auto getResultType = + [](const std::pair &entry) + -> Type { + auto &solution = *entry.first; + auto anchor = entry.second->getLocator()->getAnchor(); + return solution.simplifyType(solution.getType(anchor)); + }; - if (diagnoseConflictingGenericArguments(*this, solutionDiff, solutions)) - return true; - - if (auto bestScore = solverState->BestScore) { - solutions.erase(llvm::remove_if(solutions, - [&](const Solution &solution) { - return solution.getFixedScore() > - *bestScore; - }), - solutions.end()); + auto resultType = getResultType(aggregateFix.front()); + // If right-hand side of the conversion (result of the the AST node) + // is the same across all of the solutions let's diagnose it as if + // it it as a single failure. + if (llvm::all_of( + aggregateFix, + [&](const std::pair &entry) { + return resultType->isEqual(getResultType(entry)); + })) { + auto &fix = aggregateFix.front(); + return fix.second->diagnose(*fix.first, /*asNote=*/false); + } + + // If result types are different it could only mean that this is an attempt + // to convert a reference to, or call of overloaded declaration to a + // particular type. + + auto &solution = *aggregateFix.front().first; + auto *locator = aggregateFix.front().second->getLocator(); + auto *calleeLocator = solution.getCalleeLocator(locator); + + auto result = + llvm::find_if(solutionDiff.overloads, + [&calleeLocator](const SolutionDiff::OverloadDiff &entry) { + return entry.locator == calleeLocator; + }); + + if (result == solutionDiff.overloads.end()) + return false; - if (llvm::all_of(solutions, [&](const Solution &solution) { - auto score = solution.getFixedScore(); - return score.Data[SK_Fix] == 0 && solution.Fixes.empty(); - })) - return false; - } + auto &DE = cs.getASTContext().Diags; - if (diagnoseAmbiguityWithEphemeralPointers(*this, solutions)) - return true; + auto anchor = locator->getAnchor(); + auto name = result->choices.front().getName(); + DE.diagnose(getLoc(anchor), diag::no_candidates_match_result_type, + name.getBaseName().userFacingName(), + cs.getContextualType(anchor)); - // Collect aggregated fixes from all solutions - using LocatorAndKind = std::pair; - using SolutionAndFix = std::pair; - llvm::SmallMapVector, 4> - aggregatedFixes; for (const auto &solution : solutions) { - for (const auto *fix : solution.Fixes) { - LocatorAndKind key(fix->getLocator(), fix->getKind()); - aggregatedFixes[key].emplace_back(&solution, fix); + auto overload = solution.getOverloadChoice(calleeLocator); + if (auto *decl = overload.choice.getDeclOrNull()) { + auto loc = decl->getLoc(); + if (loc.isInvalid()) + continue; + + auto type = solution.simplifyType(overload.boundType); + + if (isExpr(anchor) || isExpr(anchor) || + (isExpr(anchor) && + castToExpr(anchor)->hasArguments())) { + auto fnType = type->castTo(); + DE.diagnose( + loc, diag::cannot_convert_candidate_result_to_contextual_type, + decl->getName(), fnType->getResult(), cs.getContextualType(anchor)); + } else { + DE.diagnose(loc, diag::found_candidate_type, type); + } } } - // If there is an overload difference, let's see if there's a common callee - // locator for all of the fixes. - auto ambiguousOverload = llvm::find_if(solutionDiff.overloads, - [&](const auto &overloadDiff) { - return llvm::all_of(aggregatedFixes, [&](const auto &aggregatedFix) { - auto *locator = aggregatedFix.first.first; - auto anchor = locator->getAnchor(); - // Assignment failures are all about the source expression, because - // they treat destination as a contextual type. - if (auto *assignExpr = getAsExpr(anchor)) - anchor = assignExpr->getSrc(); - - if (auto *callExpr = getAsExpr(anchor)) { - if (!isa(callExpr->getDirectCallee())) - anchor = callExpr->getDirectCallee(); - } else if (auto *applyExpr = getAsExpr(anchor)) { - anchor = applyExpr->getFn(); - } + return true; +} - return overloadDiff.locator->getAnchor() == anchor; - }); - }); +static bool diagnoseAmbiguity( + ConstraintSystem &cs, const SolutionDiff::OverloadDiff &ambiguity, + ArrayRef> aggregateFix, + ArrayRef solutions) { + auto *locator = aggregateFix.front().second->getLocator(); + auto anchor = aggregateFix.front().second->getAnchor(); - // If we didn't find an ambiguous overload, diagnose the common fixes. - if (ambiguousOverload == solutionDiff.overloads.end()) { - bool diagnosed = false; - for (auto fixes: aggregatedFixes) { - // A common fix must appear in all solutions - auto &commonFixes = fixes.second; - if (commonFixes.size() != solutions.size()) continue; + auto &DE = cs.getASTContext().Diags; - auto *firstFix = commonFixes.front().second; - diagnosed |= firstFix->diagnoseForAmbiguity(commonFixes); + { + auto fixKind = aggregateFix.front().second->getKind(); + if (llvm::all_of( + aggregateFix, [&](const std::pair &entry) { + auto &fix = entry.second; + return fix->getKind() == fixKind && fix->getLocator() == locator; + })) { + auto *primaryFix = aggregateFix.front().second; + if (primaryFix->diagnoseForAmbiguity(aggregateFix)) + return true; } - return diagnosed; } - auto *commonCalleeLocator = ambiguousOverload->locator; - auto *decl = ambiguousOverload->choices.front().getDecl(); - assert(solverState); + auto *decl = ambiguity.choices.front().getDeclOrNull(); + if (!decl) + return false; + + auto *commonCalleeLocator = ambiguity.locator; bool diagnosed = true; { - DiagnosticTransaction transaction(getASTContext().Diags); + DiagnosticTransaction transaction(DE); auto commonAnchor = commonCalleeLocator->getAnchor(); if (auto *callExpr = getAsExpr(commonAnchor)) commonAnchor = callExpr->getDirectCallee(); - auto &DE = getASTContext().Diags; + const auto name = decl->getName(); // Emit an error message for the ambiguity. - if (aggregatedFixes.size() == 1 && - aggregatedFixes.front().first.first->isForContextualType()) { - auto anchor = aggregatedFixes.front().first.first->getAnchor(); + if (locator->isForContextualType()) { auto baseName = name.getBaseName(); DE.diagnose(getLoc(commonAnchor), diag::no_candidates_match_result_type, - baseName.userFacingName(), getContextualType(anchor)); + baseName.userFacingName(), cs.getContextualType(anchor)); } else if (name.isOperator()) { auto *anchor = castToExpr(commonCalleeLocator->getAnchor()); @@ -3167,9 +3196,9 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes( // diagnostics in case of ambiguity, but if it's referenced // e.g. `arr.sort(by: <)` it's better to produce generic error // and a note per candidate. - if (auto *parentExpr = getParentExpr(anchor)) { + if (auto *parentExpr = cs.getParentExpr(anchor)) { if (isa(parentExpr)) { - diagnoseOperatorAmbiguity(*this, name.getBaseIdentifier(), solutions, + diagnoseOperatorAmbiguity(cs, name.getBaseIdentifier(), solutions, commonCalleeLocator); return true; } @@ -3180,7 +3209,7 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes( name.isSpecial(), name.getBaseName()); } else { bool isApplication = - llvm::any_of(ArgumentInfos, [&](const auto &argInfo) { + llvm::any_of(cs.ArgumentInfos, [&](const auto &argInfo) { return argInfo.first->getAnchor() == commonAnchor; }); @@ -3193,7 +3222,7 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes( // Produce candidate notes SmallPtrSet distinctChoices; llvm::SmallSet candidateTypes; - for (const auto &solution: solutions) { + for (const auto &solution : solutions) { auto overload = solution.getOverloadChoice(commonCalleeLocator); auto *decl = overload.choice.getDecl(); auto type = solution.simplifyType(overload.openedType); @@ -3201,27 +3230,38 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes( if (!distinctChoices.insert(decl).second) continue; + auto noteLoc = + decl->getLoc().isInvalid() ? getLoc(commonAnchor) : decl->getLoc(); + if (solution.Fixes.size() == 1) { diagnosed &= solution.Fixes.front()->diagnose(solution, /*asNote*/ true); - } else if (llvm::all_of(solution.Fixes, - [&](ConstraintFix *fix) { - return fix->getLocator() - ->findLast().hasValue(); - })) { - // All fixes have to do with arguments, so let's show the parameter lists. + } else if (llvm::all_of(solution.Fixes, [&](ConstraintFix *fix) { + return fix->getLocator() + ->findLast() + .hasValue(); + })) { + // All fixes have to do with arguments, so let's show the parameter + // lists. auto *fn = type->getAs(); assert(fn); - DE.diagnose(decl->getLoc(), - diag::candidate_partial_match, - fn->getParamListAsString(fn->getParams())); + + if (fn->getNumParams() == 1) { + const auto ¶m = fn->getParams()[0]; + DE.diagnose(noteLoc, diag::candidate_has_invalid_argument_at_position, + solution.simplifyType(param.getPlainType()), + /*position=*/1, param.isInOut()); + } else { + DE.diagnose(noteLoc, diag::candidate_partial_match, + fn->getParamListAsString(fn->getParams())); + } } else { // Emit a general "found candidate" note if (decl->getLoc().isInvalid()) { if (candidateTypes.insert(type->getCanonicalType()).second) DE.diagnose(getLoc(commonAnchor), diag::found_candidate_type, type); } else { - DE.diagnose(decl->getLoc(), diag::found_candidate); + DE.diagnose(noteLoc, diag::found_candidate); } } } @@ -3234,6 +3274,135 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes( return diagnosed; } +bool ConstraintSystem::diagnoseAmbiguityWithFixes( + SmallVectorImpl &solutions) { + if (solutions.empty()) + return false; + + SolutionDiff solutionDiff(solutions); + + if (diagnoseConflictingGenericArguments(*this, solutionDiff, solutions)) + return true; + + if (auto bestScore = solverState->BestScore) { + solutions.erase(llvm::remove_if(solutions, + [&](const Solution &solution) { + return solution.getFixedScore() > + *bestScore; + }), + solutions.end()); + + if (llvm::all_of(solutions, [&](const Solution &solution) { + auto score = solution.getFixedScore(); + return score.Data[SK_Fix] == 0 && solution.Fixes.empty(); + })) + return false; + } + + if (solutions.size() < 2) + return false; + + if (diagnoseAmbiguityWithEphemeralPointers(*this, solutions)) + return true; + + if (isDebugMode()) { + auto &log = llvm::errs(); + log << "--- Ambiguity: Considering #" << solutions.size() + << " solutions with fixes ---\n"; + int i = 0; + for (auto &solution : solutions) { + log << "--- Solution #" << i++ << "---\n"; + solution.dump(log); + log << "\n"; + } + } + + // Algorithm is as follows: + // + // a. Aggregate all of the available fixes based on callee locator; + // b. For each ambiguous overload match aggregated fixes and diagnose; + // c. Discard all of the fixes which have been already considered + // as part of overload diagnostics; + // d. Diagnose remaining (uniqued based on kind + locator) fixes + // iff they appear in all of the solutions. + + using Fix = std::pair; + + llvm::SmallSetVector fixes; + for (auto &solution : solutions) { + for (auto *fix : solution.Fixes) + fixes.insert({&solution, fix}); + } + + llvm::MapVector> fixesByCallee; + llvm::SmallVector contextualFixes; + + for (const auto &entry : fixes) { + const auto &solution = *entry.first; + const auto *fix = entry.second; + + if (fix->getLocator()->isForContextualType()) { + contextualFixes.push_back({&solution, fix}); + continue; + } + + auto *calleeLocator = solution.getCalleeLocator(fix->getLocator()); + fixesByCallee[calleeLocator].push_back({&solution, fix}); + } + + bool diagnosed = false; + + // All of the fixes which have been considered already. + llvm::SmallSetVector consideredFixes; + + for (const auto &ambiguity : solutionDiff.overloads) { + auto fixes = fixesByCallee.find(ambiguity.locator); + if (fixes == fixesByCallee.end()) + continue; + + auto aggregate = fixes->second; + diagnosed |= ::diagnoseAmbiguity(*this, ambiguity, aggregate, solutions); + + consideredFixes.insert(aggregate.begin(), aggregate.end()); + } + + if (diagnoseAmbiguityWithContextualType(*this, solutionDiff, contextualFixes, + solutions)) { + consideredFixes.insert(contextualFixes.begin(), contextualFixes.end()); + diagnosed |= true; + } + + // Remove all of the fixes which have been attached to ambiguous + // overload choices. + fixes.set_subtract(consideredFixes); + + llvm::MapVector, SmallVector> + fixesByKind; + + for (const auto &entry : fixes) { + const auto *fix = entry.second; + fixesByKind[{fix->getKind(), fix->getLocator()}].push_back( + {entry.first, fix}); + } + + // If leftover fix is contained in all of the solutions let's + // diagnose it as ambiguity. + for (const auto &entry : fixesByKind) { + if (llvm::all_of(solutions, [&](const Solution &solution) -> bool { + return llvm::any_of( + solution.Fixes, [&](const ConstraintFix *fix) -> bool { + return std::make_pair(fix->getKind(), fix->getLocator()) == + entry.first; + }); + })) { + auto &aggregate = entry.second; + diagnosed |= aggregate.front().second->diagnoseForAmbiguity(aggregate); + } + } + + return diagnosed; +} + /// Determine the number of distinct overload choices in the /// provided set. static unsigned countDistinctOverloads(ArrayRef choices) { diff --git a/test/AutoDiff/Sema/differentiable_func_type.swift b/test/AutoDiff/Sema/differentiable_func_type.swift index 77a2b8f71bc75..b02d99b64393e 100644 --- a/test/AutoDiff/Sema/differentiable_func_type.swift +++ b/test/AutoDiff/Sema/differentiable_func_type.swift @@ -175,8 +175,10 @@ extension Vector: Differentiable where T: Differentiable { mutating func move(along direction: TangentVector) { fatalError() } } +// expected-note@+1 2 {{candidate requires that 'Int' conform to 'Differentiable' (requirement specified as 'T' == 'Differentiable')}} func inferredConformancesGeneric(_: @differentiable (Vector) -> Vector) {} +// expected-note @+5 2 {{candidate requires that 'Int' conform to 'Differentiable' (requirement specified as 'T' == 'Differentiable')}} // expected-error @+4 {{generic signature requires types 'Vector' and 'Vector.TangentVector' to be the same}} // expected-error @+3 {{generic signature requires types 'Vector' and 'Vector.TangentVector' to be the same}} // expected-error @+2 {{parameter type 'Vector' does not conform to 'Differentiable' and satisfy 'Vector == Vector.TangentVector', but the enclosing function type is '@differentiable(linear)'}} @@ -184,9 +186,9 @@ func inferredConformancesGeneric(_: @differentiable (Vector) -> Vector< func inferredConformancesGenericLinear(_: @differentiable(linear) (Vector) -> Vector) {} func nondiff(x: Vector) -> Vector {} -// expected-error @+1 {{global function 'inferredConformancesGeneric' requires that 'Int' conform to 'Differentiable}} +// expected-error @+1 {{no exact matches in call to global function 'inferredConformancesGeneric'}} inferredConformancesGeneric(nondiff) -// expected-error @+1 {{global function 'inferredConformancesGenericLinear' requires that 'Int' conform to 'Differentiable}} +// expected-error @+1 {{no exact matches in call to global function 'inferredConformancesGenericLinear'}} inferredConformancesGenericLinear(nondiff) func diff(x: Vector) -> Vector {} @@ -208,16 +210,16 @@ extension Linear: Differentiable where T: Differentiable, T == T.TangentVector { typealias TangentVector = Self } -// expected-note @+1 2 {{where 'T' = 'Int'}} +// expected-note @+1 2 {{candidate requires that 'Int' conform to 'Differentiable' (requirement specified as 'T' == 'Differentiable')}} func inferredConformancesGeneric(_: @differentiable (Linear) -> Linear) {} -// expected-note @+1 2 {{where 'T' = 'Int'}} +// expected-note @+1 2 {{candidate requires that 'Int' conform to 'Differentiable' (requirement specified as 'T' == 'Differentiable')}} func inferredConformancesGenericLinear(_: @differentiable(linear) (Linear) -> Linear) {} func nondiff(x: Linear) -> Linear {} -// expected-error @+1 {{global function 'inferredConformancesGeneric' requires that 'Int' conform to 'Differentiable}} +// expected-error @+1 {{no exact matches in call to global function 'inferredConformancesGeneric'}} inferredConformancesGeneric(nondiff) -// expected-error @+1 {{global function 'inferredConformancesGenericLinear' requires that 'Int' conform to 'Differentiable}} +// expected-error @+1 {{no exact matches in call to global function 'inferredConformancesGenericLinear'}} inferredConformancesGenericLinear(nondiff) func diff(x: Linear) -> Linear {} diff --git a/test/Constraints/argument_matching.swift b/test/Constraints/argument_matching.swift index f316c06dab41a..1a8a1984faf1a 100644 --- a/test/Constraints/argument_matching.swift +++ b/test/Constraints/argument_matching.swift @@ -1465,27 +1465,24 @@ _ = acceptTuple2(tuple1) _ = acceptTuple2((1, "hello", 3.14159)) -func generic_and_missing_label(x: Int) {} -func generic_and_missing_label(x: T) {} +func generic_and_missing_label(x: Int) {} // expected-note {{incorrect labels for candidate (have: '(_:)', expected: '(x:)')}} +func generic_and_missing_label(x: T) {} // expected-note {{incorrect labels for candidate (have: '(_:)', expected: '(x:)')}} generic_and_missing_label(42) -// expected-error@-1 {{missing argument label 'x:' in call}} {{27-27=x: }} +// expected-error@-1 {{no exact matches in call to global function 'generic_and_missing_label'}} // ------------------------------------------- // Curried functions // ------------------------------------------- - func f7(_ a: Int) -> (_ b: Int) -> Int { return { b in a+b } } _ = f7(1)(1) f7(1.0)(2) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} - f7(1)(1.0) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} f7(1)(b: 1.0) // expected-error{{extraneous argument label 'b:' in call}} // expected-error@-1 {{cannot convert value of type 'Double' to expected argument type 'Int'}} - let f10 = f7(2) _ = f10(1) f10(10) // expected-warning {{result of call to function returning 'Int' is unused}} @@ -1493,7 +1490,6 @@ f10(1.0) // expected-error {{cannot convert value of type 'Double' to ex f10(b: 1.0) // expected-error {{extraneous argument label 'b:' in call}} // expected-error@-1 {{cannot convert value of type 'Double' to expected argument type 'Int'}} - class CurriedClass { func method1() {} func method2(_ a: Int) -> (_ b : Int) -> () { return { b in () } } @@ -1513,13 +1509,11 @@ c.method2(1)(2.0) // expected-error {{cannot convert value of type 'Double' to e c.method2(1.0)(2) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} c.method2(1.0)(2.0) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} // expected-error@-1 {{cannot convert value of type 'Double' to expected argument type 'Int'}} - CurriedClass.method1(c)() _ = CurriedClass.method1(c) CurriedClass.method1(c)(1) // expected-error {{argument passed to call that takes no arguments}} CurriedClass.method1(2.0)(1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'CurriedClass'}} // expected-error@-1:27 {{argument passed to call that takes no arguments}} - CurriedClass.method2(c)(32)(b: 1) // expected-error{{extraneous argument label 'b:' in call}} _ = CurriedClass.method2(c) _ = CurriedClass.method2(c)(32) @@ -1530,7 +1524,6 @@ CurriedClass.method2(c)(1.0)(b: 1) // expected-error {{cannot convert value of t CurriedClass.method2(c)(1)(1.0) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} CurriedClass.method2(c)(2)(c: 1.0) // expected-error {{extraneous argument label 'c:'}} // expected-error@-1 {{cannot convert value of type 'Double' to expected argument type 'Int'}} - CurriedClass.method3(c)(32, b: 1) _ = CurriedClass.method3(c) _ = CurriedClass.method3(c)(1, 2) // expected-error {{missing argument label 'b:' in call}} {{32-32=b: }} @@ -1543,7 +1536,6 @@ CurriedClass.method3(c)(c: 1.0) // expected-error {{incorrect argument // expected-error@-1 {{cannot convert value of type 'Double' to expected argument type 'Int'}} // expected-error@-2 {{missing argument for parameter #1 in call}} - extension CurriedClass { func f() { method3(1, b: 2) @@ -1557,64 +1549,51 @@ extension CurriedClass { extension CurriedClass { func m1(_ a : Int, b : Int) {} - + func m2(_ a : Int) {} } // QoI: "Extra argument" error when accidentally currying a method CurriedClass.m1(2, b: 42) // expected-error {{instance member 'm1' cannot be used on type 'CurriedClass'; did you mean to use a value of this type instead?}} - // QoI: Confusing error message when calling an instance method as a class method CurriedClass.m2(12) // expected-error {{instance member 'm2' cannot be used on type 'CurriedClass'; did you mean to use a value of this type instead?}} - // ------------------------------------------- // Multiple label errors // ------------------------------------------- - func testLabelErrorsBasic() { func f(_ aa: Int, _ bb: Int, cc: Int, dd: Int, ee: Int, ff: Int) {} // 1 wrong f(0, 1, ccx: 2, dd: 3, ee: 4, ff: 5) // expected-error@-1 {{incorrect argument label in call (have '_:_:ccx:dd:ee:ff:', expected '_:_:cc:dd:ee:ff:')}} {{11-14=cc}} {{none}} - // 1 missing f(0, 1, 2, dd: 3, ee: 4, ff: 5) // expected-error@-1 {{missing argument label 'cc:' in call}} {{11-11=cc: }} {{none}} - // 1 extra f(aa: 0, 1, cc: 2, dd: 3, ee: 4, ff: 5) // expected-error@-1 {{extraneous argument label 'aa:' in call}} {{5-9=}} {{none}} - // 1 ooo f(0, 1, dd: 3, cc: 2, ee: 4, ff: 5) // expected-error@-1 {{argument 'cc' must precede argument 'dd'}} {{16-23=}} {{11-11=cc: 2, }} {{none}} - // 2 wrong f(0, 1, ccx: 2, ddx: 3, ee: 4, ff: 5) // expected-error@-1 {{incorrect argument labels in call (have '_:_:ccx:ddx:ee:ff:', expected '_:_:cc:dd:ee:ff:')}} {{11-14=cc}} {{19-22=dd}} {{none}} - // 2 missing f(0, 1, 2, 3, ee: 4, ff: 5) // expected-error@-1 {{missing argument labels 'cc:dd:' in call}} {{11-11=cc: }} {{14-14=dd: }} {{none}} - // 2 extra f(aa: 0, bb: 1, cc: 2, dd: 3, ee: 4, ff: 5) // expected-error@-1 {{extraneous argument labels 'aa:bb:' in call}} {{5-9=}} {{12-16=}} {{none}} - // 2 ooo f(0, 1, dd: 3, cc: 2, ff: 5, ee: 4) // expected-error@-1 {{argument 'cc' must precede argument 'dd'}} {{16-23=}} {{11-11=cc: 2, }} {{none}} - // 1 wrong + 1 missing f(0, 1, ccx: 2, 3, ee: 4, ff: 5) // expected-error@-1 {{incorrect argument labels in call (have '_:_:ccx:_:ee:ff:', expected '_:_:cc:dd:ee:ff:')}} {{11-14=cc}} {{19-19=dd: }} {{none}} - // 1 wrong + 1 extra f(aa: 0, 1, ccx: 2, dd: 3, ee: 4, ff: 5) // expected-error@-1 {{incorrect argument labels in call (have 'aa:_:ccx:dd:ee:ff:', expected '_:_:cc:dd:ee:ff:')}} {{5-9=}} {{15-18=cc}} {{none}} - // 1 wrong + 1 ooo f(0, 1, ccx: 2, dd: 3, ff: 5, ee: 4) // expected-error@-1 {{incorrect argument labels in call (have '_:_:ccx:dd:ff:ee:', expected '_:_:cc:dd:ee:ff:')}} {{11-14=cc}} {{26-28=ee}} {{33-35=ff}} {{none}} @@ -1625,7 +1604,6 @@ struct DiagnoseAllLabels { func test() { f(aax: 0, bbx: 1, cc: 21, 22, 23, dd: 3, ff: 5) // expected-error {{incorrect argument labels in call (have 'aax:bbx:cc:_:_:dd:ff:', expected 'aa:bb:cc:_:_:dd:ff:')}} {{7-10=aa}} {{15-18=bb}} {{none}} - f(aax: 0, bbx: 1, dd: 3, ff: 5) // expected-error {{incorrect argument labels in call (have 'aax:bbx:dd:ff:', expected 'aa:bb:dd:ff:')}} {{7-10=aa}} {{15-18=bb}} {{none}} } } diff --git a/test/Constraints/bridging.swift b/test/Constraints/bridging.swift index e9424798d3c4f..5dcb206a1fc0d 100644 --- a/test/Constraints/bridging.swift +++ b/test/Constraints/bridging.swift @@ -180,7 +180,7 @@ func dictionaryToNSDictionary() { // In this case, we should not implicitly convert Dictionary to NSDictionary. struct NotEquatable {} func notEquatableError(_ d: Dictionary) -> Bool { - return d == d // expected-error{{operator function '==' requires that 'NotEquatable' conform to 'Equatable'}} + return d == d // expected-error{{referencing operator function '==' on 'Dictionary' requires that 'NotEquatable' conform to 'Equatable'}} } // NSString -> String diff --git a/test/Constraints/closures.swift b/test/Constraints/closures.swift index 1b290fb44ca1e..29104fa24b268 100644 --- a/test/Constraints/closures.swift +++ b/test/Constraints/closures.swift @@ -562,7 +562,6 @@ r32432145 { _,_ in // rdar://problem/30106822 - Swift ignores type error in closure and presents a bogus error about the caller [1, 2].first { $0.foo = 3 } // expected-error@-1 {{value of type 'Int' has no member 'foo'}} -// expected-error@-2 {{cannot convert value of type '()' to closure result type 'Bool'}} // rdar://problem/32433193, SR-5030 - Higher-order function diagnostic mentions the wrong contextual type conversion problem protocol A_SR_5030 { @@ -827,7 +826,7 @@ func rdar_40537960() { } var arr: [S] = [] - _ = A(arr, fn: { L($0.v) }) // expected-error {{cannot convert value of type 'L' to closure result type 'R

'}} + _ = A(arr, fn: { L($0.v) }) // expected-error@-1 {{generic parameter 'P' could not be inferred}} // expected-note@-2 {{explicitly specify the generic arguments to fix this issue}} {{8-8=<[S], <#P: P_40537960#>>}} } diff --git a/test/Constraints/diagnostics.swift b/test/Constraints/diagnostics.swift index 0cda84772d554..ab063ed2dcfbc 100644 --- a/test/Constraints/diagnostics.swift +++ b/test/Constraints/diagnostics.swift @@ -399,16 +399,16 @@ enum Color { static func rainbow() -> Color {} static func overload(a : Int) -> Color {} // expected-note {{incorrect labels for candidate (have: '(_:)', expected: '(a:)')}} - // expected-note@-1 {{candidate has partially matching parameter list (a: Int)}} + // expected-note@-1 {{candidate expects value of type 'Int' for parameter #1}} static func overload(b : Int) -> Color {} // expected-note {{incorrect labels for candidate (have: '(_:)', expected: '(b:)')}} - // expected-note@-1 {{candidate has partially matching parameter list (b: Int)}} + // expected-note@-1 {{candidate expects value of type 'Int' for parameter #1}} static func frob(_ a : Int, b : inout Int) -> Color {} static var svar: Color { return .Red } } -let _: (Int, Color) = [1,2].map({ ($0, .Unknown("")) }) // expected-error {{cannot convert value of type 'Array<(Int, _)>' to specified type '(Int, Color)'}} -// expected-error@-1 {{cannot infer contextual base in reference to member 'Unknown'}} +let _: (Int, Color) = [1,2].map({ ($0, .Unknown("")) }) +// expected-error@-1 {{cannot convert value of type 'Array<(Int, _)>' to specified type '(Int, Color)'}} let _: [(Int, Color)] = [1,2].map({ ($0, .Unknown("")) })// expected-error {{missing argument label 'description:' in call}} @@ -1117,8 +1117,10 @@ func platypus(a: [T]) { // Another case of the above. func badTypes() { let sequence:AnySequence<[Int]> = AnySequence() { AnyIterator() { [3] }} + // Notes, attached to declarations, explain that there is a difference between Array.init(_:) and + // RangeReplaceableCollection.init(_:) which are both applicable in this case. let array = [Int](sequence) - // expected-error@-1 {{initializer 'init(_:)' requires the types 'Int' and '[Int]' be equivalent}} + // expected-error@-1 {{no exact matches in call to initializer}} } // rdar://34357545 @@ -1248,10 +1250,9 @@ func f11(_ n: Int) {} func f11(_ n: T, _ f: @escaping (T) -> T) {} // expected-note {{where 'T' = 'Int'}} f11(3, f4) // expected-error {{global function 'f11' requires that 'Int' conform to 'P2'}} -// FIXME: Arguably we should also prefer the conformance failure in this case. -let f12: (Int) -> Void = { _ in } -func f12(_ n: T, _ f: @escaping (T) -> T) {} -f12(3, f4)// expected-error {{extra argument in call}} +let f12: (Int) -> Void = { _ in } // expected-note {{candidate '(Int) -> Void' requires 1 argument, but 2 were provided}} +func f12(_ n: T, _ f: @escaping (T) -> T) {} // expected-note {{candidate requires that 'Int' conform to 'P2' (requirement specified as 'T' == 'P2')}} +f12(3, f4)// expected-error {{no exact matches in call to global function 'f12'}} // SR-12242 struct SR_12242_R {} diff --git a/test/Constraints/dynamic_lookup.swift b/test/Constraints/dynamic_lookup.swift index ce4398116c275..cea5680ae5e0b 100644 --- a/test/Constraints/dynamic_lookup.swift +++ b/test/Constraints/dynamic_lookup.swift @@ -338,7 +338,7 @@ func testOverloadedWithUnavailable(ao: AnyObject) { func dynamicInitCrash(ao: AnyObject.Type) { let sdk = ao.init(blahblah: ()) - // expected-error@-1 {{incorrect argument label in call (have 'blahblah:', expected 'toMemory:')}} + // expected-error@-1 {{no exact matches in call to initializer}} } // Test that we correctly diagnose ambiguity for different typed members available diff --git a/test/Constraints/fixes.swift b/test/Constraints/fixes.swift index 8a8aeb82c55ba..4abb3c747420b 100644 --- a/test/Constraints/fixes.swift +++ b/test/Constraints/fixes.swift @@ -358,8 +358,6 @@ func testKeyPathSubscriptArgFixes(_ fn: @escaping () -> Int) { } func sr12426(a: Any, _ str: String?) { - a == str // expected-error {{cannot convert value of type 'Any' to expected argument type 'String'}} - // expected-error@-1 {{value of optional type 'String?' must be unwrapped to a value of type 'String'}} - // expected-note@-2 {{coalesce using '??' to provide a default when the optional value contains 'nil'}} - // expected-note@-3 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}} + a == str // expected-error {{binary operator '==' cannot be applied to operands of type 'Any' and 'String?'}} + // expected-note@-1 {{overloads for '==' exist with these partially matching parameter lists: (String, String)}} } diff --git a/test/Constraints/function.swift b/test/Constraints/function.swift index 16d0bf2455fce..429b4dc865ee4 100644 --- a/test/Constraints/function.swift +++ b/test/Constraints/function.swift @@ -62,12 +62,12 @@ func test() { // QoI: argument label mismatches produce not-great diagnostic class A { - func a(_ text:String) { + func a(_ text:String) { // expected-note {{incorrect labels for candidate (have: '(text:)', expected: '(_:)')}} } - func a(_ text:String, something:Int?=nil) { + func a(_ text:String, something:Int?=nil) { // expected-note {{incorrect labels for candidate (have: '(text:)', expected: '(_:)')}} } } -A().a(text:"sometext") // expected-error{{extraneous argument label 'text:' in call}}{{7-12=}} +A().a(text:"sometext") // expected-error{{no exact matches in call to instance method 'a'}} // QoI: incorrect diagnostic when argument to print has the wrong type diff --git a/test/Constraints/members.swift b/test/Constraints/members.swift index 54763e96a9c8b..3f35c02bf6b01 100644 --- a/test/Constraints/members.swift +++ b/test/Constraints/members.swift @@ -617,12 +617,13 @@ func rdar50679161() { func rdar_50467583_and_50909555() { if #available(macOS 9999, iOS 9999, tvOS 9999, watchOS 9999, *) { // rdar://problem/50467583 - let _: Set = [Int][] // expected-error {{no exact matches in call to subscript}} - // expected-note@-1 {{found candidate with type '(Int) -> Int'}} - // expected-note@-2 {{found candidate with type '(Range) -> ArraySlice'}} - // expected-note@-3 {{found candidate with type '((UnboundedRange_) -> ()) -> ArraySlice'}} - // expected-note@-4 {{found candidate with type '(RangeSet.Index>) -> DiscontiguousSlice<[Int]>' (aka '(RangeSet) -> DiscontiguousSlice>')}} - // expected-note@-5 {{found candidate with type '(Range.Index>) -> Slice<[Int]>' (aka '(Range) -> Slice>')}} + let _: Set = [Int][] // expected-error {{no 'subscript' candidates produce the expected contextual result type 'Set'}} + // expected-error@-1 {{no exact matches in call to subscript}} + // expected-note@-2 {{found candidate with type '(Int) -> Int'}} + // expected-note@-3 {{found candidate with type '(Range) -> ArraySlice'}} + // expected-note@-4 {{found candidate with type '((UnboundedRange_) -> ()) -> ArraySlice'}} + // expected-note@-5 {{found candidate with type '(RangeSet.Index>) -> DiscontiguousSlice<[Int]>' (aka '(RangeSet) -> DiscontiguousSlice>')}} + // expected-note@-6 {{found candidate with type '(Range.Index>) -> Slice<[Int]>' (aka '(Range) -> Slice>')}} } // rdar://problem/50909555 diff --git a/test/Constraints/operator.swift b/test/Constraints/operator.swift index 6b2ffe10644c4..8c19035d5a8d2 100644 --- a/test/Constraints/operator.swift +++ b/test/Constraints/operator.swift @@ -220,7 +220,7 @@ func rdar46459603() { // expected-error@-1 {{referencing operator function '==' on 'Equatable' requires that 'Dictionary.Values' conform to 'Equatable'}} // expected-error@-2 {{cannot convert value of type '[E]' to expected argument type 'Dictionary.Values'}} _ = [arr.values] == [[e]] - // expected-error@-1 {{operator function '==' requires that 'Dictionary.Values' conform to 'Equatable'}} + // expected-error@-1 {{referencing operator function '==' on 'Array' requires that 'Dictionary.Values' conform to 'Equatable'}} // expected-error@-2 {{cannot convert value of type '[E]' to expected element type 'Dictionary.Values'}} } diff --git a/test/Constraints/optional.swift b/test/Constraints/optional.swift index d3bf1c65a1121..5e21951a8ed74 100644 --- a/test/Constraints/optional.swift +++ b/test/Constraints/optional.swift @@ -424,8 +424,7 @@ func test_force_unwrap_not_being_too_eager() { // rdar://problem/57097401 func invalidOptionalChaining(a: Any) { a == "="? // expected-error {{cannot use optional chaining on non-optional value of type 'String'}} - // expected-error@-1 {{value of protocol type 'Any' cannot conform to 'Equatable'; only struct/enum/class types can conform to protocols}} - // expected-note@-2 {{requirement from conditional conformance of 'Any?' to 'Equatable'}} + // expected-error@-1 {{cannot convert value of type 'Any' to expected argument type 'Any.Type?'}} } // SR-12309 - Force unwrapping 'nil' compiles without warning diff --git a/test/Constraints/overload.swift b/test/Constraints/overload.swift index 9877c41ec0ab8..b1fe98112c989 100644 --- a/test/Constraints/overload.swift +++ b/test/Constraints/overload.swift @@ -127,11 +127,12 @@ func test20886179(_ handlers: [(Int) -> Void], buttonIndex: Int) { // The problem here is that the call has a contextual result type incompatible // with *all* overload set candidates. This is not an ambiguity. -func overloaded_identity(_ a : Int) -> Int {} // expected-note {{found this candidate}} -func overloaded_identity(_ b : Float) -> Float {} // expected-note {{found this candidate}} +func overloaded_identity(_ a : Int) -> Int {} // expected-note {{'overloaded_identity' produces 'Int', not the expected contextual result type '()'}} expected-note {{'overloaded_identity' declared her}} +func overloaded_identity(_ b : Float) -> Float {} // expected-note {{'overloaded_identity' produces 'Float', not the expected contextual result type '()'}} func test_contextual_result_1() { - return overloaded_identity() // expected-error {{no exact matches in call to global function 'overloaded_identity'}} + return overloaded_identity() // expected-error {{missing argument for parameter #1 in call}} + // expected-error@-1 {{no 'overloaded_identity' candidates produce the expected contextual result type '()'}} } func test_contextual_result_2() { diff --git a/test/Constraints/patterns.swift b/test/Constraints/patterns.swift index d0ca8f7582397..5468e620f0827 100644 --- a/test/Constraints/patterns.swift +++ b/test/Constraints/patterns.swift @@ -274,9 +274,7 @@ struct StaticMembers: Equatable { static var optProp: Optional = StaticMembers() static func method(_: Int) -> StaticMembers { return prop } - // expected-note@-1 {{found candidate with type '(Int) -> StaticMembers'}} static func method(withLabel: Int) -> StaticMembers { return prop } - // expected-note@-1 {{found candidate with type '(Int) -> StaticMembers'}} static func optMethod(_: Int) -> StaticMembers? { return optProp } static func ==(x: StaticMembers, y: StaticMembers) -> Bool { return true } @@ -301,7 +299,7 @@ switch staticMembers { // TODO: repeated error message case .optProp: break // expected-error* {{not unwrapped}} - case .method: break // expected-error{{no exact matches in reference to static method 'method'}} + case .method: break // expected-error{{member 'method' expects argument of type 'Int'}} case .method(0): break case .method(_): break // expected-error{{'_' can only appear in a pattern}} case .method(let x): break // expected-error{{cannot appear in an expression}} diff --git a/test/Constraints/rdar44770297.swift b/test/Constraints/rdar44770297.swift index 82d96f7459112..8d0b128b9e136 100644 --- a/test/Constraints/rdar44770297.swift +++ b/test/Constraints/rdar44770297.swift @@ -4,11 +4,10 @@ protocol P { associatedtype A } -func foo(_: () throws -> T) -> T.A? { // expected-note {{where 'T' = 'Never'}} +func foo(_: () throws -> T) -> T.A? { fatalError() } -let _ = foo() {fatalError()} & nil // expected-error {{global function 'foo' requires that 'Never' conform to 'P'}} -// expected-error@-1 {{value of optional type 'Never.A?' must be unwrapped to a value of type 'Never.A'}} -// expected-note@-2 {{force-unwrap}} -// expected-note@-3 {{coalesce using '??'}} +let _ = foo() {fatalError()} & nil // expected-error {{value of optional type 'Never.A?' must be unwrapped to a value of type 'Never.A'}} +// expected-note@-1 {{coalesce using '??' to provide a default when the optional value contains 'nil'}} +// expected-note@-2 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}} diff --git a/test/Constraints/sr12964.swift b/test/Constraints/sr12964.swift index 27d48299b144d..b18de10a36f30 100644 --- a/test/Constraints/sr12964.swift +++ b/test/Constraints/sr12964.swift @@ -3,5 +3,4 @@ protocol P {} typealias T = (P) -> Void let x: T! = [1, 2, 3].reversed().reduce() -// expected-error@-1 {{no exact matches in call to instance method 'reduce'}} -// expected-note@-2 2{{candidate has partially matching parameter list}} +// expected-error@-1 {{missing arguments for parameters #1, #2 in call}} diff --git a/test/Constraints/super_constructor.swift b/test/Constraints/super_constructor.swift index 01e15a2990432..d6976b7ec010f 100644 --- a/test/Constraints/super_constructor.swift +++ b/test/Constraints/super_constructor.swift @@ -39,15 +39,15 @@ class B { init() { } - init(x:Int) { // expected-note{{candidate has partially matching parameter list (x: Int)}} + init(x:Int) { // expected-note{{candidate expects value of type 'Int' for parameter #1}} } - init(a:UnicodeScalar) { // expected-note {{candidate has partially matching parameter list (a: UnicodeScalar)}} + init(a:UnicodeScalar) { // expected-note {{candidate expects value of type 'UnicodeScalar' (aka 'Unicode.Scalar') for parameter #1}} } - init(b:UnicodeScalar) { // expected-note{{candidate has partially matching parameter list (b: UnicodeScalar)}} + init(b:UnicodeScalar) { // expected-note {{candidate expects value of type 'UnicodeScalar' (aka 'Unicode.Scalar') for parameter #1}} } - init(z:Float) { // expected-note{{candidate has partially matching parameter list (z: Float)}} + init(z:Float) { // expected-note{{candidate expects value of type 'Float' for parameter #1}} super.init() // expected-error{{'super' members cannot be referenced in a root class}} } } diff --git a/test/Constraints/tuple.swift b/test/Constraints/tuple.swift index c452ea7b2b335..ec557012b835a 100644 --- a/test/Constraints/tuple.swift +++ b/test/Constraints/tuple.swift @@ -181,7 +181,7 @@ variadicWithTrailingClosure(fn: +) func gcd_23700031(_ a: T, b: T) { var a = a var b = b - (a, b) = (b, a % b) // expected-error {{referencing operator function '%' on 'BinaryInteger' requires that 'T' conform to 'BinaryInteger'}} + (a, b) = (b, a % b) // expected-error {{binary operator '%' cannot be applied to two 'T' operands}} } // diff --git a/test/Constraints/tuple_arguments.swift b/test/Constraints/tuple_arguments.swift index 7b31d6d897e99..c8be9ace19776 100644 --- a/test/Constraints/tuple_arguments.swift +++ b/test/Constraints/tuple_arguments.swift @@ -1702,8 +1702,8 @@ x.map { (_: ()) in () } // https://bugs.swift.org/browse/SR-9470 do { func f(_: Int...) {} - let _ = [(1, 2, 3)].map(f) // expected-error {{cannot convert value of type '(Int...) -> ()' to expected argument type '((Int, Int, Int)) throws -> T'}} - // expected-error@-1 {{generic parameter 'T' could not be inferred}} + let _ = [(1, 2, 3)].map(f) // expected-error {{no exact matches in call to instance method 'map'}} + // expected-note@-1 {{found candidate with type '(((Int, Int, Int)) throws -> _) throws -> Array<_>'}} } // rdar://problem/48443263 - cannot convert value of type '() -> Void' to expected argument type '(_) -> Void' diff --git a/test/Generics/conditional_conformances.swift b/test/Generics/conditional_conformances.swift index 7aa6f7497ba1e..791d1a4b3ffff 100644 --- a/test/Generics/conditional_conformances.swift +++ b/test/Generics/conditional_conformances.swift @@ -413,9 +413,9 @@ extension Foo: P where Bar: P { extension BinaryInteger { var foo: Self { return self <= 1 - ? 1 + ? 1 // expected-error {{cannot convert return expression of type 'Int' to return type 'Self'}} : (2...self).reduce(1, *) - // expected-error@-1 {{referencing instance method 'reduce' on 'ClosedRange' requires that 'Self.Stride' conform to 'SignedInteger'}} + // expected-error@-1 {{cannot convert value of type 'Self' to expected argument type 'Int'}} {{20-20=Int(}} {{24-24=)}} } } diff --git a/test/Generics/deduction.swift b/test/Generics/deduction.swift index f3e4d4b70cfa2..1a90faddc21a8 100644 --- a/test/Generics/deduction.swift +++ b/test/Generics/deduction.swift @@ -25,7 +25,7 @@ func useIdentity(_ x: Int, y: Float, i32: Int32) { // Deduction where the result type and input type can get different results var xx : X, yy : Y xx = identity(yy) // expected-error{{cannot assign value of type 'Y' to type 'X'}} - xx = identity2(yy) // expected-error{{no exact matches in call to global function 'identity2'}} + xx = identity2(yy) // expected-error{{no 'identity2' candidates produce the expected contextual result type 'X'}} } func twoIdentical(_ x: T, _ y: T) -> T {} @@ -89,7 +89,7 @@ func testReturnTuple(_ x: Int, y: Float) { var _ : (Float, Float) = returnTuple(y) // QoI: Propagate contextual information in a call to operands - var _ : (Int, Float) = returnTuple(y) // expected-error{{cannot convert value of type 'Float' to expected argument type 'Int'}} + var _ : (Int, Float) = returnTuple(y) // expected-error{{conflicting arguments to generic parameter 'T' ('Float' vs. 'Int')}} } diff --git a/test/Generics/function_defs.swift b/test/Generics/function_defs.swift index db836e2641733..0a271eec4f2ae 100644 --- a/test/Generics/function_defs.swift +++ b/test/Generics/function_defs.swift @@ -78,9 +78,9 @@ protocol Overload { func f1(_: B) -> B // expected-note {{candidate expects value of type 'OtherOvl.B' for parameter #1}} func f2(_: Int) -> A // expected-note{{found this candidate}} func f2(_: Int) -> B // expected-note{{found this candidate}} - func f3(_: Int) -> Int // expected-note {{found this candidate}} - func f3(_: Float) -> Float // expected-note {{found this candidate}} - func f3(_: Self) -> Self // expected-note {{found this candidate}} + func f3(_: Int) -> Int // expected-note {{found candidate with type '(Int) -> Int'}} + func f3(_: Float) -> Float // expected-note {{found candidate with type '(Float) -> Float'}} + func f3(_: Self) -> Self // expected-note {{found candidate with type '(OtherOvl) -> OtherOvl'}} var prop : Self { get } } @@ -112,7 +112,7 @@ func testOverload(_ ovl: Ovl, ovl2: Ovl, var f3f : (Float) -> Float = ovl.f3 var f3ovl_1 : (Ovl) -> Ovl = ovl.f3 var f3ovl_2 : (Ovl) -> Ovl = ovl2.f3 - var f3ovl_3 : (Ovl) -> Ovl = other.f3 // expected-error{{no exact matches in reference to instance method 'f3'}} + var f3ovl_3 : (Ovl) -> Ovl = other.f3 // expected-error{{no 'f3' candidates produce the expected contextual result type '(Ovl) -> Ovl'}} var f3i_unbound : (Ovl) -> (Int) -> Int = Ovl.f3 var f3f_unbound : (Ovl) -> (Float) -> Float = Ovl.f3 @@ -131,7 +131,7 @@ protocol Subscriptable { func getIndex() -> Index func getValue() -> Value - subscript (index : Index) -> Value { get set } + subscript (index : Index) -> Value { get set } // expected-note {{found this candidate}} } protocol IntSubscriptable { @@ -139,7 +139,7 @@ protocol IntSubscriptable { func getElement() -> ElementType - subscript (index : Int) -> ElementType { get } + subscript (index : Int) -> ElementType { get } // expected-note {{found this candidate}} } func subscripting(_ t: T) { @@ -152,9 +152,7 @@ func subscripting(_ t: T) { element = t[17] t[42] = element // expected-error{{cannot assign through subscript: subscript is get-only}} - // Suggests the Int form because we prefer concrete matches to generic matches in diagnosis. - t[value] = 17 // expected-error{{cannot convert value of type 'T.Value' to expected argument type 'Int'}} - // expected-error@-1 {{cannot assign value of type 'Int' to subscript of type 'T.ElementType'}} + t[value] = 17 // expected-error{{no exact matches in call to subscript}} } //===----------------------------------------------------------------------===// diff --git a/test/ImportResolution/import-resolution-overload.swift b/test/ImportResolution/import-resolution-overload.swift index ce9c493560811..e19ef173eb9e5 100644 --- a/test/ImportResolution/import-resolution-overload.swift +++ b/test/ImportResolution/import-resolution-overload.swift @@ -46,7 +46,7 @@ scopedFunction = 42 // FIXME: Should be an error -- a type name and a function cannot overload. var _ : Int = TypeNameWins(42) -TypeNameWins = 42 // expected-error {{no exact matches in reference to global function 'TypeNameWins'}} +TypeNameWins = 42 // expected-error {{cannot assign to immutable expression of type 'Int'}} var _ : TypeNameWins // no-warning // rdar://problem/21739333 diff --git a/test/Misc/misc_diagnostics.swift b/test/Misc/misc_diagnostics.swift index b8f2e27b18b32..557b1beec9021 100644 --- a/test/Misc/misc_diagnostics.swift +++ b/test/Misc/misc_diagnostics.swift @@ -54,8 +54,9 @@ struct MyArray {} // expected-note {{'Element' declared as parameter to class A { var a: MyArray init() { - a = MyArray.Type' and 'Int.Type'}} + // expected-error@-2 {{cannot assign value of type 'Bool' to type 'MyArray'}} } } @@ -114,11 +115,11 @@ func test17875634() { var col = 2 var coord = (row, col) - match += (1, 2) // expected-error{{cannot convert value of type '(Int, Int)' to expected argument type 'Array<(Int, Int)>'}} + match += (1, 2) // expected-error{{binary operator '+=' cannot be applied to operands of type '[(Int, Int)]' and '(Int, Int)'}} - match += (row, col) // expected-error{{cannot convert value of type '(Int, Int)' to expected argument type 'Array<(Int, Int)>'}} + match += (row, col) // expected-error{{binary operator '+=' cannot be applied to operands of type '[(Int, Int)]' and '(Int, Int)'}} - match += coord // expected-error{{cannot convert value of type '(Int, Int)' to expected argument type 'Array<(Int, Int)>'}} + match += coord // expected-error{{binary operator '+=' cannot be applied to operands of type '[(Int, Int)]' and '(Int, Int)'}} match.append(row, col) // expected-error {{instance method 'append' expects a single parameter of type '(Int, Int)'}} {{16-16=(}} {{24-24=)}} diff --git a/test/ModuleInterface/Inputs/opaque-result-types-client.swift b/test/ModuleInterface/Inputs/opaque-result-types-client.swift index 88671bd7cc6c6..8258bc3f8bb13 100644 --- a/test/ModuleInterface/Inputs/opaque-result-types-client.swift +++ b/test/ModuleInterface/Inputs/opaque-result-types-client.swift @@ -20,7 +20,7 @@ func someTypeIsTheSame() { a = foo("") // expected-error{{cannot assign value of type 'some Foo' (result of 'foo') to type 'some Foo' (result of 'foo')}} var b = foo("") - b = foo(0) // expected-error{{cannot assign value of type 'some Foo' (result of 'foo') to type 'some Foo' (result of 'foo')}} + b = foo(0) // expected-error{{no 'foo' candidates produce the expected contextual result type 'some Foo'}} b = foo("") var c = foo(MyFoo()) @@ -33,7 +33,7 @@ func someTypeIsTheSame() { var d = barInt.foo(0) d = barInt.foo(0) - d = barString.foo(0) // expected-error{{cannot assign}} + d = barString.foo(0) // expected-error{{no 'foo' candidates produce the expected contextual result type 'some Foo'}} d = getAssocType(barInt) d = getAssocType(barString) // expected-error{{cannot assign}} @@ -50,7 +50,7 @@ func someTypeIsTheSame() { d3 = getAssocSubscriptType(barString) // expected-error{{cannot assign}} var e = barString.foo(0) - e = barInt.foo(0) // expected-error{{cannot assign}} + e = barInt.foo(0) // expected-error{{no 'foo' candidates produce the expected contextual result type 'some Foo'}} e = barString.foo(0) e = getAssocType(barInt) // expected-error{{cannot assign}} e = getAssocType(barString) diff --git a/test/Parse/pointer_conversion.swift.gyb b/test/Parse/pointer_conversion.swift.gyb index d2c8137b7f18e..cdc4a29901729 100644 --- a/test/Parse/pointer_conversion.swift.gyb +++ b/test/Parse/pointer_conversion.swift.gyb @@ -307,7 +307,7 @@ struct NotEquatable {} func arrayComparison(_ x: [NotEquatable], y: [NotEquatable], p: UnsafeMutablePointer) { var x = x // Don't allow implicit array-to-pointer conversions in operators. - let a: Bool = x == y // expected-error{{operator function '==' requires that 'NotEquatable' conform to 'Equatable'}} + let a: Bool = x == y // expected-error{{referencing operator function '==' on 'Array' requires that 'NotEquatable' conform to 'Equatable'}} let _: Bool = p == &x // Allowed! } diff --git a/test/Parse/recovery.swift b/test/Parse/recovery.swift index 4613e471ca9da..cac7706052ded 100644 --- a/test/Parse/recovery.swift +++ b/test/Parse/recovery.swift @@ -10,12 +10,14 @@ func garbage() -> () { var a : Int ) this line is invalid, but we will stop at the keyword below... // expected-error{{expected expression}} return a + "a" // expected-error{{binary operator '+' cannot be applied to operands of type 'Int' and 'String'}} expected-note {{overloads for '+' exist with these partially matching parameter lists: (Int, Int), (String, String)}} + // expected-error@-1 {{no '+' candidates produce the expected contextual result type '()'}} } func moreGarbage() -> () { ) this line is invalid, but we will stop at the declaration... // expected-error{{expected expression}} func a() -> Int { return 4 } return a() + "a" // expected-error{{binary operator '+' cannot be applied to operands of type 'Int' and 'String'}} expected-note {{overloads for '+' exist with these partially matching parameter lists: (Int, Int), (String, String)}} + // expected-error@-1 {{no '+' candidates produce the expected contextual result type '()'}} } diff --git a/test/Parse/switch.swift b/test/Parse/switch.swift index 6e0c190288d64..2b42e837965c8 100644 --- a/test/Parse/switch.swift +++ b/test/Parse/switch.swift @@ -336,6 +336,7 @@ func f1(x: String, y: Whichever) { case Whichever.buzz: // expected-error {{type 'Whichever' has no member 'buzz'}} break case Whichever.alias: // expected-error {{expression pattern of type 'Whichever' cannot match values of type 'String'}} + // expected-note@-1 {{overloads for '~=' exist with these partially matching parameter lists: (Substring, String)}} break default: break diff --git a/test/Sema/diag_ambiguous_overloads.swift b/test/Sema/diag_ambiguous_overloads.swift index 10712fc3531c3..f76457697e6d5 100644 --- a/test/Sema/diag_ambiguous_overloads.swift +++ b/test/Sema/diag_ambiguous_overloads.swift @@ -126,3 +126,37 @@ func getCounts(_ scheduler: sr5154_Scheduler, _ handler: @escaping ([Count]) -> }) } +// SR-12689 +func SR12689(_ u: UnsafeBufferPointer) {} + +let array : [UInt16] = [1, 2] + +array.withUnsafeBufferPointer { + SR12689(UnsafeRawPointer($0).bindMemory(to: UInt16.self, capacity: 1)) // expected-error {{cannot convert value of type 'UnsafePointer' to expected argument type 'UnsafeBufferPointer'}} + // expected-error@-1 {{no exact matches in call to initializer}} + // expected-note@-2 {{candidate expects value of type 'UnsafeRawPointer' for parameter #1}} + // expected-note@-3 {{candidate expects value of type 'UnsafeMutableRawPointer' for parameter #1}} + // expected-note@-4 {{candidate expects value of type 'OpaquePointer' for parameter #1}} + // expected-note@-5 {{candidate expects value of type 'Builtin.RawPointer' for parameter #1}} + + UnsafeRawPointer($0) as UnsafeBufferPointer // expected-error {{cannot convert value of type 'UnsafeRawPointer' to type 'UnsafeBufferPointer' in coercion}} + // expected-error@-1 {{no exact matches in call to initializer}} + // expected-note@-2 {{found candidate with type '(UnsafeRawPointer) -> UnsafeRawPointer'}} + // expected-note@-3 {{found candidate with type '(Builtin.RawPointer) -> UnsafeRawPointer'}} + // expected-note@-4 {{found candidate with type '(OpaquePointer) -> UnsafeRawPointer'}} + // expected-note@-5 {{found candidate with type '(UnsafeMutableRawPointer) -> UnsafeRawPointer'}} +} + +func SR12689_1(_ u: Int) -> String { "" } // expected-note {{found this candidate}} expected-note {{candidate expects value of type 'Int' for parameter #1}} +func SR12689_1(_ u: String) -> Double { 0 } // expected-note {{found this candidate}} expected-note {{candidate expects value of type 'String' for parameter #1}} +func SR12689_2(_ u: Int) {} + +SR12689_2(SR12689_1(1 as Double)) // expected-error {{no exact matches in call to global function 'SR12689_1'}} +SR12689_1(1 as Double) as Int // expected-error {{no exact matches in call to global function 'SR12689_1'}} + +// Ambiguos OverloadRefExpr +func SR12689_O(_ p: Int) {} // expected-note {{found candidate with type '(Int) -> ()'}} +func SR12689_O(_ p: Double) {} // expected-note {{found candidate with type '(Double) -> ()'}} +func SR12689_3(_ param: (String)-> Void) {} + +SR12689_3(SR12689_O) // expected-error {{no 'SR12689_O' candidates produce the expected type '(String) -> Void' for parameter #0}} diff --git a/test/Sema/enum_raw_representable.swift b/test/Sema/enum_raw_representable.swift index 39e89779ddf0d..59323fbb591d3 100644 --- a/test/Sema/enum_raw_representable.swift +++ b/test/Sema/enum_raw_representable.swift @@ -135,19 +135,23 @@ rdar32431165_2(E_32431165.bar) rdar32431165_2(42, E_32431165.bar) // expected-error@-1 {{cannot convert value of type 'E_32431165' to expected argument type 'String'}} {{34-34=.rawValue}} -E_32431165.bar == "bar" -// expected-error@-1 {{cannot convert value of type 'E_32431165' to expected argument type 'String}} {{15-15=.rawValue}} - -"bar" == E_32431165.bar -// expected-error@-1 {{cannot convert value of type 'E_32431165' to expected argument type 'String}} {{24-24=.rawValue}} +// TODO: In following two examples it's possible to fix a problem by either using `.rawValue` on first argument +// or constructing raw representable type from second, both ways are valid. +do { + E_32431165.bar == "bar" + // expected-error@-1 {{binary operator '==' cannot be applied to operands of type 'E_32431165' and 'String'}} expected-note@-1 {{partially matching parameter lists: (String, String)}} + + "bar" == E_32431165.bar + // expected-error@-1 {{binary operator '==' cannot be applied to operands of type 'String' and 'E_32431165'}} expected-note@-1 {{partially matching parameter lists: (String, String)}} +} -func rdar32431165_overloaded() -> Int { 42 } // expected-note {{found candidate with type 'Int'}} +func rdar32431165_overloaded() -> Int { 42 } // expected-note {{'rdar32431165_overloaded()' produces 'Int', not the expected contextual result type 'E_32431165'}} func rdar32431165_overloaded() -> String { "A" } // expected-note {{'rdar32431165_overloaded()' produces 'String', not the expected contextual result type 'E_32431165'}} func test_candidate_diagnostic() { func test_argument(_: E_32431165) {} - let _: E_32431165 = rdar32431165_overloaded() // expected-error {{no exact matches in call to global function 'rdar32431165_overloaded'}} + let _: E_32431165 = rdar32431165_overloaded() // expected-error {{no 'rdar32431165_overloaded' candidates produce the expected contextual result type 'E_32431165'}} test_argument(rdar32431165_overloaded()) // expected-error {{cannot convert value of type 'String' to expected argument type 'E_32431165'}} {{17-17=E_32431165(rawValue: }} {{42-42=) ?? <#default value#>}} } @@ -197,7 +201,8 @@ func sr8150_mutable(obj: SR8150Box) { sr8150_helper1(opt) // expected-error@-1 {{cannot convert value of type 'Bar?' to expected argument type 'Double'}} {{23-23=?.rawValue ?? <#default value#>}} sr8150_helper1(opt ?? Bar.a) - // expected-error@-1 {{cannot convert value of type 'Bar' to expected argument type 'Double'}} {{20-20=(}} {{32-32=).rawValue}} + // expected-error@-1 {{no exact matches in call to global function 'sr8150_helper1'}} + // expected-note@-2 {{candidate expects value of type 'Bar' for parameter #0}} {{20-20=(}} {{32-32=).rawValue}} let _: Double? = opt // expected-error@-1 {{cannot convert value of type 'Bar?' to specified type 'Double?'}} {{25-25=?.rawValue}} } diff --git a/test/Serialization/builtin.swift b/test/Serialization/builtin.swift index 3dc709ca2cef3..cce143203088b 100644 --- a/test/Serialization/builtin.swift +++ b/test/Serialization/builtin.swift @@ -11,4 +11,4 @@ var a : TheBuiltinInt64 // Check that it really is Builtin.Int64. var wrapped = Int64(a) // okay -var badWrapped = Int32(a) // expected-error{{initializer 'init(_:)' requires that 'TheBuiltinInt64' conform to 'BinaryInteger'}} +var badWrapped = Int32(a) // expected-error{{no exact matches in call to initializer}} diff --git a/test/attr/attr_dynamic_member_lookup.swift b/test/attr/attr_dynamic_member_lookup.swift index 06c810448855d..f13c6913c7a4b 100644 --- a/test/attr/attr_dynamic_member_lookup.swift +++ b/test/attr/attr_dynamic_member_lookup.swift @@ -600,9 +600,7 @@ func keypath_with_subscripts(_ arr: SubscriptLens<[Int]>, func keypath_with_incorrect_return_type(_ arr: Lens>) { for idx in 0..' conform to 'Strideable'}} - // expected-error@-2 {{cannot convert value of type 'Int' to expected argument type 'Lens'}} - // expected-error@-3 {{referencing operator function '..<' on 'Comparable' requires that 'Lens' conform to 'Comparable'}} + // expected-error@-1 {{cannot convert value of type 'Int' to expected argument type 'Lens'}} let _ = arr[idx] } } diff --git a/test/decl/subscript/subscripting.swift b/test/decl/subscript/subscripting.swift index 170b8fc9baea3..667f8e511ca42 100644 --- a/test/decl/subscript/subscripting.swift +++ b/test/decl/subscript/subscripting.swift @@ -349,9 +349,9 @@ func testUnresolvedMemberSubscriptFixit(_ s0: GenSubscriptFixitTest) { struct SubscriptTest1 { subscript(keyword:String) -> Bool { return true } - // expected-note@-1 5 {{found this candidate}} expected-note@-1 {{found candidate with type 'Bool'}} + // expected-note@-1 5 {{found this candidate}} expected-note@-1 {{'subscript(_:)' produces 'Bool', not the expected contextual result type 'Int'}} subscript(keyword:String) -> String? {return nil } - // expected-note@-1 5 {{found this candidate}} expected-note@-1 {{found candidate with type 'String?'}} + // expected-note@-1 5 {{found this candidate}} expected-note@-1 {{'subscript(_:)' produces 'String?', not the expected contextual result type 'Int'}} subscript(arg: SubClass) -> Bool { return true } // expected-note {{declared here}} // expected-note@-1 2 {{found this candidate}} @@ -397,14 +397,12 @@ func testSubscript1(_ s1 : SubscriptTest1) { struct SubscriptTest2 { subscript(a : String, b : Int) -> Int { return 0 } // expected-note {{candidate expects value of type 'Int' for parameter #2}} - // expected-note@-1 {{declared here}} - // expected-note@-2 {{candidate has partially matching parameter list (String, Int)}} - subscript(a : String, b : String) -> Int { return 0 } // expected-note {{candidate expects value of type 'String' for parameter #2}} - // expected-note@-1 {{candidate has partially matching parameter list (String, String)}} + // expected-note@-1 2 {{declared here}} + subscript(a : String, b : String) -> Int { return 0 } // expected-note {{candidate expects value of type 'String' for parameter #2}} } func testSubscript1(_ s2 : SubscriptTest2) { - _ = s2["foo"] // expected-error {{no exact matches in call to subscript}} + _ = s2["foo"] // expected-error {{missing argument for parameter #2 in call}} let a = s2["foo", 1.0] // expected-error {{no exact matches in call to subscript}} diff --git a/test/expr/expressions.swift b/test/expr/expressions.swift index f6aa38a7c39c4..819d681894bec 100644 --- a/test/expr/expressions.swift +++ b/test/expr/expressions.swift @@ -791,7 +791,6 @@ func testNilCoalescePrecedence(cond: Bool, a: Int?, r: ClosedRange?) { // ?? should have lower precedence than range and arithmetic operators. let r1 = r ?? (0...42) // ok let r2 = (r ?? 0)...42 // not ok: expected-error 2 {{cannot convert value of type 'Int' to expected argument type 'ClosedRange'}} - // expected-error@-1 {{referencing operator function '...' on 'Comparable' requires that 'ClosedRange' conform to 'Comparable'}} let r3 = r ?? 0...42 // parses as the first one, not the second. diff --git a/test/expr/postfix/dot/init_ref_delegation.swift b/test/expr/postfix/dot/init_ref_delegation.swift index 7acf0d033477c..e5ffb0be4d804 100644 --- a/test/expr/postfix/dot/init_ref_delegation.swift +++ b/test/expr/postfix/dot/init_ref_delegation.swift @@ -323,12 +323,12 @@ class TestOverloadSets { self.init(5, 5) // expected-error{{extra argument in call}} } - convenience init(a : Z0) { // expected-note{{candidate has partially matching parameter list (a: Z0)}} + convenience init(a : Z0) { // expected-note{{candidate expects value of type 'Z0' for parameter #1}} self.init(42 as Int8) // expected-error{{no exact matches in call to initializer}} } - init(value: Int) { /* ... */ } // expected-note{{candidate has partially matching parameter list (value: Int)}} - init(value: Double) { /* ... */ } // expected-note{{candidate has partially matching parameter list (value: Double)}} + init(value: Int) { /* ... */ } // expected-note{{candidate expects value of type 'Int' for parameter #1}} + init(value: Double) { /* ... */ } // expected-note{{candidate expects value of type 'Double' for parameter #1}} } class TestNestedExpr { diff --git a/test/expr/unary/keypath/keypath.swift b/test/expr/unary/keypath/keypath.swift index 449876f2c8b98..4495b4a6249fc 100644 --- a/test/expr/unary/keypath/keypath.swift +++ b/test/expr/unary/keypath/keypath.swift @@ -507,7 +507,7 @@ func testLabeledSubscript() { let k = \AA.[labeled: 0] // TODO: These ought to work without errors. - let _ = \AA.[keyPath: k] // expected-error {{extraneous argument label 'keyPath:' in call}} + let _ = \AA.[keyPath: k] // expected-error@-1 {{cannot convert value of type 'KeyPath' to expected argument type 'Int'}} let _ = \AA.[keyPath: \AA.[labeled: 0]] // expected-error {{extraneous argument label 'keyPath:' in call}} diff --git a/test/expr/unary/keypath/salvage-with-other-type-errors.swift b/test/expr/unary/keypath/salvage-with-other-type-errors.swift index 56aeeb10982e9..f36b32cb46cad 100644 --- a/test/expr/unary/keypath/salvage-with-other-type-errors.swift +++ b/test/expr/unary/keypath/salvage-with-other-type-errors.swift @@ -52,7 +52,7 @@ protocol Bindable: class { } extension Bindable { func test(to targetKeyPath: ReferenceWritableKeyPath, change: Value?) { if self[keyPath:targetKeyPath] != change { - // expected-error@-1 {{operator function '!=' requires that 'Value' conform to 'Equatable'}} + // expected-error@-1 {{binary operator '!=' cannot be applied to operands of type 'Value' and 'Value?'}} self[keyPath: targetKeyPath] = change! } } diff --git a/test/stdlib/ArrayDiagnostics.swift b/test/stdlib/ArrayDiagnostics.swift index 2b6cf254d6c63..a13948e7f4b18 100644 --- a/test/stdlib/ArrayDiagnostics.swift +++ b/test/stdlib/ArrayDiagnostics.swift @@ -4,5 +4,5 @@ class NotEquatable {} func test_ArrayOfNotEquatableIsNotEquatable() { var a = [ NotEquatable(), NotEquatable() ] - if a == a {} // expected-error {{operator function '==' requires that 'NotEquatable' conform to 'Equatable'}} + if a == a {} // expected-error {{referencing operator function '==' on 'Array' requires that 'NotEquatable' conform to 'Equatable'}} } diff --git a/test/stdlib/KeyPathAppending.swift b/test/stdlib/KeyPathAppending.swift index a4c4f3217d143..a416e3c7cebc1 100644 --- a/test/stdlib/KeyPathAppending.swift +++ b/test/stdlib/KeyPathAppending.swift @@ -58,22 +58,20 @@ func mismatchedAppends(readOnlyLeft: KeyPath, // expected-note@-2 {{arguments to generic parameter 'Root' ('T' and 'V') are expected to be equal}} _ = readOnlyRight.appending(path: referenceLeft) - // expected-error@-1 {{cannot convert value of type 'ReferenceWritableKeyPath' to expected argument type 'ReferenceWritableKeyPath'}} - // expected-note@-2 {{arguments to generic parameter 'Root' ('T' and 'V') are expected to be equal}} + // expected-error@-1 {{no exact matches in call to instance method 'appending'}} _ = writableRight.appending(path: readOnlyLeft) - // expected-error@-1 {{instance method 'appending(path:)' requires that 'KeyPath' inherit from 'KeyPath'}} + // expected-error@-1 {{no exact matches in call to instance method 'appending'}} _ = writableRight.appending(path: writableLeft) // expected-error@-1 {{cannot convert value of type 'WritableKeyPath' to expected argument type 'WritableKeyPath'}} // expected-note@-2 {{arguments to generic parameter 'Root' ('T' and 'V') are expected to be equal}} _ = writableRight.appending(path: referenceLeft) - // expected-error@-1 {{cannot convert value of type 'ReferenceWritableKeyPath' to expected argument type 'ReferenceWritableKeyPath'}} - // expected-note@-2 {{arguments to generic parameter 'Root' ('T' and 'V') are expected to be equal}} + // expected-error@-1 {{no exact matches in call to instance method 'appending'}} _ = referenceRight.appending(path: readOnlyLeft) - // expected-error@-1 {{instance method 'appending(path:)' requires that 'KeyPath' inherit from 'KeyPath'}} + // expected-error@-1 {{no exact matches in call to instance method 'appending'}} _ = referenceRight.appending(path: writableLeft) // expected-error@-1 {{cannot convert value of type 'WritableKeyPath' to expected argument type 'WritableKeyPath'}} diff --git a/test/stdlib/StringDiagnostics.swift b/test/stdlib/StringDiagnostics.swift index 3a53a26c69ee0..c3fde8ff884f5 100644 --- a/test/stdlib/StringDiagnostics.swift +++ b/test/stdlib/StringDiagnostics.swift @@ -48,6 +48,7 @@ func testAmbiguousStringComparisons(s: String) { // Shouldn't suggest 'as' in a pattern-matching context, as opposed to all these other situations if case nsString = "" {} // expected-error{{expression pattern of type 'NSString' cannot match values of type 'String'}} + // expected-note@-1 {{overloads for '~=' exist with these partially matching parameter lists: (Substring, String)}} } func testStringDeprecation(hello: String) { diff --git a/test/stdlib/UnicodeScalarDiagnostics.swift b/test/stdlib/UnicodeScalarDiagnostics.swift index 6446f3e7155bb..6e30489484d22 100644 --- a/test/stdlib/UnicodeScalarDiagnostics.swift +++ b/test/stdlib/UnicodeScalarDiagnostics.swift @@ -13,9 +13,9 @@ func test_UnicodeScalarDoesNotImplementArithmetic(_ us: UnicodeScalar, i: Int) { let a4 = "a" / "b" // expected-error {{binary operator '/' cannot be applied to two 'String' operands}} let b1 = us + us // expected-error {{referencing operator function '+' on 'RangeReplaceableCollection' requires that 'UnicodeScalar' (aka 'Unicode.Scalar') conform to 'RangeReplaceableCollection'}} - let b2 = us - us // expected-error {{referencing operator function '-' on 'FloatingPoint' requires that 'UnicodeScalar' (aka 'Unicode.Scalar') conform to 'FloatingPoint'}} - let b3 = us * us // expected-error {{referencing operator function '*' on 'FloatingPoint' requires that 'UnicodeScalar' (aka 'Unicode.Scalar') conform to 'FloatingPoint'}} - let b4 = us / us // expected-error {{referencing operator function '/' on 'FloatingPoint' requires that 'UnicodeScalar' (aka 'Unicode.Scalar') conform to 'FloatingPoint'}} + let b2 = us - us // expected-error {{binary operator '-' cannot be applied to two 'UnicodeScalar' (aka 'Unicode.Scalar') operands}} + let b3 = us * us // expected-error {{binary operator '*' cannot be applied to two 'UnicodeScalar' (aka 'Unicode.Scalar') operands}} + let b4 = us / us // expected-error {{binary operator '/' cannot be applied to two 'UnicodeScalar' (aka 'Unicode.Scalar') operands}} let c1 = us + i // expected-error {{cannot convert value of type 'UnicodeScalar' (aka 'Unicode.Scalar') to expected argument type 'Int'}} let c2 = us - i // expected-error {{cannot convert value of type 'UnicodeScalar' (aka 'Unicode.Scalar') to expected argument type 'Int'}} diff --git a/test/stdlib/UnsafePointerDiagnostics.swift b/test/stdlib/UnsafePointerDiagnostics.swift index 7b654dcfdcc77..b41e5401218af 100644 --- a/test/stdlib/UnsafePointerDiagnostics.swift +++ b/test/stdlib/UnsafePointerDiagnostics.swift @@ -67,8 +67,8 @@ func unsafePointerConversionAvailability( _ = UnsafeMutablePointer(umpi) // expected-warning {{UnsafeMutablePointer has been replaced by UnsafeMutableRawPointer}} _ = UnsafeMutablePointer(umps) // expected-warning {{UnsafeMutablePointer has been replaced by UnsafeMutableRawPointer}} - _ = UnsafePointer(rp) // expected-error {{cannot convert value of type 'UnsafeRawPointer' to expected argument type 'Builtin.RawPointer'}} expected-warning {{UnsafePointer has been replaced by UnsafeRawPointer}} - _ = UnsafePointer(mrp) // expected-error {{cannot convert value of type 'UnsafeMutableRawPointer' to expected argument type 'Builtin.RawPointer'}} expected-warning {{UnsafePointer has been replaced by UnsafeRawPointer}} + _ = UnsafePointer(rp) // expected-error {{no exact matches in call to initializer}} expected-warning {{UnsafePointer has been replaced by UnsafeRawPointer}} + _ = UnsafePointer(mrp) // expected-error {{no exact matches in call to initializer}} expected-warning {{UnsafePointer has been replaced by UnsafeRawPointer}} _ = UnsafePointer(umpv) // expected-warning {{UnsafePointer has been replaced by UnsafeRawPointer}} _ = UnsafePointer(upv) // expected-warning {{UnsafePointer has been replaced by UnsafeRawPointer}} _ = UnsafePointer(umpi) // expected-warning {{UnsafePointer has been replaced by UnsafeRawPointer}} @@ -81,10 +81,10 @@ func unsafePointerConversionAvailability( _ = UnsafeMutablePointer(orp) // expected-error {{no exact matches in call to initializer}} _ = UnsafeMutablePointer(omrp) // expected-error {{no exact matches in call to initializer}} - _ = UnsafePointer(rp) // expected-error {{cannot convert value of type 'UnsafeRawPointer' to expected argument type 'Builtin.RawPointer'}} - _ = UnsafePointer(mrp) // expected-error {{cannot convert value of type 'UnsafeMutableRawPointer' to expected argument type 'Builtin.RawPointer'}} - _ = UnsafePointer(orp) // expected-error {{cannot convert value of type 'UnsafeRawPointer?' to expected argument type 'Builtin.RawPointer'}} - _ = UnsafePointer(omrp) // expected-error {{cannot convert value of type 'UnsafeMutableRawPointer?' to expected argument type 'Builtin.RawPointer'}} + _ = UnsafePointer(rp) // expected-error {{no exact matches in call to initializer}} + _ = UnsafePointer(mrp) // expected-error {{no exact matches in call to initializer}} + _ = UnsafePointer(orp) // expected-error {{no exact matches in call to initializer}} + _ = UnsafePointer(omrp) // expected-error {{no exact matches in call to initializer}} _ = UnsafePointer(ups) // expected-error {{cannot convert value of type 'UnsafePointer' to expected argument type 'UnsafePointer'}} // expected-note@-1 {{arguments to generic parameter 'Pointee' ('String' and 'Int') are expected to be equal}} diff --git a/test/stmt/foreach.swift b/test/stmt/foreach.swift index 8b7b8d0cea18d..07441ed39f079 100644 --- a/test/stmt/foreach.swift +++ b/test/stmt/foreach.swift @@ -68,7 +68,7 @@ func patterns(gir: GoodRange, gtr: GoodTupleIterator) { for (i, f) in gtr { sum = sum + i sumf = sumf + f - sum = sum + f // expected-error {{cannot convert value of type 'Float' to expected argument type 'Int'}} + sum = sum + f // expected-error {{cannot convert value of type 'Float' to expected argument type 'Int'}} {{17-17=Int(}} {{18-18=)}} } for (i, _) : (Int, Float) in gtr { sum = sum + i } diff --git a/test/type/protocol_composition.swift b/test/type/protocol_composition.swift index c6ec77766eb01..f6df6bdc94d18 100644 --- a/test/type/protocol_composition.swift +++ b/test/type/protocol_composition.swift @@ -174,6 +174,10 @@ takesP1AndP2([AnyObject & protocol_composition.P1 & P2]()) takesP1AndP2([AnyObject & P1 & protocol_composition.P2]()) takesP1AndP2([DoesNotExist & P1 & P2]()) // expected-error {{cannot find 'DoesNotExist' in scope}} takesP1AndP2([Swift.DoesNotExist & P1 & P2]()) // expected-error {{module 'Swift' has no member named 'DoesNotExist'}} +// expected-error@-1 {{binary operator '&' cannot be applied to operands of type 'UInt8' and 'P1.Protocol'}} +// expected-error@-2 {{binary operator '&' cannot be applied to operands of type 'UInt8' and 'P2.Protocol'}} +// expected-note@-3 2 {{overloads for '&' exist with these partially matching parameter lists}} + typealias T08 = P1 & inout P2 // expected-error {{'inout' may only be used on parameters}} typealias T09 = P1 & __shared P2 // expected-error {{'__shared' may only be used on parameters}} diff --git a/test/type/types.swift b/test/type/types.swift index 7716a1582c3cf..135607476d43f 100644 --- a/test/type/types.swift +++ b/test/type/types.swift @@ -20,14 +20,7 @@ var d4 : () -> Int = { d2 } // expected-error{{function produces expected type if #available(macOS 9999, iOS 9999, tvOS 9999, watchOS 9999, *) { var e0 : [Int] - e0[] // expected-error {{no exact matches in call to subscript}} - // expected-note@-1 {{candidate has partially matching parameter list (Int)}} - // expected-note@-2 {{candidate has partially matching parameter list (Range)}} - // expected-note@-3 {{candidate has partially matching parameter list ((UnboundedRange_) -> ())}} - // expected-note@-4 {{candidate has partially matching parameter list (RangeSet.Index>)}} - // expected-note@-5 {{candidate has partially matching parameter list (Range.Index>)}} - // expected-note@-6 {{candidate has partially matching parameter list ((UnboundedRange_) -> ())}} - // expected-note@-7 {{candidate has partially matching parameter list (RangeSet.Index>)}} + e0[] // expected-error {{missing argument for parameter #1 in call}} {{6-6=<#Int#>}} } var f0 : [Float] diff --git a/validation-test/Sema/type_checker_perf/slow/rdar53589951.swift b/validation-test/Sema/type_checker_perf/slow/rdar53589951.swift index 702c92ee62ea9..b2bc3356a2986 100644 --- a/validation-test/Sema/type_checker_perf/slow/rdar53589951.swift +++ b/validation-test/Sema/type_checker_perf/slow/rdar53589951.swift @@ -1,5 +1,6 @@ // RUN: %target-typecheck-verify-swift -solver-expression-time-threshold=1 // REQUIRES: tools-release,no_asan +// REQUIRES: rdar36854536 class Color { init(hue: Double, saturation: Double, brightness: Double, alpha: Double) {}