Commit Graph

620 Commits

Author SHA1 Message Date
Doug Gregor
7d0357c7b5 [Property wrappers] Validate wrappedValue before using it.
Fixes SR-10984.
2019-06-24 23:42:23 -07:00
Doug Gregor
592887cb53 [Type checker] Fix multi-file crasher for property wrapper backing storage.
Fixes rdar://problem/51810057
2019-06-24 22:35:51 -07:00
Slava Pestov
02bad9a479 Sema: Clean up lazy properties and related code 2019-06-19 22:12:55 -04:00
Slava Pestov
1e1e812768 Sema: Use a request to create lazy property backing storage 2019-06-19 22:12:55 -04:00
Slava Pestov
7913d30236 Sema: Use a request to compute FuncDecl::getSelfAccessKind() 2019-06-19 14:38:43 -04:00
Slava Pestov
a1b8913edf Sema: Synthesize accessors for computed local and global properties
If a stored property has a didSet/willSet, we currently synthesize
the getter and the setter inside the parser.  I want to get rid of
the parser's code path for doing that and consolidate all accessor
synthesis here in Sema.

Note that the parser did not synthesize a modify. This is now more
explicit in the code.

Also, we have to relax an assertion since addMemberToContextIfNeeded()
now gets called on declarations in local contexts.
2019-06-18 18:35:03 -04:00
Doug Gregor
1160017e9b [SE-0258] Escalate access of wrapperValue-produced $x to internal. 2019-06-14 11:49:18 -07:00
Doug Gregor
d35e1eaf72 [SE-0258] Support initial values & explicit initialization arguments.
Allow both explicit initialization and initial values to work together, e.g.,

```
@Clamping(min: 0, max: 255) var red: Int = 127
```

gets initialized as

```
Clamping(initialValue: 127, min: 0, max: 255)
```
2019-06-14 01:10:53 -07:00
Doug Gregor
18768ecd59 Merge pull request #25449 from DougGregor/property-wrapper-composition
[SE-0258] Implement basic support for property wrapper composition.
2019-06-13 20:28:30 -07:00
Doug Gregor
82ed5e9a02 [SE-0258] Implement basic support for property wrapper composition.
When multiple property wrapper attributes are provided on a declaration,
compose them outside-in to form a composite property wrapper type. For
example,

  @A @B @C var foo = 17

will produce

  var $foo = A(initialValue: B(initialValue: C(initialValue: 17)))

and foo's getter/setter will access "foo.value.value.value".
2019-06-13 18:26:29 -07:00
Slava Pestov
95c221a118 Sema: Replace makeFinal() calls in favor of smarter IsFinalRequest 2019-06-13 01:03:33 -07:00
Slava Pestov
4a8e3fcc91 AST: Add VarDecl::isLazyStorageProperty() and set it 2019-06-13 00:39:53 -07:00
Slava Pestov
ae4de47f83 Sema: Correctly mark backing storage for lazy properties and property wrappers as 'final'
By calling isFinal() first in makeFinal(), we were triggering
computation of IsFinalRequest and caching a value of 'false'.

With lazy properties, we did direct storage access, and no
accessors were synthesized anyway, but add a test for that.

With property wrappers this now means the backing storage
property is final, as intended (?).
2019-06-13 00:39:53 -07:00
Doug Gregor
5244805b17 [SE-0258] Clean up memberwise initializer / default-initialization interaction
When the backing storage of a wrapped property is default-initialized via the
property wrapper type's init(), don't count that as a direct initialization
of the backing storage for the purposes of constructing the memberwise
initializer. Instead, treat this case the same as if there were no initializer,
keying the form of the memberwise initializer off the presence of
init(initialValue:).
2019-06-12 10:29:54 -07:00
Doug Gregor
5e00f01ce4 [SE-0258] Ensure that we fully check the property type vs. wrapper's value type
Various optimizations / shortcuts in type checking property wrappers meant
that we weren't consistently verifying that a wrapped property type is
identical to the type of the 'value' property of the wrapper. Do so.

Fixes SR-10899 / rdar://problem/51588022.
2019-06-11 10:06:31 -07:00
Harlan Haskins
126df464ee [CodeSynthesis] Reset TypeLoc when synthesizing overridden designated inits (#25182)
Previously, we'd clone the superclass's initializer and update its
interface type, but we didn't reset the TypeLoc. This meant the
synthesized overridden initializer's parameter typeLocs would still be in
the parent decl context, which caused the ASTPrinter to print the
unsubstituted type.

rdar://50914733
2019-06-01 08:25:55 -07:00
Doug Gregor
be2867fb84 [SE-0258] Fix crash-on-invalid involving some wrappers with wrapperValue
Fixes rdar://problem/51193573.
2019-05-31 21:50:21 -07:00
Doug Gregor
59180db1f3 [SE-0258] Reduce access of backing storage variable to 'private'. 2019-05-30 10:37:34 -07:00
Doug Gregor
c02ecf9859 [SE-0258] Rename to Property Wrappers 2019-05-29 22:17:50 -07:00
swift-ci
265fa8bdda Merge pull request #25120 from DougGregor/property-wrappers-in-class-crash 2019-05-29 14:21:19 -07:00
Doug Gregor
9468eddc52 [SE-0258] Make sure we add accessors to backing storage in classes.
Thanks to Avi on the Swift Forums for pointing this out!
2019-05-29 13:17:20 -07:00
Slava Pestov
ec1b1a390a AST: Remove ASTContext::ExternalDefinitions
Anything added here has a type checked body now, so it no longer
serves any purpose.
2019-05-28 22:08:30 -04:00
Slava Pestov
96749a2702 Sema: Mark synthesized accessors as transparent earlier 2019-05-28 22:08:30 -04:00
Slava Pestov
4b1fb5785a Sema: Remove a few calls to addSynthesizedDecl() 2019-05-28 22:08:30 -04:00
Slava Pestov
140a5b0018 Sema: Build fully type-checked AST for stub initializers 2019-05-23 10:40:34 -04:00
Doug Gregor
d86907e095 [Property delegates] Fix crash involving generic uses of delegateValue.
Fixes rdar://problem/50873275.
2019-05-20 10:15:12 -07:00
Slava Pestov
d93695f999 Sema: Remove support code for building non-type checked accessors 2019-05-14 19:19:24 -04:00
Slava Pestov
e65161ea2e Sema: Build type checked bodies for lazy getters 2019-05-14 19:18:58 -04:00
Slava Pestov
7e15c21dac Sema: Use an 'if let' instead of a hasValue/! in lazy property getter
We used to generate this:

  let tmp1 = storage
  if tmp1.hasValue {
    return tmp1!
  }

Instead we now generate this:

  if let tmp1 = storage {
    return tmp1
  }
2019-05-14 19:18:57 -04:00
Slava Pestov
d29d017fce Sema: Build type checked bodies for observer setters 2019-05-14 19:18:57 -04:00
Slava Pestov
a18c32ae06 Sema: Build type checked bodies for designated init overrides
Similarly to trivial accessors, the body of a synthesized
designated initializer override is simple enough that we can
build it directly without involving the constraint solver.
2019-05-13 17:25:49 -04:00
Slava Pestov
0bab515f66 Sema: Build type checked bodies for trivial accessors
This includes all synthesized accessors except for lazy getters
and observer setters.

Building checked AST has certain advantages:

- It is faster, avoiding the need to create and solve ConstraintSystems
  or performing various diagnostic and semantic walks over the AST.

- It allows us to postpone delayed body synthesis until needed in SILGen,
  instead of having to walk a list of "external declarations" in Sema.

It also unblocks lazier conformance checking. Now that SILGen can
trigger conformance checking on its own, we need to be able to
synthesize bodies of accessors that witness protocol requirements.
This will allow us to eventually remove Sema's "used conformances"
list.

Note that for now, various utility functions in CodeSynthesis.cpp are
used for both checked and unchecked function bodies, so they take a
'typeChecked' boolean parameter that complicates some logic more than
necessary. Once the remaining body synthesizers are refactored to
build type-checked AST, the 'typeChecked' flag will go away.
2019-05-13 17:25:49 -04:00
Doug Gregor
eb3f28825c [Property delegates] Fix textual interfaces for properties with delegates
Don’t synthesize a missing setter for a property that has an attached
delegate and is in a .swiftinterface file.
2019-05-05 22:12:00 -07:00
Doug Gregor
f34aa79df1 [Property delegates] Implicit initialization for properties with delegates.
When a property delegate type has a default initializer, use that to
implicitly initialize properties that use that delegate and do not have
their own initializers. For example, this would allow (e.g.), delegate
types like the DelayedImmutable and DelayedMutable examples to drop
the explicit initialization, e.g.,

```
  @DelayedMutable var foo: Int
```

would be implicitly initialized via

```
  $foo = DelayedMutable()
```

This is a simplistic implementation that does not yet propertly handle
definite initialization.

Fixes rdar://problem/50266039.
2019-05-01 23:17:16 -07:00
Doug Gregor
bf2c4d951b Prevent less-visible properties with delegates from affecting memberwise initializer
When a property with an attached delegate has less-than-internal visibility
and is initialized, don’t put it into the memberwise initializer because
doing so lowers the access level of the memberwise initializer, making it
fairly useless.

Longer term, it probably makes sense to have several memberwise initializers
at different access levels, so adding an initialized `private var` make
the memberwise initializer useless throughout the rest of the module.

Addresses rdar://problem/50266245.
2019-05-01 14:10:56 -07:00
swift-ci
ff208b677f Merge pull request #24363 from DougGregor/is-memberwise-initialized 2019-04-30 11:29:27 -07:00
Doug Gregor
96952ea9a2 [AST] Distinguish memberwise-initialized properties for storage vs. declared
The determination of whether a property is memberwise-initialized is
somewhat confused for properties that have synthesized backing properties.
Some clients (Sema/Index) want to see the declared properties, while others
(SILGen) want to see the backing stored properties. Add a flag to
`VarDecl::isMemberwiseInitialized()` to capture this variation.
2019-04-30 10:12:43 -07:00
Doug Gregor
1a169b91bd Centralize the definition of isMemberwiseInitialized()
This utility was defined in Sema, used in Sema and Index, declared in
two headers, and semi- copy-pasted into SILGen. Pull it into
VarDecl::isMemberwiseInitialized() and use it consistently.
2019-04-29 10:30:38 -07:00
Doug Gregor
e7ef638285 [Property delegates] Sure synthesized PatternBindingDecl static when needed
Fixes rdar://problem/50201019.
2019-04-27 09:38:34 -07:00
Doug Gregor
6218673ead [Property delegates] Use $$foo for the backing storage and make it private.
When the property delegate type overrides the delegate value by providing
a delegateValue property, name the backing storage $$foo and make it private.
2019-04-23 21:56:03 -07:00
Doug Gregor
fcd2fd97e8 [Property delegates] Don't create backing var for ill-formed delegate type.
Fixes the crash-on-invalid in rdar://problem/49982937.
2019-04-23 11:32:29 -07:00
Doug Gregor
7df695536e [Property delegates] Fix printing of memberwise initializer default arguments 2019-04-23 11:32:28 -07:00
Doug Gregor
261b879b54 [Property delegates] Rename storageValue to delegateValue 2019-04-23 11:32:28 -07:00
Doug Gregor
2e9f8cf981 Capture a placeholder opaque value expression when needed. 2019-04-23 11:32:28 -07:00
Doug Gregor
4f56db2653 [Property delegates] Implement support for storageValue 2019-04-23 11:32:28 -07:00
Doug Gregor
cc68b12d1a [SILGen] Initialization of instance properties with property delegates
The initialization of an instance property that has an attached
property delegate involves the initial value written on the property
declaration, the implicit memberwise initializer, and the default
arguments to the implicit memberwise initializer. Implement SILGen
support for each of these cases.

There is a small semantic change to the creation of the implicit
memberwise initializer due to SE-0242 (default arguments for the
memberwise initializer). Specifically, the memberwise initializer will
use the original property type for the parameter to memberwise
initializer when either of the following is true:

  - The corresponding property has an initial value specified with the
    `=` syntax, e.g., `@Lazy var i = 17`, or
  - The corresponding property has no initial value, but the property
    delegate type has an `init(initialValue:)`.

The specific case that changed is when a property has an initial value
specified as a direct initialization of the delegate *and* the
property delegate type has an `init(initialValue:)`, e.g.,

```swift
struct X {
  @Lazy(closure: { ... })
  var i: Int
}
```

Previously, this would have synthesized an initializer:

```swift
init(i: Int = ???) { ... }
```

However, there is no way for the initialization specified within the
declaration of i to be expressed via the default argument. Now, it
synthesizes an initializer:

```swift
init(i: Lazy<Int> = Lazy(closure: { ... }))
```
2019-04-23 11:31:59 -07:00
Doug Gregor
6526cfa8d4 Memberwise initializer synthesis for properties with attached delegates. 2019-04-23 11:31:58 -07:00
Doug Gregor
b18a2902e5 Implement access control for property delegates 2019-04-23 11:31:58 -07:00
Doug Gregor
b8061eab34 Synthesize backing storage property for properties with attached delegates.
When a property has an attached property delegate, a backing storage
property of the corresponding delegate type will be
synthesized. Perform this synthesis, and also synthesize the
getter/setter for the original property to reference the backing
storage property.
2019-04-23 11:31:58 -07:00
Alexis Laferrière
007fbb6ebd Merge pull request #23932 from xymus/IsFinalRequest
Sema: implement `isFinal` using a request evaluator
2019-04-19 13:02:07 -07:00