Skip to content

[Property Wrappers] Don't allow wrappedValue and projectedValue to have dynamic Self type. #31344

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

Merged

Conversation

hborla
Copy link
Member

@hborla hborla commented Apr 27, 2020

Currently, when wrappedValue or projectedValue have dynamic Self type, the synthesized properties when using the wrapper will also get a dynamic Self type, but in a new context. This bug could manifest as really misleading diagnostics, or a crash. For now, we will disallow this, but we can re-visit implementing correct support for this in the future.

Resolves: rdar://problem/53258469

@hborla hborla requested a review from DougGregor April 27, 2020 19:51
@hborla
Copy link
Member Author

hborla commented Apr 27, 2020

@swift-ci please smoke test

@hborla
Copy link
Member Author

hborla commented Apr 27, 2020

@swift-ci please smoke test OS X platform

@theblixguy
Copy link
Collaborator

theblixguy commented Apr 29, 2020

Hmm, I suppose this is only problematic when working with classes? For example, currently this code works fine:

@propertyWrapper
struct Foo {
  let wrappedValue: String
  var projectedValue: Self { self }

  init(wrappedValue: String) {
    self.wrappedValue = wrappedValue
  }

  func bar() {}
}

struct UsesFoo {
  @Foo var property = "hello"

  func test() {
    $property.bar() // Ok
  }
}

although if you change Foo to be a class then I get value of type 'UsesFoo' has no member 'bar' which is wrong, so I am wondering whether we should only disallow it when the wrapper type is a class, although I understand simply banning it outright is a simpler rule.

@hborla
Copy link
Member Author

hborla commented Apr 29, 2020

@theblixguy you're right that Self is not problematic when the property wrapper is a struct, and this code still allows that to compile. Self in a struct is replaced with the type of that struct rather than a DynamicSelfType. So, this code does only disallow Self when the property wrapper is a class.

The followup errors when using the property wrapper are annoying, and they happen because the backing storage and projected value properties aren't synthesized when a property wrapper has an invalid PropertyWrapperTypeInfo. This can also happen if the property wrapper is missing a non-static wrappedValue property, for example. Synthesizing invalid properties in this case might be good for diagnostics...

@theblixguy
Copy link
Collaborator

theblixguy commented Apr 29, 2020

Ah, I didn't know that, I thought it'd still be DynamicSelfType. Thank you for the explanation! I think it might be worth adding a test case for the struct case (if there's isn't one) to make sure we don't regress.

(btw I think it should work for final class too as its equivalent to Self but it's not supported right now.).

@hborla hborla force-pushed the property-wrapper-invalid-dynamic-self branch from 46e02df to a8406a3 Compare April 29, 2020 16:03
@hborla
Copy link
Member Author

hborla commented Apr 29, 2020

@swift-ci please smoke test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants