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-4017] It's impossible to add a property setter through extension #46602

Open
swift-ci opened this issue Feb 21, 2017 · 1 comment
Open

[SR-4017] It's impossible to add a property setter through extension #46602

swift-ci opened this issue Feb 21, 2017 · 1 comment
Labels
feature A feature request or implementation improvement

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-4017
Radar None
Original Reporter marc (JIRA User)
Type Improvement
Additional Detail from JIRA
Votes 1
Component/s
Labels Improvement, LanguageFeatureRequest
Assignee None
Priority Medium

md5: 51a30ea6603f4c1be8bc14581c1df11a

Issue Description:

It is currently not possible to add a setter to a computed property through an extension there that property also works properly outside the module (i.e. in other modules who import the extension).

CGRect for example has two read-only computed properties height and width.

Through an extension these properties can be shadowed by read-write computed properties like this:

extension CGRect {

    public var height: CGFloat {
        get { return size.height }
        mutating set { size.height = newValue }
    }

    public var width: CGFloat {
        get { return size.width }
        mutating set { size.width = newValue }
    }
}

and then be used like this:

var rect = CGRect()
rect.height = 1
rect.width = 2

var height = rect.height
var width = rect.width

It works fine in the same module as where the extension was defined.

It does not work however in other modules which import that extension. While the setters work fine, the getters will be considered "ambiguous" (between the original and the extension's implementations) and Swift provides no way to disambiguate this:

import ModuleProvidingTheExtension

var rect = CGRect()
rect.height = 1 // works
rect.width = 2 // works

var height = rect.height // Ambiguous use of 'height'
var width = rect.width // Ambiguous use of 'width'

There is no workaround for this problem.

Possible solutions:

  • Swift could provide a way to disambiguate the property access

    • at the call-site (would add weird syntax though)

    • at the import-site (e.g. import ModuleProvidingTheExtension.CGRect or ModuleProvidingTheExtension.CGRect.width - potentially very verbose)

    • by declaring that symbols in extensions always have precedence over symbols in the type being extended (won't work since CoreGraphic's CGRect.height/width is also added through extension)

    • by declaring symbol precedence depending on the order of module imports (potentially dangerous/unexpected?)

  • Swift could allow property getters to have a lower visibility than property setters which allowed for hiding the ambiguous getter (private get … in the extension)

  • Swift could allow adding a property setter through an extension without providing a getter

The last solution (providing a setter without getter) would easily fix this issue. It maintains source-compatibility and introduces no new syntax.

Example:

extension CGRect {

    public var height: CGFloat {
        mutating set { size.height = newValue }
    }

    public var width: CGFloat {
        mutating set { size.width = newValue }
    }
}

It adds a setter to the existing read-only properties.
Providing just a setter is only allowed if the property being affected is already defined somewhere - i.e. already has a getter.

This could be extended to allowing subclasses to override only the setter of a property without having to override the getter just to call super's implementation. Same for protocol conformances where the getter would already be covered by a default implementation.

--

I consider this to be more a bug than a feature request because overwriting the property in an extension leads to an unresolvable ambiguous access error in the getter only.

If necessary I'll re-post this on the Swift Evolution Mailing List.

@belkadan
Copy link
Contributor

Yes, this would need to go through the Swift Evolution Process.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature A feature request or implementation improvement
Projects
None yet
Development

No branches or pull requests

2 participants