For now, the accessors have been underscored as `_read` and `_modify`.
I'll prepare an evolution proposal for this feature which should allow
us to remove the underscores or, y'know, rename them to `purple` and
`lettuce`.
`_read` accessors do not make any effort yet to avoid copying the
value being yielded. I'll work on it in follow-up patches.
Opaque accesses to properties and subscripts defined with `_modify`
accessors will use an inefficient `materializeForSet` pattern that
materializes the value to a temporary instead of accessing it in-place.
That will be fixed by migrating to `modify` over `materializeForSet`,
which is next up after the `read` optimizations.
SIL ownership verification doesn't pass yet for the test cases here
because of a general fault in SILGen where borrows can outlive their
borrowed value due to being cleaned up on the general cleanup stack
when the borrowed value is cleaned up on the formal-access stack.
Michael, Andy, and I discussed various ways to fix this, but it seems
clear to me that it's not in any way specific to coroutine accesses.
rdar://35399664
There are two general constructor forms here:
- One took the number of parameter lists, to be filled in later.
Now, this takes a boolean indicating if there is an implicit
'self'.
- The other one took the actual parameter lists and filled them
in right away. This now takes a separate 'self' ParamDecl and
ParameterList.
Instead of storing the number of parameter lists, an
AbstractFunctionDecl now only needs to store if there is a 'self'
or not.
I've updated most places that construct AbstractFunctionDecls to
properly use these new forms. In the ClangImporter, there is
more code that remains to be untangled, so we continue to build
multiple ParameterLists and unpack them into a ParamDecl and
ParameterList at the last minute.
Introduce a new request kind to capture the computation of the set of
overridden declarations of a given declaration, eliminating the
stateful “setOverriddenDecls()” calls from the type checker.
The other side of #17404. Since we don't want to generate up front key path metadata for properties/subscripts with no withheld implementation details, the client should generate a key path component that can be used to represent a key path component based on its public interface.
This was originally added to support "derived" top-level declarations,
which in practice was just '==' implementations for enums. Now that
those are members, we don't have the notion of derived top-level
declarations anymore, and neither is there anything that would
normally be a cross-reference that we want to force to be serialized
directly.
No functionality change (because this was unused).
Several kinds of declarations can override other declarations, but the
computation and storage for these “overridden” declarations was scattered in
at least 3 different places, with different resolution paths. Pull them
all together into two bits of LazySemanticInfo in ValueDecl (“have we computed
overrides?” and “are there any overrides?”), with a side table for the
actual list of overrides.
One side effect here is that the AST can now represent multiple overridden
declarations, although only associated type declarations track this
information.
Start using LazyResolver::resolveOverriddenDecl() more consistently, unifying
it with the separate path we had for associated type overrides. All of this
is staging for a move to the request-evaluator for overridden declaration
computation.
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.
We sometimes serialized the “isObjC” state, and sometimes not. When we did serialize it,
we rarely used the bit for anything. Serialize it for all declarations where it makes
sense, and consistently call setIsObjC() with the deserialized value.
This is enough to let the test case in rdar://problem/40899824 pass,
and any callers of this function already need to be able to handle a
nullptr result. There's a lot more work to do in this area, but it's
nice to get the simple things working again.
Now that @inlinable is a supported feature, we need to handle cases
where a function is inlinable but it references some type that imports
differently in different Swift versions. To start, handle the case
where a SIL function's type is now invalid and therefore the entire
function can't be imported. This doesn't open up anything interesting
yet, but it's a start.
Part of rdar://problem/40899824
Signature optimization is slightly different to (most) other thunks, in that
it's taking an existing function and turning that into a thunk, rather than
creating a thunk that calls an existing function. These symbols can be public,
etc. and so need to be handled a bit different to other types of thunks.
If, for whatever reason, a type used in an extension's generic
requirements is missing, just drop the whole extension. This isn't
wonderful recovery, but in practice nothing should be able to use the
extension anyway, since the relevant type in question is missing.
...Okay, that's not quite true; there could, for example, be inlinable
code that references one of these methods. However, that (1) isn't
worse than the behavior for any other inlinable code (which doesn't
yet attempt to recover from missing declarations), and (2) is still a
strict improvement over the current situation, where we will eagerly
abort the compiler trying to load the extension in the first place.
rdar://problem/40956460