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-14280] Ternary operator block assignment with @convention attribute confuses compiler #56639

Closed
iby opened this issue Feb 27, 2021 · 6 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself type checker Area → compiler: Semantic analysis

Comments

@iby
Copy link

iby commented Feb 27, 2021

Previous ID SR-14280
Radar rdar://problem/74877828
Original Reporter @iby
Type Bug
Status Resolved
Resolution Done
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, TypeChecker
Assignee None
Priority Medium

md5: d78ac8d662e0d015be7548d7b9afa64f

Issue Description:

Compiler gets confused by block with (AFAIK) any @convention attribute. Removing @convention(c) from below compiles as expected.

let x: (@convention(block) () -> Void)?
x = Bool.random() ? nil : {} // (2, 3) Type of expression is ambiguous without more context
let x: (@convention(c) () -> Void)?
x = Bool.random() ? {} : {} // (3, 19) A C function pointer can only be formed from a reference to a 'func' or a literal closure
@LucianoPAlmeida
Copy link
Collaborator

By a quick look to solver debug output the problem in this case is just ambiguity where solver finds 2 viable solutions `(@convention(block) () -> Void)?` and `(() -> ())?` for ternary result type var.

@iby
Copy link
Author

iby commented Feb 28, 2021

That is a workaround, of course. I wouldn't mind that for tiny closures, but with a signature with with 5+ parameters this becomes a very painful experience.

@LucianoPAlmeida
Copy link
Collaborator

Ah, for the case with @conversion(c) is really not possible to convert from a closure that is inferred as a swift closure to a c convention one(except in some cases where compiler can determine context statically). So, basically almost all thick(swift, block) to thin(c, thin) conversions are not allowed because thick(swift, block) closures can capture context.
In the first case with block should not be ambiguous, it should typecheck correctly.

@typesanitizer
Copy link

@swift-ci create

@iby
Copy link
Author

iby commented Mar 2, 2021

Thanks for the input @LucianoPAlmeida. The issue is not about being able to convert between different conventions, it's about the compiler failing to accept two valid ones in a rather very simple (from the end usage perspective) scenario. The original issue I've run in was with … ? nil : {} and @convention(c) (like the first approach). My guess is that the compiler doesn't assume (but needs to) that both block operands are of the same convention as the declaration it's being assigned to. The error in second example is the consequence of that – both block don't capture context and are valid to be passed into C.

@LucianoPAlmeida
Copy link
Collaborator

Fixed on main by #36208
@iby Can you please verify on the next available snapshot and close? Thanks

@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
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

3 participants