1) Make AnyFunctionType::getParams() inline friendly (it compiles down
to just a few instructions).
2) Byte align/size the embedded number of AnyFunctionType parameters.
This was set to 10 bits back when the inline bitfields were 32 bits
in size. Now with 64 bits to play with, we have room to spare.
Inline bitfields are a common design pattern in LLVM and derived
projects, but the associated boilerplate can be demotivating and
brittle. This new header makes it easier to define and use inline
bitfields in Swift.
This also reorders some fields for better code generation.
Both AnyFunctionType and SILFunctionType reserve 16 bits in the TypeBase
for their respective "ExtInfo" bits, but then these types use less than
half of the bits they reserve. This patch changes AnyFunctionType and
SILFunctionType to only reserve what they need and then verify at
construction time that ExtInfo bits are not being truncated.
This change is motivated by the need to have more TypeBase bits
available for other uses.
Finally, this change fixes a copy-and-paste error introduced when
AnyFunctionType and SILFunctionType stopped sharing the same ExtInfo
data structure.
Sometimes we end up mapping a conformance into and then out of a
particular context, which led to "stacked" specialized conformances
that were basically a no-op. Look through these to collapse them
eagerly.
Collapses 15786 conformances in the standard library.
Swift's ASTContext contained all of the logic to find the complete list
of properties for an Objective-C class, which is used by the Clang importer
to influence the mapping of Objective-C names into Swift. Swift's
ASTContext also included a *cache* for this information, indexed by
the Clang `ObjCInterfaceDecl *`. However, this cache was getting
populated/queried from the Clang importer's name importer, such that
the keys would be Clang declarations used to build modules and then
deallocated. If that memory eventually gets reused for a different
`ObjCInterfaceDecl *`, we would get incorrect/stale all-properties
information.
Almost Surely fixes rdar://problem/35347167, which is a
nondeterministic failure where UIView's `addGestureRecognizer(_:)` gets
occasionally imported as `add(_:)`.
BoundGenericType::Profile() is the only Profile method that calculates the
recursive type properties as a side effect. This change makes the method
like all of the others.
When a particular nominal type or extension thereof declares conformance
to a protocol, check whether that type or extension contains any members
that *nearly* match a defaulted requirement (i.e., a requirement that
is satisfied by something in a protocol extension), but didn’t match
for some reason and weren’t used to satisfy any other requirement of
that protocol. It’s intended to catch subtle mistakes where a default
gets picked instead of the intended member.
This is a generalization of the code we’ve had for @objc optional
requirements for a long time.
Fixes rdar://problem/24714887.
Now that the GenericSignatureBuilder is no longer sensitive to the input
module, stop uniquing the canonical GSBs based on that module. The main
win here is when deserializing a generic environment: we would end up
creating a canonical GSB in the module we deserialized and another
canonical GSB in the module in which it is used.
Implement a module-agnostic conformance lookup operation within the GSB
itself, so it does not need to be supplied by the code constructing the
generic signature builder. This makes the generic signature builder
(closer to) being module-agnostic.
When an associated type declaration “overrides” (restates) an associated
type from a protocol it inherits, note that it overrides that declaration.
SourceKit now reports overrides of associated types.
The number of generic signature builders “registered” indicates how many
times a generic signature builder (GSB) was moved in to become the canonical
GSB, rather than recreating the GSB. When a GSB is “already registered”, it
means that we’ve constructed a new GSB only to find that there already was
a canonical GSB for that particular generic signature. These latter cases
could potentially benefit from more caching.
Once we compute a generic signature from a generic signature builder,
all queries involving that generic signature will go through a separate
(canonicalized) builder, and the original builder can no longer be used.
The canonicalization process then creates a new, effectively identical
generic signature builder. How silly.
Once we’ve computed the signature of a generic signature builder, “register”
it with the ASTContext, allowing us to move the existing generic signature
builder into place as the canonical generic signature builder. The builder
requires minimal patching but is otherwise fully usable.
Thanks to Slava Pestov for the idea!
Funnel all places where we create a generic signature builder to compute
the generic signature through a single entry point in the GSB
(`computeGenericSignature()`), and make `finalize` and `getGenericSignature`
private so no new uses crop up.
Tighten up the signature of `computeGenericSignature()` so it only works on
GSB rvalues, and ensure that all clients consider the GSB dead after that
point by clearing out the internal representation of the GSB.
Funnel all places where we create a generic signature builder to compute
the generic signature through a single entry point in the GSB
(`computeGenericSignature()`), and make `finalize` and `getGenericSignature`
private so no new uses crop up.
Tighten up the signature of `computeGenericSignature()` so it only works on
GSB rvalues, and ensure that all clients consider the GSB dead after that
point by clearing out the internal representation of the GSB.
For enums, we now only call _mixInt on the computed hash value if
it has associated values; for enums without associated values, we
use the ordinal alone, as before.
The number of generic signature builders “registered” indicates how many
times a generic signature builder (GSB) was moved in to become the canonical
GSB, rather than recreating the GSB. When a GSB is “already registered”, it
means that we’ve constructed a new GSB only to find that there already was
a canonical GSB for that particular generic signature. These latter cases
could potentially benefit from more caching.
Once we compute a generic signature from a generic signature builder,
all queries involving that generic signature will go through a separate
(canonicalized) builder, and the original builder can no longer be used.
The canonicalization process then creates a new, effectively identical
generic signature builder. How silly.
Once we’ve computed the signature of a generic signature builder, “register”
it with the ASTContext, allowing us to move the existing generic signature
builder into place as the canonical generic signature builder. The builder
requires minimal patching but is otherwise fully usable.
Thanks to Slava Pestov for the idea!
Funnel all places where we create a generic signature builder to compute
the generic signature through a single entry point in the GSB
(`computeGenericSignature()`), and make `finalize` and `getGenericSignature`
private so no new uses crop up.
Tighten up the signature of `computeGenericSignature()` so it only works on
GSB rvalues, and ensure that all clients consider the GSB dead after that
point by clearing out the internal representation of the GSB.
Given an existential type E, this creates a new canonical
generic signature <T : E>.
If E is a protocol composition containing members of protocol,
class or AnyObject type, the resulting generic signature will
split up the T : E requirement into a canonical and minimal
set of conformance, superclass and layout requirements.
If/when we implement generalized existentials, existential
types will be defined in terms of an arbitrary set of
generic requirements applied to a single generic parameter;
at that point, this method will be replaced with a generic
signature stored inside the type itself.
For now, this will be used to simplify some logic in the
SILOptimizer.
This implementation required a compromise between parser
performance and AST structuring. On the one hand, Parse
must be fast in order to keep things in the IDE zippy, on
the other we must hit the disk to properly resolve 'canImport'
conditions and inject members of the active clause into the AST.
Additionally, a Parse-only pass may not provide platform-specific
information to the compiler invocation and so may mistakenly
activate or de-activate branches in the if-configuration decl.
The compromise is to perform condition evaluation only when
continuing on to semantic analysis. This keeps the parser quick
and avoids the unpacking that parse does for active conditions
while still retaining the ability to see through to an active
condition when we know we're moving on to semantic analysis anyways.
A protocol extension initializer creates a new instance of the
static type of Self at the call site.
However a convenience initializer in a class is expected to
initialize an instance of the dynamic type of the 'self' value,
because convenience initializers can be inherited by subclasses.
This means that when a convenience initializer delegates to a
protocol extension initializer, we have to substitute the
'Self' type in the protocol extension generic signature with
the DynamicSelfType, and not the static type.
Since the substitution is formed from the type of the 'self'
parameter in the class convenience initializer, the solution is
to change the type of 'self' in a class convenience initializer
to DynamicSelfType, just like we do for methods that return
'Self'.
This fixes cases where we allowed code to type check that
should not type check (if the protocol extension initializer
has 'Self' in contravariant position, and we pass in an
instance of the static type).
It also fixes a miscompile with valid code -- if the protocol
extension initializer was implemented by calling 'Self()',
it would again use the static type and not the dynamic type.
Note that the SILGen change is necessary because Sema now creates
CovariantReturnExprs that convert a static class type to
DynamicSelfType, but the latter lowers to the former at the
SIL level, so we have to peephole away unnecessary unchecked_ref_cast
instructions in this case.
Because this change breaks source compatibility, it is guarded
by a '-swift-version 5' check.