Skip to content

[Typed throws] Handle function conversions involving different thrown errors #68995

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

DougGregor
Copy link
Member

Teach the constraint solver about the subtyping rule that permits converting one function type to another when the effective thrown error type of one is a subtype of the effective thrown error type of the other, using any Error for untyped throws and Never for non-throwing.

With minor other fixes, this allows us to use typed throws for generic functions that carry a typed error from their arguments through to themselves, which is in effect a typed rethrows:

func mapArray<T, U, E: Error>(_ array: [T], body: (T) throws(E) -> U)
throws(E) -> [U] {
  var resultArray: [U] = .init()
  for value in array {
    resultArray.append(try body(value))
  }
  return resultArray
}

… errors

Teach the constraint solver about the subtyping rule that permits
converting one function type to another when the effective thrown error
type of one is a subtype of the effective thrown error type of the
other, using `any Error` for untyped throws and `Never` for
non-throwing.

With minor other fixes, this allows us to use typed throws for generic
functions that carry a typed error from their arguments through to
themselves, which is in effect a typed `rethrows`:

```swift
func mapArray<T, U, E: Error>(_ array: [T], body: (T) throws(E) -> U)
throws(E) -> [U] {
  var resultArray: [U] = .init()
  for value in array {
    resultArray.append(try body(value))
  }
  return resultArray
}
```
@DougGregor
Copy link
Member Author

@swift-ci please smoke test

This won't happen in "normal" Swift code, but can occur with tests that
use `-parse-stdlib`.
@DougGregor
Copy link
Member Author

@swift-ci please smoke test

Copy link
Contributor

@xedin xedin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Left a couple of comments inline.

@@ -14999,6 +15105,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
case FixKind::AllowAssociatedValueMismatch:
case FixKind::GenericArgumentsMismatch:
case FixKind::AllowConcreteTypeSpecialization:
case FixKind::IgnoreThrownErrorMismatch:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder how impactful this fix is vs. i.e. @escaping mismatch should it be more like a conversion mismatch which is has impact of 2?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a good sense of what the right impact score should be. I'll go with your suggestion of 2.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If one overload choice has a mismatch on argument or result type and another on throws should that be ambiguous?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I would not think it should be ambiguous. Within a single module, we don't allow overloading on throws alone, but of course this overloading can happen across module boundaries.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I am trying to ask is what overload is going to be a better suggestion in such case or whether both overloads should be mentioned, that’s where the impact matters.

@DougGregor
Copy link
Member Author

@swift-ci please smoke test

@DougGregor DougGregor merged commit 78c925b into swiftlang:main Oct 7, 2023
@DougGregor DougGregor deleted the typed-throws-function-conversions branch October 7, 2023 17:14
@DougGregor DougGregor mentioned this pull request Oct 11, 2023
21 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants