When the property delegate type overrides the delegate value by providing
a delegateValue property, name the backing storage $$foo and make it private.
When a custom attribute is given a direct initializer, save and re-use
the initializer context we create so that it can be associated with the
enclosing pattern binding. Fixes assertions involving explicit closures
in 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: { ... }))
```
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.
A property with an attached delegate can be initialized in one of two ways:
* By directly specifying initialization arguments on the attribute,
e.g., "@SomeDelegate(x: 17, y: 42) var a".
* By initializing the original property itself, which goes through the
delegate type's init(initialValue:) initializer, e.g.,
"@Lazy var x = 17".
Implement support for both forms of initialization, including type
inference and checking for inconsistencies (e.g., if the annotation on
the property type doesn't match what the delegate type would
provide).
A custom attribute can be resolved to a property delegate type. Allow
this for property declarations (only), and diagnose the various places
where properties cannot have property delegates.
The main fixes here are:
- we weren't looking through open-existentials in the l-value
- we weren't handling mutating gets correctly unless CSApply wrapped
the base in an InOutExpr, which seems to be multifile-sensitive
- we were missing diagnostics in some cases involving subscripts
A better fix would be to re-introduce LValueAccessKind, but I wanted
a workable short-term fix that I could try to get into 5.1.
Fixes rdar://49482742, which is specific to the lazy-getter problem.
The diagnostics for `variable_never_mutated` always suggests
changing `var` to `let`, which is misleading in case of
for-each loops where explicitly immutable context applies.
This patch adds some variety to the message to make it appropriate.
Resolves: SR-9732
Parsed declarations would create an untyped 'self' parameter;
synthesized, imported and deserialized declarations would get a
typed one.
In reality the type, if any, depends completely on the properties
of the function in question, so we can just lazily create the
'self' parameter when needed.
If the function already has a type, we give it a type right there;
otherwise, we check if a 'self' was already created when we
compute a function's type and set the type of 'self' then.
...and collapse StaticVar/ClassVar and StaticLet/ClassLet into
StaticProperty/ClassProperty.
"var" and "let" aren't great nouns to use in diagnostics to begin with,
especially alongside semantic terms like "instance method". Focus on
the type vs. non-type aspect instead with "property", which better
matches how people talk about member vars (and lets) anyway.
As part of this, lift the now-unnecessary restriction against
combining a non-mutable addressor with a setter. I've also
tweaked some of the diagnostics.
This is in preparation for generalized accessors.
Separate out the semantic state for the ‘dynamic’ check (from the
presence of the attribute), and move all of the computation of the
‘dynamic’ bit into the request-evaluator.
In the process, this fixes a bug where implicitly-synthesized initializers
in subclasses of imported classes would not be implicitly made ‘final’.
The storage kind has been replaced with three separate "impl kinds",
one for each of the basic access kinds (read, write, and read/write).
This makes it far easier to mix-and-match implementations of different
accessors, as well as subtleties like implementing both a setter
and an independent read/write operation.
AccessStrategy has become a bit more explicit about how exactly the
access should be implemented. For example, the accessor-based kinds
now carry the exact accessor intended to be used. Also, I've shifted
responsibilities slightly between AccessStrategy and AccessSemantics
so that AccessSemantics::Ordinary can be used except in the sorts of
semantic-bypasses that accessor synthesis wants. This requires
knowing the correct DC of the access when computing the access strategy;
the upshot is that SILGenFunction now needs a DC.
Accessor synthesis has been reworked so that only the declarations are
built immediately; body synthesis can be safely delayed out of the main
decl-checking path. This caused a large number of ramifications,
especially for lazy properties, and greatly inflated the size of this
patch. That is... really regrettable. The impetus for changing this
was necessity: I needed to rework accessor synthesis to end its reliance
on distinctions like Stored vs. StoredWithTrivialAccessors, and those
fixes were exposing serious re-entrancy problems, and fixing that... well.
Breaking the fixes apart at this point would be a serious endeavor.
With batch mode, other files may have forced lazy properties to get finalized before the implicit constructor is formed. Avoid the order dependency by making the behavior stable regardless of the type-checking phase of lazy declarations. Fixes rdar://problem/40903186.
By formalizing ReferenceOwnership as a diagnostic argument kind, we get
less boilerplate, better type safety, better output consistency, and
last but not least: future proofing.
We can use the existing logic for checking recursion in
declaration validation. This eliminates some bogus
diagnostics and allows some weird logic to be removed
from typo correction.
This fixes two easy cases where we would go exponential in type
checking tuple literals.
Instead of generating a conversion to a single type variable (which
results in one large constraint system), we generate a conversion ot
the same type that appears in the initializer expression (which for
tuples is a tuple type, which naturally splits the constraint system).
I experimented with trying to generalize this further, but ran into
problems getting it working, so for now this will have to do.
Fixes rdar://problem/20233198.
When performing a binding/assignment to a weak or unowned variable/property from an initialiser call, emit a warning that the instance will be immediately deallocated.