Before lookup was requestified, the entire lookup stack would
install semantic members. As this caused cycles in the lookup path, it
was refactored to instead only occur at the TypeChecker::lookup*
entrypoints. Unfortunately, these entrypoints were not kept in sync with
the stack building code in qualified lookup, so a case was missed:
class-bound archetypes. We need to synthesize semantic members for them
as well or we'll non-deterministically fail to find synthesizable
members in incremental mode.
rdar://74174749
Since getStoredProperties() is a request that lowers lazy properties
and property wrappers to their underlying storage, and SIL can validate
stored property and enum element types, there's no longer any need for
Sema to explicitly finalize members of structs and enums. SILGen can
trigger any necessary type checkin work just by lowering a struct or
enum type.
Now the only remaining reason we need finalizeDecl() is adding implicit
methods to classes, and synthesizing accessors for storage in classes
and protocols.
If a convenience initializer in a subclass delegated to an inherited initializer from its base, we would end up type-checking the reference to the base class constructor as returning the base type, leading to type mismatches in the result AST and downstream crashes. We can wrap up the synthesized OtherConstructorRefExpr in a CovariantFunctionConversionExpr, which will trick the type checker into propagating the covariant result that gets rebound to `self` on return, avoiding this problem. (For now, I'm avoiding making the constructor decl formally have a Self return type, since that exposes a bunch of downstream breakage in code paths that only expect FuncDecls to be covariant, and also affects the mangling of constructors, causing a bunch of test case thrash we really don't want to inflict on the 3.1 branch.)