Commit Graph

689 Commits

Author SHA1 Message Date
Slava Pestov
454281b226 AST: Split off StorageImplInfo from AbstractStorageDecl::AccessorRecord
We want to compute the former independently of the latter.
It's only 16 bits so storing it inside the Decl is fine;
it also allows us to eliminate the 'compact' representation
where an AbstractStorageDecl without an accessor record is
assumed to be stored.
2019-07-22 20:19:09 -04:00
Slava Pestov
a532a325e1 AST: Move a few methods from VarDecl down to ParamDecl 2019-07-22 20:19:09 -04:00
Slava Pestov
4fa48473bc Sema: Stop finalizing struct and enum members
Since getStoredProperties() is a request that lowers lazy properties
and property wrappers to their underlying storage, and SIL can validate
stored property and enum element types, there's no longer any need for
Sema to explicitly finalize members of structs and enums. SILGen can
trigger any necessary type checkin work just by lowering a struct or
enum type.

Now the only remaining reason we need finalizeDecl() is adding implicit
methods to classes, and synthesizing accessors for storage in classes
and protocols.
2019-07-17 18:07:03 -04:00
Slava Pestov
d0240cc22d Sema: Simplify finalizeType() by using getStoredProperties()
Continue gutting finalizeType() by using our new request to
synthesize the backing storage for lazy properties and
property wrappers.
2019-07-16 16:38:39 -04:00
Slava Pestov
b0e18e81ac Sema: Simplify synthesizeWitnessAccessorsForStorage() 2019-07-16 16:38:38 -04:00
Slava Pestov
8b287f20fa Sema: Refactor maybeAddAccessorsToStorage()
The idea here is to split up the logic into three parts:

- computation of the final ImplInfo for lazy, property wrappers
  and @NSManaged

- deciding if we should add accessors or not

- actually adding the accessors
2019-07-16 14:24:35 -04:00
Doug Gregor
690409d04f Merge pull request #26105 from DougGregor/more-lazy-body-synthesis
More lazy body synthesis
2019-07-12 10:07:54 -07:00
Doug Gregor
8117849d46 [AST] Make function body synthesizers less stateful.
Instead of requiring that function body synthesizers will always call
setBody(), which is annoyingly stateful, have function body synthesizers
always return the synthesized brace statement along with a bit that
indicates whether the body was already type-checked. This takes us a
step closer to centralizing the mutation of the body of a function.
2019-07-11 21:31:21 -07:00
Slava Pestov
ecc9e32f13 Sema: Remove validateAbstractStorageDecl()
Validating a variable or subscript no longer forces accessor synthesis.
2019-07-11 20:55:42 -04:00
Slava Pestov
15a831614e Sema: Remove finalizeAbstractStorageDecl()
Also since we're lazier about validating accessors now, relax some
checks in the ASTVerifier so that it can tolerate implicit accessors
without interface types. All other declarations must still have
interface types in verifyChecked().

ASTVerifier: Tolerate implicit accessors without interface types
2019-07-11 20:55:42 -04:00
Doug Gregor
ee52e7317c [SE-0258] Don't ask for the nominal type decl of an unresolved property wrapper
Generic type aliases break this query; don't use it.
Fixes rdar://problem/51989272
2019-07-09 16:36:19 -07:00
Doug Gregor
a66a5ff0a4 [SE-0258] Properly contextualize closures in property wrapper initialization.
Fixes SR-11061 / rdar://problem/52593304 / rdar://problem/52220881.
2019-07-08 16:39:49 -07:00
Doug Gregor
bc2e605b31 [Property wrappers] Improve enclosing-self subscript handling.
Extend handling of enclosing-self subscripts by differentiating
between the original wrapped property (which now goes through
`subscript(_enclosingInstance:wrapped:storage:)`) and the projected
property (which goes through
`subscript(_enclosingInstance:projected:storage:)`). The new middle
argument provides a key path to the property that was accessed,
allowing one to distinguish the property being updated.
2019-06-29 23:22:01 -07:00
Doug Gregor
8c54db727b [Property wrappers] Prototype support for enclosing self-based access
Allow property wrapper types to support a second access pattern for
instance properties of classes. When supported, the property wrapper's
static subscript(_enclosingInstance:storage:) is provided with the
enclosing "self" and a reference-writable key path referring to the
backing storage property.

Implements rdar://problem/52222560.
2019-06-29 00:08:49 -07:00
Doug Gregor
ef17b38106 [SE-0258] Trigger synthesis of _foo/$foo from name lookup.
Fix a bug with cross-file uses of the synthesized _foo/$foo for
properties with attached wrappers by implicitly triggering the
appropriate synthesis during name lookup.

Fixes rdar://problem/51725203.
2019-06-27 00:08:31 -07:00
Doug Gregor
db5440bdef [SE-0258] Rename wrapperValue to projectedValue. 2019-06-26 07:39:01 -07:00
Doug Gregor
7bb01c743b [SE-0258] Promote projection variables ($foo) to the original property access
When the outermost property wrapper associated with a property has a
`wrapperValue`, create the projection property (with the `$` prefix)
at the same access level as the original property. This puts the
wrapped-value interface and the projection interface at the same level.

The newly-introduced @_projectionValueProperty attribute is implicitly
created to establish the link between the original property and the
projection value within module interfaces, where both properties will
be explicitly written out.
2019-06-26 07:39:01 -07:00
Doug Gregor
446d0b3953 [SE-0258] Rename backing storage property to _foo.
In anticipation of upcoming changes to the property wrapper proposal,
rename the backing storage for a wrapped property to "foo", unconditionally.
2019-06-26 07:39:01 -07:00
Doug Gregor
22e40fedf5 [SE-0258] Enable default argument for wrapped property going through init().
My recent refactoring of default arguments for the memberwise initializer
accidentally dropped support for getting a default argument when the
attached property wrapper has an init(). Reinstate that support,
fixing rdar://problem/52116923.
2019-06-25 10:03:15 -07:00
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