This is technically a source break, but it was always a circularity
issue. It will compile fine in isolation, but all attempts to lookup
nested type via qualified lookup (e.g. witness matching) will re-enter
themselves and potentially produce inconsistent results.
Commit a regression test so we nail down this behavior to see if we can
revisit this.
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.
It is possible for getSuperclassDecl() to return a non-null type, while
getSuperclass() returns an ErrorType. In this case, getContextSubstitutions()
could crash because the walk of the superclass chain via getSuperclass()
might not find the context class.
Instead of crashing in asserts builds, let getContextSubstitutions()
silently build an invalid substitution map here, just as it does in no-asserts
builds.
getInterfaceType() will return an ErrorType if the declaration is currently
being validated, which can happen if override checking triggers associated
type inference.
I believe this is <rdar://problem/47220065>.
Resolve a cycle caused by overload resolution considering recursive
static candidates where before it would silently reject them. In
a world before the InterfaceTypeRequest, the overload resolution
machinery would attempt to validate the declaration and would recieve
a bad answer. This caused circular candidates to be ignored as a side
effect. This behavior was partially restored by the fixes in #27725 and #27668
but that isn't enough for recursive static variables. Even if it were,
the constraint fix kind doesn't make sense.
Luckily, the right answer is to just reject recursive static VarDecl
candidates entirely.
Addresses rdar://56410015
When member type lookup is rooted at a typealias, it should not be possible for that
lookup to see the typealias itself. This prevents recursively trying
to resolve the underlying type, which used to be silently ignored when
validateDecl bounced the caller back with an error type or a null type.
Addresses rdar://56411408