mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[ConstraintSystem] Simplify diagnoseAmbiguityWithEphemeralPointers
Don't attempt to figure out what exactly is ambiguous, let `diagnoseAmbiguity` take care of that. Simplify make sure that only some of the solutions have fixes and these fixes are all related to use of ephemeral pointers.
This commit is contained in:
@@ -2891,8 +2891,6 @@ static bool diagnoseConflictingGenericArguments(ConstraintSystem &cs,
|
||||
static bool
|
||||
diagnoseAmbiguityWithEphemeralPointers(ConstraintSystem &cs,
|
||||
ArrayRef<Solution> solutions) {
|
||||
llvm::MapVector<Expr *, ValueDecl *> ambiguities;
|
||||
|
||||
bool allSolutionsHaveFixes = true;
|
||||
for (const auto &solution : solutions) {
|
||||
if (solution.Fixes.empty()) {
|
||||
@@ -2900,23 +2898,10 @@ diagnoseAmbiguityWithEphemeralPointers(ConstraintSystem &cs,
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const auto *fix : solution.Fixes) {
|
||||
if (fix->getKind() != FixKind::TreatEphemeralAsNonEphemeral)
|
||||
if (!llvm::all_of(solution.Fixes, [](const ConstraintFix *fix) {
|
||||
return fix->getKind() == FixKind::TreatEphemeralAsNonEphemeral;
|
||||
}))
|
||||
return false;
|
||||
|
||||
// Ephemeral pointers are only possible in argument positions.
|
||||
if (auto *anchor = simplifyLocatorToAnchor(fix->getLocator())) {
|
||||
anchor = cast<InOutExpr>(anchor)->getSubExpr();
|
||||
|
||||
auto overload = solution.getOverloadChoiceIfAvailable(
|
||||
cs.getConstraintLocator(anchor));
|
||||
|
||||
if (!(overload && overload->choice.isDecl()))
|
||||
return false;
|
||||
|
||||
ambiguities.insert({anchor, overload->choice.getDecl()});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If all solutions have fixes for ephemeral pointers, let's
|
||||
@@ -2924,13 +2909,10 @@ diagnoseAmbiguityWithEphemeralPointers(ConstraintSystem &cs,
|
||||
if (allSolutionsHaveFixes)
|
||||
return false;
|
||||
|
||||
auto &DE = cs.getASTContext().Diags;
|
||||
for (const auto &entry : ambiguities) {
|
||||
DE.diagnose(entry.first->getLoc(), diag::ambiguous_decl_ref,
|
||||
DeclNameRef(entry.second->getBaseName()));
|
||||
}
|
||||
|
||||
return true;
|
||||
// If only some of the solutions have ephemeral pointer fixes
|
||||
// let's let `diagnoseAmbiguity` diagnose the problem either
|
||||
// with affected argument or related declaration e.g. function ref.
|
||||
return cs.diagnoseAmbiguity(solutions);
|
||||
}
|
||||
|
||||
bool ConstraintSystem::diagnoseAmbiguityWithFixes(
|
||||
|
||||
@@ -520,3 +520,10 @@ func testArgumentLabelReferencing() {
|
||||
// expected-note@-5 {{implicit argument conversion from '[Int]' to 'UnsafePointer<Int>' produces a pointer valid only for the duration of the call to 'takesTwoPointers(ptr:ptr:)'}}
|
||||
// expected-note@-6 {{use the 'withUnsafeBufferPointer' method on Array in order to explicitly convert argument to buffer pointer valid for a defined scope}}
|
||||
}
|
||||
|
||||
func ambiguous_fn(@_nonEphemeral _ ptr: UnsafePointer<Int>) {} // expected-note {{found this candidate}}
|
||||
func ambiguous_fn(_ ptr: UnsafeRawPointer) {} // expected-note {{found this candidate}}
|
||||
|
||||
func test_ambiguity_with_function_instead_of_argument(_ x: inout Int) {
|
||||
ambiguous_fn(&x) // expected-error {{ambiguous use of 'ambiguous_fn'}}
|
||||
}
|
||||
|
||||
@@ -467,3 +467,10 @@ func testNonEphemeralInMemberwiseInits() {
|
||||
// expected-note@-1 {{implicit argument conversion from 'String' to 'UnsafePointer<Int8>' produces a pointer valid only for the duration of the call to 'const'}}
|
||||
// expected-note@-2 {{use the 'withCString' method on String in order to explicitly convert argument to pointer valid for a defined scope}}
|
||||
}
|
||||
|
||||
func ambiguous_fn(@_nonEphemeral _ ptr: UnsafePointer<Int>) {} // expected-note {{found this candidate}}
|
||||
func ambiguous_fn(_ ptr: UnsafeRawPointer) {} // expected-note {{found this candidate}}
|
||||
|
||||
func test_ambiguity_with_function_instead_of_argument(_ x: inout Int) {
|
||||
ambiguous_fn(&x) // expected-error {{ambiguous use of 'ambiguous_fn'}}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user