When we determine that a potential archetype's stated conformance to a
protocol is redundant because the superclass of that potential
archetype already conforms to that conformance, mark this conformance
as "inherited". Inherited conformances are dropped when building both
the archetype (because the conformance is recoverable via the
superclass) and when building the generic signature.
Previously, the latter occurred (because these were classified as
"redundant"), but the former did not, leading to inconsistencies in
the archetypes built from an explicitly-written "where" clause
vs. ones reconstituted from the generic signature.
Pair-programmed with Arnold. Fixes rdar://problem/29223093.
Now that the previous patches have shaken out implicit assumptions
about the order of generic requirements and substitutions, we can
make a more radical change, dropping redundant protocol requirements
when building the original generic signature.
This means that the canonical ordering and minimization that we
used to only perform when building the mangling signature is done
all of the time, and hence getCanonicalManglingSignature() can go
away.
Usages now either call getCanonicalSignature(), or operate on the
original signature directly.
Instead of walking over PotentialArchetypes representatives directly
and using a separate list to record same-type constraints, just use
enumerateRequirements() and check the RequirementSource to drop
redundant requirements.
This means getGenericSignature() and getCanonicalManglingSignature()
can share the same logic for collecting requirements; the only
differences are the following:
- both drop requirements from Redundant sources, but mangling
signatures also drop requirements from Protocol sources
- mangling signatures also canonicalize the types appearing in the
final requirement
We used RequirementSources to identify redundant requirements
when building the canonical mangling signature. There were a
few problems with how this worked:
- We used the Inferred requirement source for both requirements
that were inferred from function parameter and result types
(for example, T : Hashable in `func foo<T, U>(dict: [T : U])`
and some completely unrelated things, like same-type
constraints imposed on nested types by existing same-type
constraints on the outer types.
- We used the Protocol requirement source for associated type
requirements on protocols as well as conformance requirements
on inherited protocols.
- Introducing a new Redundant requirement did not mark existing
Explicit requirements as Redundant.
None of these were an issue because of how canonical mangling
signature construction works:
- We already started with a canonical signature, so there were
no Inferred requirements of the first kind (which we *do* want
to keep here)
- We dropped both Protocol and Redundant requirements, so it
didn't matter that the distinction here was not sufficiently
fine-grained
- We never introduced Explicit requirements that would be later
superceded by a Redundant requirement, because we always
started with an existing canonical signature where such Explicit
requirements were already dropped.
However, I want to use the same algorithm for building the
original signature as the canonical mangling signature, so this
patch introduces these changes:
- The Inferred source is now only used for inferred requirements of
the first kind; the second kind are now Redundant
- The Protocol source is now only used for associated type
requirements; inherited protocol conformances are now Redundant
- updateRequirementSource() now does the right thing with
introduced Redundant requirements
For now, this doesn't change much, but an upcoming patch
refactors ArchetypeBuilder::getGenericSignature() to also
use enumerateRequirements(), except dropping Redundant
requirements only, and not Protocol.
This fixes several issues:
- By default parent types of alias types are not printed which results in
- Erroneous fixits, for example when casting to 'Notification.Name' from a string, which ends up adding erroneous cast
as "Name(rawValue: ...)"
- Hard to understand types in code-completion results and diagnostics
- When printing with 'fully-qualified' option typealias types are printed erroneously like this "<PARENT>.Type.<TYPEALIAS>"
The change make typealias printing same as nominal types and addresses the above.
and provide a fix-it to move it to the new location as referenced
in SE-0081.
Fix up a few stray places in the standard library that is still using
the old syntax.
Update any ./test files that aren't expecting the new warning/fix-it
in -verify mode.
While investigating what I thought was a new crash due to this new
diagnostic, I discovered two sources of quite a few compiler crashers
related to unterminated generic parameter lists, where the right
angle bracket source location was getting unconditionally set to
the current token, even though it wasn't actually a '>'.
If a particular type parameter is bound by a superclass requirement C
and also stated to conform to some protocol P to which C conforms, the
conformance to P is redundant. Treat it as such in the archetype
builder.
When a type parameter has a superclass constraint, the conformances of
the superclass can resolve some nested types of the type parameter via
the type witnesses for the corresponding associated types.
Fixes rdar://problem/24730536.
There was a diagnostic to catch these, but it wasn't triggered
reliably, and it sounds like users were already relying on this
feature working in the few cases where it did.
So instead, just map an archetype's superclass into context
when building the archetype.
Recursion is still not allowed and is diagnosed, for example
<T, U where T : C<U>, U : C<T>>.
Note that compiler_crashers_fixed/00022-no-stacktrace.swift no
longer produces a diagnostic in Sema, despite the fact that the
code is invalid. It does diagnose in IRGen when we map the
type into context. Diagnosing in Sema requires fixing the
declaration checker to correctly handle recursion through a
generic signature. Right now, if recursion is detected, we bail
out, but do not always diagnose. Alternatively, we could
prohibit unbound generic types from appearing in generic
signatures.
This is a more principled fix for rdar://problem/24590570.