Don't assume all members are existential types; we could have
a class (or a class-constrained existential) also, and this
needs to be handled.
When building a canonical protocol composition, the subclass
requirement always comes first in the list of types. This is
an important invariant allowing ExistentialLayout to be
calculated quickly.
Also, calculate the recursive properties of the composition
type from the recursive properties of its members, since they're
no longer trivial if the composition contains a class member
with generic parameters.
This consolidates calculations which need to look at every
protocol in an existential type. Soon we will also have to
deal with superclass constrained existentials, so start
updating call sites that look at all protocols to use the
new ExistentialLayout and correctly handle a class constraint
as well.
Also, eventually I will kill off the AnyObject protocol and
model it as a protocol composition with no protocols or
superclass, but the requiresClass() flag set.
This is not quite modeled this way yet and AnyObject still
exists, but the new abstraction is a step in the right
direction.
- Add support for _Class and _NativeClass layout constraints, which are supposed to represent T: Superclass and P: class constraints in the future.
- Use the re-factoring to also reduce the number of dynamic allocations when creating layout constraints. Simple non-parametrized layout constraints are now represented as statically allocated singletons (static members of LayoutConstraintInfo).
A lot of files transitively include Expr.h, because it was
included from SILInstruction.h, SILLocation.h and SILDeclRef.h.
However in reality most of these files don't do anything
with Exprs, especially not anything in IRGen or the SILOptimizer.
Now we're down to 171 files in the frontend which depend on
Expr.h, which is still a lot but much better than before.
The new DeclBaseName type will later be able to hold either normal
identifiers (as they exist now) or special names that don't have an
identifier (like subscripts)
ASTContext::getSpecializedConformance() already copies the
substitutions, so remove some AllocateCopy() calls.
Also, add a new overload taking a SubstitutionMap instead.
This allows removing some gatherAllSubstitutions() calls,
which have an allocation inside them.
Finally, remove the now-unused ModuleDecl parameter from
ProtocolConformance::subst() and make it public.
In some cases, the type checker will produce error types with the
"original type" intact for recovery purposes. Like other types, when
the original type contains a type variable, the ErrorType instance
will be allocated in the "temporary" memory arena associated with the
active constraint solver, because there's no way that particular error
will come up again once the constraint system containing that type
variable has been destroyed.
However, we weren't propagating that "contains a type variable"
information to the newly-created ErrorType, which meant that any type
/containing/ that ErrorType would be allocated in the "permanent"
arena. In practice, this would always be a DependentMemberType; not
too many types are created without looking at their base types at all.
The arena containing the ErrorType would then be deallocated, and its
memory reused later on for a /different/ type. If we ever tried to
make a DependentMemberType whose base was this new type, we'd find the
old DependentMemberType instance in our cache and return that. The
result was that we'd have a DependentMemberType whose "HasError" bit
was set even though the base type was not an error type, and which was
considered canonical whether or not the base type was. This would then
either hit an assertion later on or result in nonsensical errors like
"'C.Iterator' is not the same type as 'C.Iterator'".
Because the reused address always referred to a valid type, none of
the usual dynamic analysis tools could catch the problem. It really
comes down to using a pointer address as a key in a map---but even
without that, we were allocating types in the permanent arena that
really should be temporary, which is a waste of memory.
Likely fixes rdar://problem/30382791, a nondeterministic failure we've
been seeing for weeks on the bots and on developer machines.
This has the effect of propagating the search path to the clang importer as '-iframework'.
It doesn't affect whether a swift module is treated as system or not, this can be done as follow-up enhancement.
This biggest change is:
- LayoutConstraintInfo is now a FoldingSetNode, which allows for proper canonicalization of LayoutConstraints. This is important for the correctness of type comparisons if types contain layout constraints.
No functionality changes from the client's point of view.
SubstitutionList is going to be a more compact representation of
a SubstitutionMap, suitable for inline allocation inside another
object.
For now, it's just a typedef for ArrayRef<Substitution>.
ArchetypeBuilder::finalize() is needed to tie up any loose ends before
requesting a generic signature or generic environment. Make sure it
gets called consistently.
We sometimes construct DependentMemberTypes with an UnresolvedType
base. These are not "real" interface types and can end up in
places where we don't expect interface types, triggering an
assertion. Make sure such types don't respond true to hasTypeParameter().
Separate formal lowered types from SIL types.
The SIL type of an argument will depend on the SIL module's conventions.
The module conventions are determined by the SIL stage and LangOpts.
Almost NFC, but specialized manglings are broken incidentally as a result of
fixes to the way passes handle book-keeping of aruments. The mangler is fixed in
the subsequent commit.
Otherwise, NFC is intended, but quite possible do to rewriting the logic in many
places.
This commit introduces new kind of requirements: layout requirements.
This kind of requirements allows to expose that a type should satisfy certain layout properties, e.g. it should be a trivial type, have a given size and alignment, etc.
Instead of creating an archetype builder with a module---which was
only used for protocol conformance lookups of concrete types
anyway---create it with a LookupConformanceFn. This is NFC for now,
but moves us closer to making archetype builders more canonicalizable
and reusable.
The typedef `swift::Module` was a temporary solution that allowed
`swift::Module` to be renamed to `swift::ModuleDecl` without requiring
every single callsite to be modified.
Modify all the callsites, and get rid of the typedef.
Teach the serialized form of ArchetypeType about its owning generic
environment, so we can wire up the generic environment of (primary)
archetypes eagerly (at the point of deserialization) rather than when
we form the generic environment. This ensures that there is no point
at which we have a (non-opened-existential) archetype without a
generic environment.
... except that the type reconstruction code creates such archetypes.
* Pack the bits for IfConfigDecls into Decl
* Don't open symbols into a module when evaluating canImport statements
The module loaders now have API to check whether a given module can be
imported without importing the referenced module. This provides a
significant speed boost to condition resolution and no longer
introduces symbols from the referenced module into the current context
without the user explicitly requesting it.
The definition of ‘canImport’ does not necessarily mean that a full
import without error is possible, merely that the path to the import is
visible to the compiler and the module is loadable in some form or
another.
Note that this means this check is insufficient to guarantee that you
are on one platform or another. For those kinds of checks, use
‘os(OSNAME)’.
Not sure why but this was another "toxic utility method".
Most of the usages fell into one of three categories:
- The base value was always non-null, so we could just call
getCanonicalType() instead, making intent more explicit
- The result was being compared for equality, so we could
skip canonicalization and call isEqual() instead, removing
some boilerplate
- Utterly insane code that made no sense
There were only a couple of legitimate uses, and even there
open-coding the conditional null check made the code clearer.
Also while I'm at it, make the SIL open archetypes tracker
more typesafe by passing around ArchetypeType * instead of
Type and CanType.
This is intended to have no functional effect, but there was a
minor change to a diagnostic in invalid code in the tests for the
unfinished ASTScope code; I hope I didn't break anything more
fundamental there.
We might allow protocols inside non-generic class/struct/enum
declarations eventually; there's no conceptual difficulty, just
some IRGen and Serialization work that has to happen first.
Also, this fixes a crasher :-)
We "fake" a conformance of UnresolvedType to any protocol.
Instead of returning a concrete conformance, return an
abstract conformance. The concrete conformance had several
problems leading to further crashes:
- The DC was set to a module, not a type declaration context,
since there is not type declaration context here.
- The conformance was marked complete even though it was missing
inherited conformances.