Skip to content
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

Poor type inference with typed throws #78639

Open
karwa opened this issue Jan 14, 2025 · 1 comment
Open

Poor type inference with typed throws #78639

karwa opened this issue Jan 14, 2025 · 1 comment
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler itself error handling generics Feature: generic declarations and types Swift 6.2-dev throws & rethrows Feature → error handling: throws & rethrows type checker Area → compiler: Semantic analysis type inference Feature: type inference typed throws Feature → error handling → throws & rethrows: Typed throws unexpected error Bug: Unexpected error

Comments

@karwa
Copy link
Contributor

karwa commented Jan 14, 2025

Description

Consider the following function:

extension StaticString {
    func withCString<R>(_ block: (UnsafePointer<CChar>) -> R) -> R {
        self.utf8Start.withMemoryRebound(to: CChar.self, capacity: utf8CodeUnitCount + 1) {
            block($0)
        }
    }
}

We don't need to write explicit signatures for the closure that we pass to withMemoryRebound, because the compiler can infer it - it knows that block($0) returns an R, so the closure does, so the call to withMemoryRebound does, so the body of the function does.

I would expect this same level of type inference when adopting typed throws, but even simple examples require explicit type annotations.

Reproduction

I take the example above, and add an E generic parameter as the type of error thrown by block:

extension StaticString {
    func withCString<E, R>(_ block: (UnsafePointer<CChar>) throws(E) -> R) throws(E) -> R {
        try self.utf8Start.withMemoryRebound(to: CChar.self, capacity: utf8CodeUnitCount + 1) {
            try block($0)
        }
    }
}

It fails to compile.

<source>:3:13: error: thrown expression type 'any Error' cannot be converted to error type 'E'
1 | extension StaticString {
2 |     func withCString<E, R>(_ block: (UnsafePointer<CChar>) throws(E) -> R) throws(E) -> R {
3 |         try self.utf8Start.withMemoryRebound(to: CChar.self, capacity: utf8CodeUnitCount + 1) {
  |             `- error: thrown expression type 'any Error' cannot be converted to error type 'E'
4 |             try block($0)
5 |         }

To make it work, you need to add an explicit type signature to the closure where block is called:

extension StaticString {
    func withCString<E, R>(_ block: (UnsafePointer<CChar>) throws(E) -> R) throws(E) -> R {
        try self.utf8Start.withMemoryRebound(to: CChar.self, capacity: utf8CodeUnitCount + 1) {
            (ptr: UnsafePointer<CChar>) throws(E) -> R in      // <--------
            try block(ptr)
        }
    }
}

Expected behavior

I expect the first example in the reproduction section (with typed throws, without explicit type annotations in the function body) to compile

Environment

Swift version 6.2-dev (LLVM 81859ac55f8d09a, Swift 8ec8a12)
Target: x86_64-unknown-linux-gnu

Also Xcode 16.0 (16A242d)

Additional information

No response

@karwa karwa added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels labels Jan 14, 2025
@xedin
Copy link
Contributor

xedin commented Jan 14, 2025

cc @AnthonyLatsis

@AnthonyLatsis AnthonyLatsis self-assigned this Jan 14, 2025
@AnthonyLatsis AnthonyLatsis added compiler The Swift compiler itself type checker Area → compiler: Semantic analysis generics Feature: generic declarations and types type inference Feature: type inference unexpected error Bug: Unexpected error typed throws Feature → error handling → throws & rethrows: Typed throws Swift 6.2-dev error handling throws & rethrows Feature → error handling: throws & rethrows and removed triage needed This issue needs more specific labels labels Jan 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler itself error handling generics Feature: generic declarations and types Swift 6.2-dev throws & rethrows Feature → error handling: throws & rethrows type checker Area → compiler: Semantic analysis type inference Feature: type inference typed throws Feature → error handling → throws & rethrows: Typed throws unexpected error Bug: Unexpected error
Projects
None yet
Development

No branches or pull requests

3 participants