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-10203] Subscripts setter on key-path calls getter of the destination property #52603

Open
DevAndArtist mannequin opened this issue Mar 27, 2019 · 5 comments
Open
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. key paths Feature: key paths (both native and Objective-C) standard library Area: Standard library umbrella swift 5.9 unexpected behavior Bug: Unexpected behavior or incorrect output

Comments

@DevAndArtist
Copy link
Mannequin

DevAndArtist mannequin commented Mar 27, 2019

Previous ID SR-10203
Radar rdar://problem/49345381
Original Reporter @DevAndArtist
Type Bug
Environment

Apple Swift version 5.0 (swiftlang-1001.0.69.5 clang-1001.0.46.3)
Target: x86_64-apple-darwin18.2.0

Additional Detail from JIRA
Votes 3
Component/s Compiler
Labels Bug
Assignee None
Priority Medium

md5: 13afefaa36d850c75676dbe3a222ba64

Issue Description:

This example unexpectedly crashes:

struct DelayedMutable<Value> {
  private var _value: Value? = nil

  var isInitialized: Bool {
    return _value != nil
  }

  var value: Value {
    get {
      guard let value = _value else {
        fatalError("property accessed before being initialized")
      }
      return value
    }
    set {
      _value = newValue
    }
  }

  /// "Reset" the delegate so it can be initialized again.
  mutating func reset() {
    _value = nil
  }
}

private var _value = DelayedMutable<Int>()

var value: Int {
  get { return _value[keyPath: \.value] }
  set { _value[keyPath: \.value] = newValue }
}

value = 42

Discussion on the forums: https://forums.swift.org/t/keypaths-subscript-setter-accesses-the-properties-getter/22212

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

Running into this bug as well.

@daniel-hall
Copy link

Same, this bug is unfortunately preventing me from implementing a useful API that uses key paths. Would love to see a fix for it!

@AnthonyLatsis AnthonyLatsis added standard library Area: Standard library umbrella key paths Feature: key paths (both native and Objective-C) crash Bug: A crash, i.e., an abnormal termination of software unexpected behavior Bug: Unexpected behavior or incorrect output SILGen Area → compiler: The SIL generation stage swift 5.9 and removed standard library Area: Standard library umbrella crash Bug: A crash, i.e., an abnormal termination of software labels Apr 8, 2023
@AnthonyLatsis
Copy link
Collaborator

A slightly simpler example:

struct Foo {
  private var isInitialized: Bool = false

  var value: Int {
    get {
      guard isInitialized else {
        fatalError("property accessed before being initialized")
      }
      return 1
    }
    set {}
  }
}

do {
  var x = Foo()
  x[keyPath: \.value] = 0
}

@AnthonyLatsis AnthonyLatsis added standard library Area: Standard library umbrella and removed SILGen Area → compiler: The SIL generation stage labels Apr 8, 2023
@gabriellanata
Copy link

gabriellanata commented Sep 14, 2023

This issue still happens and is also affecting an API that we were trying to build. Specifically, the getter runs an expensive operation to get the value so we want to avoid doing that unnecessarily.

struct Foo {
  var value: Int {
    get { fatalError("Should not call get") }
    set {}
  }
}

var foo = Foo()
foo[keyPath: \.value] = 0

Confusingly, this is exactly how SwiftUI environment works too. It uses key paths to set the value. I wonder if they're doing something different behind the scenes or are also having this issue as a small performance hit

@AnthonyLatsis AnthonyLatsis removed the compiler The Swift compiler in itself label Sep 14, 2023
@johannesd
Copy link

Having the same problem!

@gabriellanata SwiftUI probably does not run into this problem because environment variables always have a value (the default value, if it has not been overwritten). So, they don't have to use fatalError in the getter.

nikitabobko added a commit to nikitabobko/AeroSpace that referenced this issue Dec 26, 2023
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. key paths Feature: key paths (both native and Objective-C) standard library Area: Standard library umbrella swift 5.9 unexpected behavior Bug: Unexpected behavior or incorrect output
Projects
None yet
Development

No branches or pull requests

5 participants