Introduced during the bring-up of the generics system in July, 2012,
Substitution (and SubstitutionList) has been completely superseded by
SubstitutionMap. R.I.P.
Now that SubstitutionMap is used in so many places, reduce it's header
dependencies by moving SubstitutionMap::Storage into its own separate
implementation header. Use forward declarations of other entities
(GenericSignature, Substitution) instead.
Good for build times and general sanity.
Fixes a bug where having two generic params same-typed together would lead to crashes in IRGen, and maybe other places, that only expect to deal with canonical params.
Previously, the following code would result in different sets of
conditional requirements:
struct RedundancyOrderDependenceGood<T: P1, U> {}
extension RedundancyOrderDependenceGood: P2 where U: P1, T == U {}
struct RedundancyOrderDependenceBad<T, U: P1> {}
extension RedundancyOrderDependenceBad: P2 where T: P1, T == U {}
The T: P1 requirement is redundant: it is implied from U: P1 and T == U,
but just checking it in the signature of the struct isn't sufficient,
the T == U requirement needs to be considered too. This uses a quadratic
algorithm to identify those cases. We don't think the quadratic-ness is
too bad: most cases have relatively few requirements.
Fixes rdar://problem/34944318.
Instead of representing every same-type constraint we see as a rewrite rule,
only record rewrite rules when we merge equivalence classes, and record
rules that map the between the anchors of the equivalence classes. This
gives us fewer, smaller rewrite rules that (by construction) build correct
anchors.
With specific type-checking interleavings in large projects, the generic
signature builder for the generic signature of a protocol might not have
been built from the requirement signature of the protocol, which would
lead to malformed conformance access paths. Make this code path more
robust by building a new generic signature builder when this happens.
This is a stop-gap solution that is suitable for the Swift 4.1 branch;
a better solution would be to re-canonicalize the generic signature
builder itself somehow, but this carries more risk in the short term.
Fixes rdar://problem/37335173.
This new format more efficiently represents existing information, while
more accurately encoding important information about nested generic
contexts with same-type and layout constraints that need to be evaluated
at runtime. It's also designed with an eye to forward- and
backward-compatible expansion for ABI stability with future Swift
versions.
Queries against the generic signature might use types that are
ill-formed for that generic signature, e.g., because they refer to
associated types of unrelated protocols. Detect such conditions to
maintain GSB invariants that all potential archetypes in a well-formed
generic signature are well-formed.
Fixes the crash in SR-6797 / rdar://problem/36673825.
If we used the requirement signature to create a protocol requirement
element in a requirement source, there's no need to verify that it's
from the requirement signature (duh).
When forming a conformance access path, remove from consideration any
requirement sources that contain protocol requirements that aren't
found in the requirement signature. This ensure well-formedness of the
resulting conformance access path. Huge thanks to Slava for reducing
this one, and apologies to Arnold for having to track it down a second
time before I fixed it.
Fixes SR-6200 / rdar://problem/35113583.
conformsToProtocol() is the main way in which we check whether a given type
conforms to a given protocol. Extend it to check conditional requirements by
default, so that an unmodified caller will get the "does not conform" result
(with diagnostics when a location is present) rather than simply ignoring
the conditional requirements.
Some callers take responsibility for conditional requirements, e.g., to
push them into the constraint system. Allow those callers to opt out of
this checking, and do so wherever appropriate.
Fixes rdar://problem/35518088, where we were ignoring the conditional
requirements needed to verify that Equatable synthesis could be performed.
When we canonicalize a generic signature, ensure that the resulting
signature has canonical requirements in the appropriate order.
More validation for generic signature canonicalization as part of the
ABI, which is tracked by SR-3733 / rdar://problem/31412994.
If we encounter a superclass or concrete source within a conformance
access path, use the stored conformance to terminate the path. Fixes a
compiler crasher.
Introduce GenericSignature::requirementsNotSatisfiedBy(otherSig) to
compute the set of requirements in a generic signature that aren't satisfied
by some other generic signature. This is used both for conditional
conformances (the conditional requirements) and for name mangling of
constrained extensions/protocol conformances.
The mangler had some ad hoc logic for only mangling requirements in a
generic signature that are not requirements in the parent context's
generic signature. However, it was based on an heuristic that isn't
correct. Replace that logic with a check to determine whether
the requirement is satisfied by the parent generic signature, which is
far simpler.
Fixes rdar://problem/31889040 / SR-6107.
This allows determining which requirements make a conformance conditional; as
in, which requirements aren't known as part of the type itself.
Additionally, use this to assert that a few builtin protocols aren't
conditionally-conformed-to, something we won't support for now.
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.
The anchor of an equivalence class canonically represents that equivalence
class. Add API for computing the anchor directly, and switch a few more
clients off of `resolveArchetype()`.
Queries through the GenericSignatureBuilder about a particular type
parameter only really need information about the equivalence class in which that type parameter resides. Introduce a new entry point
GenericSignatureBuilder::resolveEquivalenceClass() that only
For now, resolveEquivalanceClass() is a thin layer over
resolveArchetype().
Use ArchetypeResolutionKind::CompleteWellFormed whenever we need to
ask questions about the potential archetype, and
ArchetypeResolutionKind::WellFormed when we need only evaluate whether
there is a legitimate type with that name (and possibly get a handle
to it).
Rather than pretend that the requirement signature of a protocol is a
full, well-formed generic signature that one can meaningfully query,
treat it as a flat set of requirements. Nearly all clients already did
this, but make it official. NFC
When a requirement signature could not be used to construct the
requirement sources in a conformance access path (due to recursive
protocols), we rebuild the path based on knowledge of the
protocol. Instead of using the requirement signature for this (which
depends on a canonicalized generic signature that breaks our intended
invariants w.r.t. unresolved nested types), use the protocol's generic
signature instead. This requires one small adjustment at the root of
the path, but is otherwise NFC.
Eliminates the penultimate use of AlwaysPartial.
When we infer a requirement from the result type of a function, don't
warn if that requirement was also stated explicitly. This has been a
point of confusion since we introduced the redundancy warnings,
because users don't consider to result type to be an "input" to the
function in the way the compiler does. So, while technically it is
"correct" to warn, it's unintuitive---so stop.
Fixes SR-5072 / rdar://problem/31357967.
When resolving archetypes using the "always partial" resolution kind,
we allow the system to form potential archetypes which might be
invalid. Start limiting the use of this "always partial" resolution
kind, so that it can eventually be removed entirely to simplify the
invariants of the GenericSignatureBuilder.
Each of the callers should either be working with complete,
well-formed archetypes or they should not force any resolution this
early.
Rather than having `ASTContext:: getOrCreateCanonicalGenericEnvironment()`
ask its `GenericSignatureBuilder` parameter recompute the generic signature
at nontrivial cost, just pass the known signature through.
SubstitutionMap::lookupConformance() would map archetypes out
of context to compute a conformance path. Do the same thing
in SubstitutionMap::lookupSubstitution().
The DenseMap of replacement types in a SubstitutionMap now
always has GenericTypeParamTypes as keys.
This simplifies some code and brings us one step closer to
a more efficient representation of SubstitutionMaps.