Skip to content

Commit

Permalink
[Diagnostic] Don't fix partial mismatch for sub-types associated with…
Browse files Browse the repository at this point in the history
… optional conversion

If mismatch detected by `repairFailures` is related to a complex
wrapped value of optional type formed from optional-to-optional
or value-to-optional conversion let's not try to fix it directly
but let `simplifyRestrictedConstraintImpl` record a top-level fix
for more context.

Resolves: rdar://problem/59703585
  • Loading branch information
xedin committed Mar 3, 2020
1 parent b5cb81b commit f7b2645
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 0 deletions.
6 changes: 6 additions & 0 deletions lib/Sema/CSDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1884,6 +1884,12 @@ bool ContextualFailure::diagnoseAsError() {
return true;
}

if (isa<AssignExpr>(anchor)) {
emitDiagnostic(anchor->getLoc(), diag::cannot_convert_assign,
getFromType(), getToType());
return true;
}

return false;
}

Expand Down
6 changes: 6 additions & 0 deletions lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3788,6 +3788,12 @@ bool ConstraintSystem::repairFailures(
tupleLocator->isLastElement<LocatorPathElt::GenericArgument>())
break;

// If the mismatch is a part of either optional-to-optional or
// value-to-optional conversions, let's allow fix refer to a complete
// top level type and not just a part of it.
if (tupleLocator->findLast<LocatorPathElt::OptionalPayload>())
break;

ConstraintFix *fix;
if (tupleLocator->isLastElement<LocatorPathElt::FunctionArgument>()) {
fix = AllowFunctionTypeMismatch::create(*this, lhs, rhs, tupleLocator, index);
Expand Down
12 changes: 12 additions & 0 deletions test/Constraints/function_conversion.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,15 @@ noEscapeParam = takesAny // expected-error {{converting non-escaping value to 'A
func rdar_59773317(x: () -> Int) -> (() -> Int)? { // expected-note {{parameter 'x' is implicitly non-escaping}}
return x // expected-error {{using non-escaping parameter 'x' in a context expecting an @escaping closure}}
}

// rdar://problem/59703585 - Wrong error message when signature of a C function type and Swift implementation mismatch
func rdar_59703585() {
typealias Fn = @convention(c) (UnsafePointer<Int8>?, UnsafeMutableRawPointer?) -> Void

func swiftCallback(someString: UnsafePointer<Int8>, someObject: UnsafeMutableRawPointer?) {}

var cb: Fn? = nil

cb = swiftCallback
// expected-error@-1 {{cannot assign value of type '(UnsafePointer<Int8>, UnsafeMutableRawPointer?) -> ()' to type 'Fn?' (aka 'Optional<@convention(c) (Optional<UnsafePointer<Int8>>, Optional<UnsafeMutableRawPointer>) -> ()>')}}
}

0 comments on commit f7b2645

Please sign in to comment.