We need to make sure they don't end up as "concrete" equivalence
classes, because they behave more like unresolved ones.
Fixes rdar://problem/40009245.
Concrete and superclass constraints may be written involving type parameters
that are later resolved to concrete types. Perform the substitution to
ensure that type equality within constraint checking accounts for other
same-type constraints.
Fixes assertion in rdar://problem/40428709.
This claws back some of the regression of
2feb830b58 on certain generics heavy code.
rdar://problem/40005262 (no-opt) goes from 7.83 -> 5.75 and
rdar://problem/40010847 (opt) goes from 90.7 -> 66.6 (both -27%).
We could end up recursing through getTypeInContext() before we had time to
diagnose the recursion, so be *certain* that we can't recurse here to fix
a few crashes.
Rather than relying on the NameAliasType we get by default for references
to non-generic typealiases, use BoundNameAliasType consistently to handle
references to typealiases that are formed by the type checker.
Generic typealiases can add requirements that aren't used by their
underlying type. For example, CountableRange in the standard library:
public typealias CountableRange<Bound: Comparable> = Range<Bound>
Perform requirement inference based on uses of generic typealiases,
such that a generic function like this:
func f<T>(_: CountableRange<T>) { }
will infer T: Bound from the use of CountableRange.
Note that this does not yet work for extensions.
Swift complains about redundant inheritance of a protocol, and
canonicalizes away such redundancies in its metadata. Clang does not
warn about such redundancies, nor does the Objective-C "conforms to
protocol" check take inheritance into account. Extend the existing
"redundant inheritance" hack (designed for JSExport) to cover all
protocols defined in Objective-C, so we match Clang's output of
Objective-C metadata.
Fixes SR-7130 / rdar://problem/38394637.
Eliminate some redundant work in the GenericSignatureBuilder by only merging
one nested type per name, rather than all nested types that have that same
name.
Same-type constraints are one of the primary places where potential
archetypes are used explicitly in the GenericSignatureBuilder. Switch
the representation over to a dependent type (represented by a `Type`)
instead, furthering the demise of PotentialArchetype.
Same-type constraints are (still) described in terms of potential
archetypes, so push the "realization" operation for potential
archetypes down into the function that adds a same-type constraint
between type parameters.
GenericSignatureBuilder::addSameTypeRewriteRule() was described in
terms of an equivalence class and a potential archetype. Rework it in
terms of two dependent types (i.e., the anchors of their equivalence
classes), so we don't need to rely on the PotentialArchetype
mechanism.
Make GenericSignatureBuilder::getCanonicalTypeParameter() independent of
equivalence classes. This is primarily cleanup, because all of these
equivalence-class resolution calls were actually dead from the point
where we changed the key for the rewrite-roots DenseMap over to
dependent types.
Rather than keying the rewrite tree roots on equivalence classes,
which imply a mapping through potential archetypes, key on (canonical)
types that are currently the anchors of equivalence classes.
Now that we no longer have DependentMemberTypes within the GSB that don't
have associated type declarations, we can no longer fail when
unpacking type into a RewritePath, so remove a bunch of optionals and
null Type checks that are now superfluous.
As part of minimization, example each rule to determine whether
minimizing the left-hand-side (while ignoring the rule under question)
still produces the right-hand side. If so, the rule is redundant and
will be eliminated from the rewrite tree.
Introduce the first step of a minimization algorithm for the
term-rewriting system used to produce anchors of equivalence
classes. This step simplifies the right-hand sides of each rewrite
rule, so that each rewrite step goes to the minimal result.
This code is currently not enabled; it *can* be enabled by minimizing
before computing anchors, but it ends up pessimizing compile times to
do so.
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.
To make generic signature builder more robust it's imperative to
eliminate possibility of out-of-order typealias substitution.
These changes try to make it so potential archetypes could only be
constructed with associated types by doing early concrete type (typealias)
subsitution while trying to resolve equivalence class.
During "expansion" of the requirements of a protocol, we check all of
the inherited associated types against definitions within the
protocol. Also look for concrete types within extensions of that
protocol, so we can identify more places where developers have used
typealiases in inheriting protocols to effect a same-type constraint
on an inherited associated type.
Fixes SR-7097 / rdar://problem/38001269.
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.
Although we were properly recording rewrite rules like tau_0_1 -> tau_0_0
in the rewrite tree, we were failing to apply them, so tau_0_1 wouldn’t
get properly canonicalized. Fix this, and add some assertions to make sure
we catch this with our current test suite.
Fixes rdar://problem/37469390.
The GenericSignatureBuilder is allowing unresolved dependent member
types to creep into generic signatures, which eventually blows up in
name mangling. Prefer to pick dependent member types that are
fully-resolved when choosing anchors.
This is a spot fix; a better approach would eliminate the notion of
unresolved dependent member types entirely from
PotentialArchetype. That's tracked by rdar://problem/35839277.
Fixes rdar://problem/36549499.
Use term rewriting exclusively in the computation of the canonical
dependent type (anchor) for an equivalence class, eliminating any dependence
on the specific potential archetypes and eliminating the hacks around
generic type parameters.
Previously, the term rewriting logic for same-type constraints was only
able to express “relative” rewrites, where the base of the type being
rewritten (i.e., the generic type at the root) is unchanged. This meant
that we were unable to capture same-type constraints such as “T == U” or
“T.Foo == T” within the rewriting system.
Separate out the notion of a rewrite path and extend it with an optional
new base. When we’re simplifying a term and we encounter one of these
replacements, the whole type from the base up through the last-matched
path component gets replaced with the replacement path.
Fully rewriting a given type will produce the canonical representation of that type, because all rewrite rules take a step toward a more-canonical type. Use this approach to compute the anchor of an equivalence class, replacing the existing ad hoc approach of enumerating known potential
archetypes—which was overly dependent on having the “right” set of
potential archetypes already computed.