Introduce some metaprogramming of accessors and generally prepare
for storing less-structured accessor lists.
NFC except for a change to the serialization format.
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.
Inherited designated initializers got the same availability
as the corresponding initialier in the superclass.
However if the superclass was more available than the subclass,
we would generate a diagnostic that a member cannot be more
available than its containing type.
This diagnostic had an unknown source location, since the
location was for a synthesized declaration, causing confusion.
Fixes <https://bugs.swift.org/browse/SR-7881> aka
<rdar://problem/40853731>.
Rather than ASTContext-allocating ConcreteDeclRef’s storage when there is a
non-empty substitution map, put the SubstitutionMap directly in the
ConcreteDeclRef. Simplify the various interfaces along the way.
Replace two prominent uses of SubstitutionList, in ConcreteDeclRef and
Witness, with SubstitutionMap. Deal with the myriad places where we
now have substitution maps and need substitution lists (or vice versa)
caused by this change.
Overall, removes ~50 explicit uses of SubstitutionList (of ~400).
If the base class initializer was '@inlinable public' and the
derived class was '@usableFromInline internal', the synthesized
initializer was '@inlinable internal', which was an error.
The DeclChecker had three possible states:
- IsFirstPass true, IsSecondPass false. This is the 'first pass' for
declarations that appear at the top-level, or are nested inside
top-level types.
- IsFirstPass false, IsSecondPass true. This is the 'second pass' for
declarations that appear at the top-level, or are nested inside
top-level types.
- IsFirstPass false, IsSecondPass false. This was used for (some)
local declarations.
This is unnecessarily confusing. We can eliminate the third state
by calling typeCheckDecl() twice in a few places. This allows
IsSecondPass to be removed entirely since it's now always equal to
!IsFirstPass.
The importer would only synthesize its own memberwise init if the
declaration had a zero initializer, which supresses Sema's automatic
synthesis. Trouble is we cannot rely on Sema synthesizing the
memberwise init in case we deserialize declarations after type
checking.
Some other changes caught this with an assert, so fix the importer
to do the right thing here.
We don't want @_fixed_layout to apply to static properties, or you
get fun consequences like not being able to change static stored
properties defined in extensions of imported types to computed.
This has three principal advantages:
- It gives some additional type-safety when working
with known accessors.
- It makes it significantly easier to test whether a declaration
is an accessor and encourages the use of a common idiom.
- It saves a small amount of memory in both FuncDecl and its
serialized form.
Follow-up for 7c707ce97c. Without this, the declaration would be
accepted, but any uses of the overridden property would be treated as
ambiguous because the property wouldn't really be marked as an
override.
rdar://problem/35900345
Rather than storing contextual types in the type witnesses and associated
conformances of NormalProtocolConformance, store only interface types.
@huonw did most of the work here, and @DougGregor patched things up to
complete the change.
When overriding storage with a forced static dispatch materializeForSet,
the override's materializeForSet should not override the base
materializeForSet.
This is the case where a dynamic property witnesses a protocol
requirement, and Sema synthesizes a materializeForSet for it.
In this case, the synthesized materializeForSet dynamically dispatches
to the dynamic property's getter and setter, and the protocol witness
thunk directly calls the synthesized materializeForSet.
The subclass only needs to override the getter and setter in this case,
since the base class's materializeForSet will already do the right
thing.
In fact, marking it as an override exposes a problem where we cannot
serialize an xref to an imported property's materializeForSet, since
it was not created by the importer.
Follow-up to my earlier changes to drop 'inout' types when cloning parameter
lists, we also need to deal with substitutions into those parameter types.
This is an artifact of us having mostly---but not entirely---removed
InOutType from the AST. Fixes rdar://problem/34818336.
When type-checking a function or subscript that itself does not have generic
parameters (but is within a generic context), we were creating a generic
signature builder which will always produce the same generic signature as
the enclosing context. Stop creating that generic signature builder.
Instead, teach the CompleteGenericTypeResolver to use the generic signature
+ the canonical generic signature builder for that signature to resolve
types, which also eliminates some extraneous re-type-checking.
Improves type-checking performance of the standard library by 36%.
When type-checking a function or subscript that itself does not have generic
parameters (but is within a generic context), we were creating a generic
signature builder which will always produce the same generic signature as
the enclosing context. Stop creating that generic signature builder.
Instead, teach the CompleteGenericTypeResolver to use the generic signature
+ the canonical generic signature builder for that signature to resolve
types, which also eliminates some extraneous re-type-checking.
Improves type-checking performance of the standard library by 36%.
The base mutability of storage is part of the signature, so be sure
to compute that during validation. Also, serialize it as part of
the storage declaration, and fix some places that synthesize
declarations to set it correctly.
A lazy property setter stores a value to the underlying storage
of the lazy property. The underlying storage is private, and it
is not proper for a public transparent function body to reference
a private member.
In practice, this only failed if the private member had a
non-constant offset, which only occurs with subclasses of @objc
classes, and resilient classes.
For @objc classes we already had a workaround where no accessors
for stored properties are ever transparent. I put this in to fix
this very issue with lazy properties, but now I realize it was
the wrong workaround, because we still had this problem with
resilient classes.
Note that I'm keeping the logic which made @objc accessors
non-transparent in place, because there's a good chance we will
decide that field offset globals should always be private.
Also, to make this issue reproducible in the test, I changed the
resilience execution tests to build the resilient library as a
dylib and link against that instead of just linking .o files
together. This is because .o files can see each other's internal
symbols, so I was not able to reproduce the original failure
this way. I went ahead and updated the other resilient tests to
do this as well. Also, each test now builds in WMO and non-WMO
mode, to exercise different SIL linking behavior. Again, the
WMO variant was needed to reproduce the issue fixed by this
commit, because without WMO we currently discard serialized SIL,
so no cross-module inlining of the lazy property setter was
taking place.
"Accessibility" has a different meaning for app developers, so we've
already deliberately excised it from our diagnostics in favor of terms
like "access control" and "access level". Do the same in the compiler
now that we aren't constantly pulling things into the release branch.
This commit changes the 'Accessibility' enum to be named 'AccessLevel'.
Pushes __consuming through the frontend and extends existing
attribute-based diagnsotics to cover it. Unlike `nonmutating`,
__consuming is allowed in class methods, though it makes little
sense to put it there.