You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
AST: Fix issue where SIL type lowering did not commute with subst()
SIL type lowering uses ReplaceOpaqueTypesWithUnderlyingTypes to lower away
opaque result types when the current context can "see" the underlying type
of the opaque result type.
To determine if an opaque result type could be replaced with its
underlying type, we check if every nominal type declaration appearing
in the "fully substituted" underlying type is visible from the current
context.
To form the "fully substituted" type, we first apply the substitution map
stored in the opaque type decl, which replaces the 'Self' generic parameter
with the actual concrete result type.
Then, we apply the substitution map stored in the archetype itself.
However, calling subst() on an opaque archetype modifies the substitution
map stored in the archetype.
What this means in practice is that if I have an opaque type declaration
that depends on its outer generic parameters, the fully-substituted type
that I see here depends on whether subst() has been performed or not.
For example, suppose I have the following:
protocol P {}
struct S : P {}
extension P {
func foo() -> some Any { return [self] }
}
The opaque result decl for P.foo() maps 'Self' to 'Array<Self>'. Now,
imagine someone calls foo() with the substitution 'Self := S'. The
fully-substituted underlying type is 'Array<S>'. If 'S' is private, we
will decide that we cannot replace the opaque result type with its
underlying type. However, if we had performed the opaque type replacement
_before_ substituting 'Self := S', then we will end up replacing the
opaque result type.
To re-state this in yet another form, we want the following identity to
hold here:
getLoweredType(opaqueType).subst(subMap) == getLoweredType(opaqueType.subst(subMap))
We can ensure that this holds by only applying the archetype's
substitutions _after_ we check visibility.
Fixes rdar://problem/76556368.
0 commit comments