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: Change RequirementEnvironment::getRequirementToWitnessThunkSubs() to use contextual types
In the provided test case, the generic signature of the
protocol requirement is
<Self, T where Self == T.A, T: P2>
The conformance requirement `Self: P1` is derived from `T: P2`
and `Self.A: P1` in P1. So given a substitution map
`{ Self := X, T := T }` that replaces T with a concrete type X
and T with a type parameter T, there are two ways to recover a
substituted conformance for `Self: P1`:
- We can apply the substitution map to Self to get X, and look
up conformance of X to P1, to get a concrete conformance.
- We can evaluate the conformance path `(T: P2)(Self.A: P1)`,
to get an abstract conformance.
Both answers are correct, but SILGenModule::emitProtocolWitness()
was assuming it would always get a concrete conformance back.
This was the case until e3c8f42,
but then we started returning an abstract conformance. SILGen
would then mangle the protocol witness thunk in a way that was
not sufficiently unique, and as a result, we could miscompile
a program where two witness tables both hit this same scenario.
By using contextual types in the getRequirementToWitnessThunkSubs()
substitution map, we ensure that evaluating the conformance path
against the substitution map produces the same result as performing
the global lookup.
Also, to prevent this from happening again, add a check to SILGen
to guard against emitting two protocol witness thunks with the
same mangled name.
Unfortunately, this is done intentionally as part of some
backward deployment logic for coroutine accessors. There is a
hack to allow duplicate thunks with the same name in this case,
but this should be revisited some day.
Fixes rdar://problem/155624135..
0 commit comments