Add a request to lookup all implied conformances for use while
typechecking the primary. This provides a cache-point for
evaluator-based dependency tracking.
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`.
This removes a set of static assertions that did not do what they were
supposed to do.
The static assertions were attempting to ensure that the functions are
different. However, the address of a function is *not* a constant
expression and cannot be used in a static assertion.
Furthermore, the static assert is either tautologically true or will be
caught as a compile error on the dispatch. The methods being checked
here are non-virtual. The PFN that was being computed is tautologically
different as there is no virtuality and the two methods must be
different (barring any ICF coalescing that may be performed by the
linker or by LTO). The method must exist, otherwise, the dispatch
itself will trigger a resolution failure.
Effectively, the static assertionss did not compute anything as a
result:
- the method's existence is checked by the dispatch
- the address of the function is always different
This was identified by building with GCC 7.
Witness matching is a source of a lot of ad-hoc cycles, and mixes the
logic that performs resolution, caching, validation, and cycle detection into one
place. To make matters worse, some checkers kick off other checks in
order to cache work for further declarations, and access an internal
cache on their subject conformance for many requirements at once, or
sometimes just one requirement.
None of this fits into the request evaluator's central view of the
caching. This is further evidenced by the fact that if you attempt to
move the caching step into the evaluator, it overcaches the same
witness and trips asserts.
As a start, define requests for the resolution steps, and flush some
hacks around forcing witness resolution. The caching logic is mostly
untouched (the requests don't actually cache anything), but some cycle
breaking is now handled in the evaluator itself. Once witness matching
has been refactored to cache with the evaluator, all of these hacks can
go away.
My urge to destroy the LazyResolver outweighs the compromises here.
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.
The general class of cycle here is when validation asks for the generic signature which triggers requirement checking which forces us to ask for the generic signature of the extension again. We should look into a more principled solution.
See rdar://55263708
Most of AST, Parse, and Sema deal with FileUnits regularly, but SIL
and IRGen certainly don't. Split FileUnit out into its own header to
cut down on recompilation times when something changes.
No functionality change.
Computing the generic signature changes the way that cycles appear in the compiler. For now, break these cycles. We should investigate each place where hasComputedGenericSignature() is used in service of breaking cycles. See rdar://55263708
First, remove the AvailabilityContext parameter; it was confusing because
we actually always want to use the deployment target here.
Then, split this method up into three methods:
- isAlwaysWeakImported(): simply checks for a @_weakLinked attribute, either
on the declaration itself or one of its parent contexts.
- getAvailabilityForLinkage(): returns the OS version availability when
this declaration was introduced, or if the declaration does not have
explicit availability, check it's storage (if its an accessor), or its
parent contexts.
- isWeakImported(ModuleDecl *fromModule): combines these two checks to
determine if the declaration should be weak linked when referenced from
the given module, or if it might be weak referenced from some module
(if the module parameter is null).
We've fixed a number of bugs recently where callers did not expect
to get a null Type out of subst(). This occurs particularly often
in SourceKit, where the input AST is often invalid and the types
resulting from substitution are mostly used for display.
Let's fix all these potential problems in one fell swoop by changing
subst() to always return a Type, possibly one containing ErrorTypes.
Only a couple of places depended on the old behavior, and they were
easy enough to change from checking for a null Type to checking if
the result responds with true to hasError().
Also while we're at it, simplify a few call sites of subst().
Now that ensureRequirementsAreSatisfied() is never called with
failUnsubstituted == false, remove all the logic for deferring
checking of a conformance against the requirement signature of
its protocol.
Previously we would call ensureRequirementsAreSatisfied() with the
failUnsubstituted parameter set to false. This would populate the
signature conformances and check the requirement signature in a
parsed conformance.
Sometimes, forming the substituted requirement types would fail,
and since failUnsubstituted was false the conformance would be
added to TypeChecker::PartiallyCheckedConformances.
Now, we use finishSignatureConformances() to lazily populate
the signature conformances when needed. This is always expected to
produce valid conformances.
ensureRequirementsAreSatisfied() is still called for conformances
in primary files, but it no longer writes to the signature
conformances array, and instead only diagnoses errors.
This method was only ever called with non-generic witnesses,
because it assumed the substitutions stored in the witness
would always be derived from the conforming type.
There were two cases where this wasn't the case though:
1) If the witness is itself generic
2) The witness was defined in a protocol extension and the
conforming type is a non-final class
In all cases, the SubstitutionMap stored in a Witness always
uses the 'synthetic environment'. In some cases, the
'synthetic environment' is the generic environment of the
witness. But in 1) and 2) it was different. While 1) never
occurred because we never used this method to look up
witnesses for generic requirements, 2) could happen.
ConformanceChecker::ensureRequirementsAreSatisfied() modifies the
conformance as it resolves each one of its associated conformances,
so a re-entrant call can end up corrupting state by adding too
many elements to the buffer, or adding elements at the wrong
offsets.
If TypeChecker::checkConformanceRequirements() was called before
ConformanceChecker::resolveTypeWitnesses(), we could re-entrantly call
ConformanceChecker::ensureRequirementsAreSatisfied():
TypeChecker::checkConformanceRequirements()
=> ConformanceChecker::ensureRequirementsAreSatisfied()
=> Type::subst(), etc
=> ConformanceChecker::resolveTypeWitnesses()
=> ConformanceChecker::ensureRequirementsAreSatisfied()
The code in SubstitutionMap::lookupConformance() worked around
this by checking the failure condition and calling
resolveTypeWitness() first, before calling getAssociatedConformance().
Instead, remove this and call resolveTypeWitness() from inside
NormalProtocolConformance::getAssociatedConformance().
Way back in Swift 1 I was trying to draw a distinction between
"overlays", separate libraries that added Swift content to an existing
Objective-C framework, and "the Swift part of a mixed-source
framework", even though they're implemented in almost exactly the same
way. "Adapter module" was the term that covered both of those. In
practice, however, no one knew what "adapter" meant. Bring an end to
this confusion by just using "overlay" within the compiler even for
the mixed-source framework case.
No intended functionality change.
Sorting of DeclContext-local protocols and conformances shouldn't ever
be necessary, because the underlying data structures that produce
these lists should be deterministic. Sorting can hide any
non-determinism, so stop doing it and we can address the underlying
nondeterminism.
NormalProtocolConformance::isRetroactive() introduces dependency on swiftClangImporter by calling ClangModuleUnit::getAdapterModule().
Do some refactoring to break the cycle.
When debugging Objective-C or C++ code on Darwin, the debug info
collected by dsymutil in the .dSYM bundle is entirely
self-contained. It is possible to debug a program, set breakpoints and
print variables even without having the complete original source code
or a matching SDK available. With Swift, this is currently not the
case. Even though .dSYM bundles contain the binary .swiftmodule for
all Swift modules, any Clang modules that the Swift modules depend on,
still need to be imported from source to even get basic LLDB
functionality to work. If ClangImporter fails to import a Clang
module, effectively the entire Swift module depending on it gets
poisoned.
This patch is addressing this issue by introducing a ModuleLoader that
can ask queries about Clang Decls to LLDB, since LLDB knows how to
reconstruct Clang decls from DWARF and clang -gmodules producxes full
debug info for Clang modules that is embedded into the .dSYM budle.
This initial version does not contain any advanced functionality at
all, it merely produces an empty ModuleDecl. Intertestingly, even this
is a considerable improvement over the status quo. LLDB can now print
Swift-only variables in modules with failing Clang depenecies, and
becuase of fallback mechanisms that were implemented earlier, it can
even display the contents of pure Objective-C objects that are
imported into Swift. C structs obviously don't work yet.
rdar://problem/36032653
If the type checker doesn't prepopulate signature conformances, fill
them in when we first need them. This is a stopgap solution until we
can move these queries over to the request-evaluator.
Fixes rdar://problem/34584596, as well as a regression introduced by
the use of mangled names for associated conformances in witness tables.