This simplifies fixing the master-next build. Upstream LLVM already
has a copy of this function, so on master-next we only need to delete
the Swift copy, reducing the potential for merge conflicts.
Motivation: `GenericSignatureImpl::getCanonicalSignature` crashes for
`GenericSignature` with underlying `nullptr`. This led to verbose workarounds
when computing `CanGenericSignature` from `GenericSignature`.
Solution: `GenericSignature::getCanonicalSignature` is a wrapper around
`GenericSignatureImpl::getCanonicalSignature` that returns the canonical
signature, or `nullptr` if the underlying pointer is `nullptr`.
Rewrite all verbose workarounds using `GenericSignature::getCanonicalSignature`.
ProtocolConformanceRef already has an invalid state. Drop all of the
uses of Optional<ProtocolConformanceRef> and just use
ProtocolConformanceRef::forInvalid() to represent it. Mechanically
translate all of the callers and callsites to use this new
representation.
Structurally prevent a number of common anti-patterns involving generic
signatures by separating the interface into GenericSignature and the
implementation into GenericSignatureBase. In particular, this allows
the comparison operators to be deleted which forces callers to
canonicalize the signature or ask to compare pointers explicitly.
This memoizes the result, which is fine for all callers; the only
exception is open existential types where each new open existential
now explicitly gets a unique generic environment, allocated by
calling GenericEnvironment::getIncomplete().
When a request for an abstract generic signature contains noncanonical
types, first compute the abstract generic signature for the
canonicalized types, then map back to the provided generic
parameters. Clients of this request generally work in canonical types
already, but it's a small win.
Introduce a request to form an abstract generic signature given a
base signature, additional generic parameters, and additional
requirements. It is meant to provide a caching layer in front of the
generic signature builder.
Switch one direct client of the generic signature builder over to this
mechanism, the formation of a generic signature for an existential
type.
Opaque result type archetypes can involve type variables, which
then get introduced into GenericSignatureBuilders and the
generated GenericSignatures. Allocate them in the proper arena
So we don’t end up with use-after-free errors.
Fixes rdar://problem/50309503.
When substituting type parameters to compute a canonical type within a
given generic context, also handle the case where the type parameter is
directly known to be a concrete type. The type checker won’t do this, but
SourceKit does.
Fixes a regression in SourceKit/DocSupport/doc_stdlib.swift.
This silences the instances of the warning from Visual Studio about not all
codepaths returning a value. This makes the output more readable and less
likely to lose useful warnings. NFC.
It's a recursive helper that only captures one argument other than
'this'. Pay the cost of putting a declaration in a commonly-included
header to simplify the code.
No intended functionality change.
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.