When we see a second same-type-to-concrete constraint on a particular
potential archetype, record it. Previously, we were checking it and
then updating the requirement source eagerly. That won't work with
proper recursion detection, and meant that we missed out on some
obvious redundant-same-type-constraint diagnostics.
The scheme here is to build up the equivalence classes without losing
any information, and then determine which information is redundant at
the end.
Introduce an equivalence-class abstraction that captures all of the
members of the equivalence class in a separate type that will maintain
the "truth" about the meaning of the equivalence class, rather than
having that information distributed amongst the potential archetypes
within the class.
For now, use it to capture the members of the equivalence classes, so
we have one SmallVector per equivalence class rather than N
SmallVectors.
Diagnose when a same-type constraint (to a concrete type) is made
redundant by another same-type constraint. Slightly improve the
diagnostic that handles collisions between two same-type constraints.
When a type parameter is made concrete via an existential type,
conformance requirements on that type parameter will be
abstract. Fixes rdar://problem/30610428.
`GenericSignatureBuilder::resolve()` was always jumping to the
representative, to treat typealias representatives as
special. However, doing this means that we put the same-type
constraint on the wrong potential archetype (with the wrong source).
Eliminate the use of `getRepresentative()`. This unfortunately
causes us to need recursive resolution, because we can't always depend
on jumping to the representative to avoid it.
Track each same-type-to-concrete constraint on the potential archetype
against which it was written, and ensure that the requirement sources
for such same-type constraints stay with the potential archetypes on
which they were described. This is similar to the way we track
same-type constraints among potential archetypes.
Use this information to canonicalize same-type-to-concrete constraints
appropriately. For each connected component within an equivalence
class of potential archetypes, select the best requirement source to
the concrete type, or substitute in an abstract requirement source if
none exists. This approach ensures that components that would be
equivalent to that concrete type anyway get a derived source, while
components that get the concrete-type equivalence by being tied to
another
To get here, we also needed to change the notion of the archetype
anchor so that potential archetypes with no same-type constraints
directly in their path are preferred over potential archetypes that do
have a same-type constraint in their path. Otherwise, the anchor might
be something that is always concrete and is, therefore, not terribly
interesting.
Fixes the new case that popped up in rdar://problem/30478915.
Generic typealiases are entirely broken as archetypes, but some things
mostly worked with them before introducing ResolvedType, so let's
restore that behaviour.
At the moment, these are only done on demand, when the typealias is
actually used somewhere, because there's currently a recursive
validation loop that stops doing it more eagerly from working in many
cases.
This adds the concept of an "unresolved type" and a "resolved type",
where the latter involves stripping away any typealias archetype layers
from the former, to get to the "true" potential archetype or concrete
type that something refers to.
Unify the handling of the "inheritance" clauses of a generic type
parameter, associated type, or protocol, walking them in a
TypeRepr-preserving manner and adding requirements as they are
discovered. This sets the stage for providing better source-location
information [*].
This eliminates a redundant-but-different code path for protocol
"inheritance" clauses, which was using
ProtocolDecl::getInheritedProtocols() rather than looking at the
actual TypeReprs, and unifies the logic with that of associated types
and type parameters. This eliminates a near-DRY violation, sets us up
for simplifying the "inherited protocols" part of ProtocolDecl, and
sets us up better for the soon-to-be-proposed
class C { }
protocol P: C { }
[*] We still drop it, but now we have a FIXME!
If a nested type of a generic parameter was a typealias, and the
generic parameter was not at depth 0, index 0, we would resolve
the type down to the wrong PotentialArchetype, causing bogus
diagnostics and crashes.
Make sure we apply a substitution to the typealias's underlying
type before resolving it, to map it to the correct PotentialArchetype.
Note that the original test case in the radar works now, but the more
comprehensive test I added exposes an existing problem where generic
signature canonicalization is not idempotent. When this is fixed,
the RUN: line in the test can be changed from -typecheck to -emit-ir.
Fixes <rdar://problem/30248571>.
Reimplement the RequirementSource class, which captures how
a particular requirement is satisfied by a generic signature. The
primary goal of this rework is to keep the complete path one follows
in a generic signature to get from some explicit requirement in the
generic signature to some derived requirement or type, e.g.,
1) Start at an explicit requirement "C: Collection"
2) Go to the inherited protocol Sequence,
3) Get the "Iterator" associated type
4) Get its conformance to "IteratorProtocol"
5) Get the "Element" associated type
We don't currently capture all of the information we want in the path,
but the basic structure is there, and should also allow us to capture
more source-location information, find the "optimal" path, etc. There are
are a number of potential uses:
* IRGen could eventually use this to dig out the witness tables and
type metadata it needs, instead of using its own fulfillment
strategy
* SubstitutionMap could use this to lookup conformances, rather than
it's egregious hacks
* The canonical generic signature builder could use this to lookup
conformances as needed, e.g., for the recursive-conformances case.
... and probably more simplifications, once we get this right.
When we're looking up all associated types with the same name in order
to find the right archetype anchor, skip extension members to avoid
circular deserialization.
Discovered while investigating <rdar://problem/30248571>.
We no longer need the "concrete type in path" checks to correctly
order potential archetypes, and they prohibit us from making the
representative always the archetype anchor.
Make the representative of an equivalence class also be the archetype
anchor, so we don't need to walk through the equivalence class each
time we need the archetype anchor.
When emitting a requirement for a same-type-to-concrete constraint,
use the known concrete source for just the first of the component
anchors. For the rest, we need to explicitly model the constraint lest
it get lost. Fixes rdar://problem/30478915.
This essentially undoes the implementation in 51da51dfc0, which
implicitly did a substitution of the Self type in a protocol's
requirement signature by threading around the replacement PA. This is
brittle because every part of the code needs to take and pass around the
argument. By preemptively substituting, the whole requirement is in the
right form from the time it enters `addRequirement`.
The infrastructure here also allows simplifying some code.