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
Property behaviors prototype #1297
Conversation
@swift-ci Please test |
b38a54c
to
66f9ec2
Compare
@swift-ci Please test |
@@ -3626,7 +3647,7 @@ class AbstractStorageDecl : public ValueDecl { | |||
} | |||
}; | |||
void configureAddressorRecord(AddressorRecord *record, | |||
FuncDecl *addressor, FuncDecl *mutableAddressor); | |||
FuncDecl *addressor, FuncDecl *mutableAddressor); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pointless edit here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixing an 80-column violation.
@jckarter This looks awesome. I just have a few nitpicks that you're free to ignore. |
66f9ec2
to
9c37211
Compare
@swift-ci Please test |
9da36f8
to
d54abd1
Compare
@swift-ci Please test |
Parse 'var [behavior] x: T', and when we see it, try to instantiate the property's implementation in terms of the given behavior. To start out, behaviors are modeled as protocols. If the protocol follows this pattern: ``` protocol behavior { associatedtype Value } extension behavior { var value: Value { ... } } ``` then the property is instantiated by forming a conformance to `behavior` where `Self` is bound to the enclosing type and `Value` is bound to the property's declared type, and invoking the accessors of the `value` implementation: ``` struct Foo { var [behavior] foo: Int } /* behaves like */ extension Foo: private behavior { @implements(behavior.Value) private typealias `[behavior].Value` = Int var foo: Int { get { return value } set { value = newValue } } } ``` If the protocol requires a `storage` member, and provides an `initStorage` method to provide an initial value to the storage: ``` protocol storageBehavior { associatedtype Value var storage: Something<Value> { ... } } extension storageBehavior { var value: Value { ... } static func initStorage() -> Something<Value> { ... } } ``` then a stored property of the appropriate type is instantiated to witness the requirement, using `initStorage` to initialize: ``` struct Foo { var [storageBehavior] foo: Int } /* behaves like */ extension Foo: private storageBehavior { @implements(storageBehavior.Value) private typealias `[storageBehavior].Value` = Int @implements(storageBehavior.storage) private var `[storageBehavior].storage`: Something<Int> = initStorage() var foo: Int { get { return value } set { value = newValue } } } ``` In either case, the `value` and `storage` properties should support any combination of get-only/settable and mutating/nonmutating modifiers. The instantiated property follows the settability and mutating-ness of the `value` implementation. The protocol can also impose requirements on the `Self` and `Value` types. Bells and whistles such as initializer expressions, accessors, out-of-line initialization, etc. are not implemented. Additionally, behaviors that instantiate storage are currently only supported on instance properties. This also hasn't been tested past sema yet; SIL and IRGen will likely expose additional issues.
Fix some interface type/context type confusion in the AST synthesis from the previous patch, add a unique private mangling for behavior protocol conformances, and set up SILGen to emit the conformances when property declarations with behaviors are visited. Disable synthesis of the struct memberwise initializer if any instance properties use behaviors; codegen will need to be redesigned here.
We have enough implementation to do "delayed" now.
d54abd1
to
0e14108
Compare
@swift-ci Please test |
…rement. Would be nice to have `guard` in C++...
Since the feature is incomplete and yet to be accepted or implemented as proposed, hide it behind an -enable-experimental-property-behaviors frontend flag.
0e14108
to
79fbbaf
Compare
@swift-ci Please test |
I've merged this into master, hidden behind a frontend flag, |
Parse 'var [behavior] x: T', and when we see it, try to instantiate the property's
implementation in terms of the given behavior. To start out, behaviors are modeled
as protocols. If the protocol follows this pattern:
then the property is instantiated by forming a conformance to
behavior
whereSelf
is bound to the enclosing type andValue
is bound to the property'sdeclared type, and invoking the accessors of the
value
implementation:If the protocol requires a
storage
member, and provides aninitStorage
methodto provide an initial value to the storage:
then a stored property of the appropriate type is instantiated to witness the
requirement, using
initStorage
to initialize:In either case, the
value
andstorage
properties should support any combinationof get-only/settable and mutating/nonmutating modifiers. The instantiated property
follows the settability and mutating-ness of the
value
implementation. Theprotocol can also impose requirements on the
Self
andValue
types.Bells and whistles such as initializer expressions, accessors,
out-of-line initialization, etc. are not implemented. Additionally, behaviors
that instantiate storage are currently only supported on instance properties.
This also hasn't been tested past sema yet; SIL and IRGen will likely expose
additional issues.