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-15218] Enhance interchangeable CGFloat/Double to allow interchange between optional #57540

Open
mattyoung opened this issue Sep 20, 2021 · 10 comments
Labels
compiler The Swift compiler in itself expressions Feature: expressions feature A feature request or implementation implicit conversions Feature: implicit conversions type checker Area → compiler: Semantic analysis

Comments

@mattyoung
Copy link

mattyoung commented Sep 20, 2021

Previous ID SR-15218
Radar rdar://problem/83322839
Original Reporter @mattyoung
Type New Feature
Status In Progress
Resolution
Additional Detail from JIRA
Votes 3
Component/s Compiler
Labels New Feature, StarterBug, TypeChecker
Assignee ldhough (JIRA)
Priority Medium

md5: f6e45c4a9212f2077155f5dc1ee322a7

Issue Description:

Currently passing Double? to parameter of CGFloat? do not work. Please add enhancement to allow such. Additionally, allow multiple level of optionality. Basically allow this:

Double?* <-> CGFloat?* (zero or more level of optionality)

See: https://forums.swift.org/t/why-double-can-pass-to-cgfloat-but-double-cannot/52217/5

@xedin
Copy link
Member

xedin commented Sep 20, 2021

@swift-ci create

@xedin
Copy link
Member

xedin commented Sep 20, 2021

I think this can make an interesting StarterBug.

@amritpan
Copy link
Contributor

Hi @xedin, what should I look at if I'm interested in fixing this but don't have familiarity with where this is handled or what the fix will look like? I'd like to figure out if I can do this before assigning it to myself.

@xedin
Copy link
Member

xedin commented Oct 29, 2021

@amritpan This might be a bit tricky actually due to how conversion restrictions behave. CGFloat/Double conversion needs to wait until all Optional-to-Optional conversions are performed for a particular location, and if the optionality is the same on both sides (e.g. both types are no longer optional) allow Double/CGFloat conversion (Related methods are `matchTypes` and `simplifyRestrictedConstraintImpl` located in CSSimplify.cpp). This is relatively straight-forward to implement and it would result in a valid solution (you can double-check that using `-Xfrontend -debug-constraints` - more info about that @ https://github.com/apple/swift/blob/main/docs/DebuggingTheCompiler.md#debugging-the-type-checker). Next step is to add a number of implicit `.map` calls based on the number of `optional-to-optional` conversions performed for a given location during solution application (related code lives in CSApply.cpp - `coerceToType` method, you can search for ConversionRestrictionKind::DoubleToCGFloat to find relevant location). Here is another catch though - `ConstraintRestrictions` are not positional, so there is no way (currently) to determine how many did each location (identified by a ConstraintLocator) have, you'd have to change that to be able to insert appropriate number of `.map` calls or somehow figure out what was the optionality before first optional-to-optional conversion has been applied to a given location.

@mattyoung
Copy link
Author

Cannot convert value of type 'UnsafeMutablePointer<Double>' to expected argument type 'UnsafeMutablePointer<CGFloat>'

extension Color {
    var luminance: Double {
        var (r, g, b, a): (Double, Double, Double, Double) = (0, 0, 0, 0)
        UIColor(self).getRed(&r, green: &g, blue: &b, alpha: &a)    // Cannot convert value of type 'UnsafeMutablePointer<Double>' to expected argument type 'UnsafeMutablePointer<CGFloat>'
        return 0.2126 * r + 0.7152 * g + 0.0722 * b
    }
}

is this the same problem? Or something different?

@xwu
Copy link
Collaborator

xwu commented Jan 16, 2022

@mattyoung No, that is different and also not a problem, as it works as expected. It is logically impossible to make typed pointers to two types with possibly distinct representations in memory become interchangeable with each other.

@mattyoung
Copy link
Author

Looks like this is fixed: #40047

@xwu
Copy link
Collaborator

xwu commented Feb 17, 2022

@mattyoung No, that is a tailored diagnostic to explain that this is not supported.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@jreference
Copy link

jreference commented May 2, 2023

@xedin Hello, I'm new to this project and tried working on this issue since it's a StarterBug. I went through the code with a debugger and did some experiments. I would like some help please.

  1. How do we generate implicit map calls within ExprRewriter ? I looked at the AST generated when the compiler processes a regular someOptional.map call but it is quite large and complex. In particular, i'm not sure how I can get a reference to Optional::map I can use with a DotSyntaxCallExpr

  2. There was a comment stating that CGFloat/Double conversion needs to wait until all Optional-to-Optional conversions are performed for a particular location. Does this comment mean waiting for all the existing coerceToOptional and DoubleToCGFloat logic within coerceToType() to finish first?

@xedin
Copy link
Member

xedin commented May 4, 2023

@jreference Sorry, we shouldn't have added "good first issue" tag on this one. You'd need to be familiar with some inner working of the solver before attempting to fix it.

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 expressions Feature: expressions feature A feature request or implementation implicit conversions Feature: implicit conversions type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

6 participants