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

[SR-14051] [docs] Document allowed conversions between function types. #56442

Closed
typesanitizer opened this issue Jan 15, 2021 · 5 comments
Closed
Assignees
Labels
compiler The Swift compiler in itself task

Comments

@typesanitizer
Copy link

Previous ID SR-14051
Radar rdar://problem/73250604
Original Reporter @typesanitizer
Type Task
Status Closed
Resolution Done
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Task
Assignee @typesanitizer
Priority Medium

md5: e32be650ad46166f441bcda46ece65d4

relates to:

Issue Description:

The code for checking conversions between function types is somewhat tricky. It's not immediately obvious what kinds of conversions are allowed, and what the different checks handle (leading to, for example, confusion as in https://bugs.swift.org/browse/SR-14050). We should document the allowed conversions and double-check that all of them have at least 1 test case.

@typesanitizer
Copy link
Author

@swift-ci create

@typesanitizer
Copy link
Author

Posting some notes from a conversation with Slava:

converting from @convention(c) to a thick function should be fine, since you can allocate a context
it’s only conversions to @convention(c) that can’t work
unless the source is statically known, in which case we can emit a thunk that doesn’t capture context

Turns out, there is code which uses this in the stdlib.

    withUnsafeMutablePointer(to: &context) { (context) -> () in
      Builtin.onceWithContext(oncePtr._rawValue, _createStringTableCache // @convention(swift) -> @convention(c) conversion
                              , context._rawValue)
    }

This means that we have something like:

// someFunc's source is available
takesCPtr(someFunc) // okay
let f = someFunc; takesCPtr(f) // error
let g : @convention(c) ... = someFunc; takesCPtr(g) // okay

So the checking for representation matching is not done entirely in CSSimplify's matchFunctionRepresentations, but part of it is done later during SILGen.

    if (srcRepTy->getRepresentation() !=
        FunctionTypeRepresentation::CFunctionPointer) {
      // A "conversion" of a DeclRef a C function pointer is done by referencing
      // the thunk (or original C function) with the C calling convention.
      result = emitCFunctionPointer(SGF, e);
// emitCFunctionPointer
    SGF.SGM.diagnose(expr->getLoc(),
                     diag::c_function_pointer_from_function_with_context,
                     /*closure*/ constant.hasClosureExpr(),
                     kind);

@LucianoPAlmeida
Copy link
Collaborator

theindigamer (JIRA User) I remember from working on this is that because of variance and subtype relation in contravariant and covariant places conversions between diference conventions can cause some confusion. Perhaps this should be documented together as well =]

@typesanitizer
Copy link
Author

PR is up #35457

@typesanitizer
Copy link
Author

PR merged, marking as resolved and closing.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler The Swift compiler in itself task
Projects
None yet
Development

No branches or pull requests

2 participants