@@ -36,220 +36,19 @@ namespace autodiff {
3636// moved to a shared location.
3737// ===----------------------------------------------------------------------===//
3838
39- CanGenericSignature buildThunkSignature (SILFunction *fn, bool inheritGenericSig,
40- OpenedArchetypeType *openedExistential,
41- GenericEnvironment *&genericEnv,
42- SubstitutionMap &contextSubs,
43- SubstitutionMap &interfaceSubs,
44- ArchetypeType *&newArchetype) {
45- // If there's no opened existential, we just inherit the generic environment
46- // from the parent function.
47- if (openedExistential == nullptr ) {
48- auto genericSig = fn->getLoweredFunctionType ()->getInvocationGenericSignature ();
49- genericEnv = fn->getGenericEnvironment ();
50- interfaceSubs = fn->getForwardingSubstitutionMap ();
51- contextSubs = interfaceSubs;
52- return genericSig;
53- }
54-
55- auto &ctx = fn->getASTContext ();
56-
57- // Add the existing generic signature.
58- GenericSignature baseGenericSig;
59- int depth = 0 ;
60- if (inheritGenericSig) {
61- baseGenericSig = fn->getLoweredFunctionType ()->getInvocationGenericSignature ();
62- if (baseGenericSig)
63- depth = baseGenericSig.getGenericParams ().back ()->getDepth () + 1 ;
64- }
65-
66- // Add a new generic parameter to replace the opened existential.
67- auto *newGenericParam =
68- GenericTypeParamType::get (/* type sequence*/ false , depth, 0 , ctx);
69-
70- assert (openedExistential->isRoot ());
71- auto constraint = openedExistential->getExistentialType ();
72- if (auto existential = constraint->getAs <ExistentialType>())
73- constraint = existential->getConstraintType ();
74-
75- Requirement newRequirement (RequirementKind::Conformance, newGenericParam,
76- constraint);
77-
78- auto genericSig = buildGenericSignature (ctx, baseGenericSig,
79- { newGenericParam },
80- { newRequirement });
81- genericEnv = genericSig.getGenericEnvironment ();
82-
83- newArchetype =
84- genericEnv->mapTypeIntoContext (newGenericParam)->castTo <ArchetypeType>();
85-
86- // Calculate substitutions to map the caller's archetypes to the thunk's
87- // archetypes.
88- if (auto calleeGenericSig =
89- fn->getLoweredFunctionType ()->getSubstGenericSignature ()) {
90- contextSubs = SubstitutionMap::get (
91- calleeGenericSig,
92- [&](SubstitutableType *type) -> Type {
93- return genericEnv->mapTypeIntoContext (type);
94- },
95- MakeAbstractConformanceForGenericType ());
96- }
97-
98- // Calculate substitutions to map interface types to the caller's archetypes.
99- interfaceSubs = SubstitutionMap::get (
100- genericSig,
101- [&](SubstitutableType *type) -> Type {
102- if (type->isEqual (newGenericParam))
103- return openedExistential;
104- return fn->mapTypeIntoContext (type);
105- },
106- MakeAbstractConformanceForGenericType ());
107-
108- return genericSig.getCanonicalSignature ();
109- }
110-
11139CanSILFunctionType buildThunkType (SILFunction *fn,
11240 CanSILFunctionType &sourceType,
11341 CanSILFunctionType &expectedType,
11442 GenericEnvironment *&genericEnv,
11543 SubstitutionMap &interfaceSubs,
11644 bool withoutActuallyEscaping,
11745 DifferentiationThunkKind thunkKind) {
118- assert (!expectedType->isPolymorphic () &&
119- !expectedType->getCombinedSubstitutions ());
120- assert (!sourceType->isPolymorphic () &&
121- !sourceType->getCombinedSubstitutions ());
122-
123- // Cannot build a reabstraction thunk without context. Ownership semantics
124- // on the result type are required.
125- if (thunkKind == DifferentiationThunkKind::Reabstraction)
126- assert (expectedType->getExtInfo ().hasContext ());
127-
128- // This may inherit @noescape from the expected type. The `@noescape`
129- // attribute is only stripped when using this type to materialize a new decl.
130- // Use `@convention(thin)` if:
131- // - Building a reabstraction thunk type.
132- // - Building an index subset thunk type, where the expected type has context
133- // (i.e. is `@convention(thick)`).
134- auto extInfoBuilder = expectedType->getExtInfo ().intoBuilder ();
135- if (thunkKind == DifferentiationThunkKind::Reabstraction ||
136- extInfoBuilder.hasContext ()) {
137- extInfoBuilder = extInfoBuilder.withRepresentation (
138- SILFunctionType::Representation::Thin);
139- }
140- if (withoutActuallyEscaping)
141- extInfoBuilder = extInfoBuilder.withNoEscape (false );
142-
143- // Does the thunk type involve archetypes other than opened existentials?
144- bool hasArchetypes = false ;
145- // Does the thunk type involve an open existential type?
146- CanOpenedArchetypeType openedExistential;
147- auto archetypeVisitor = [&](CanType t) {
148- if (auto archetypeTy = dyn_cast<ArchetypeType>(t)) {
149- if (auto opened = dyn_cast<OpenedArchetypeType>(archetypeTy)) {
150- const auto root = cast<OpenedArchetypeType>(CanType (opened->getRoot ()));
151- assert ((openedExistential == CanArchetypeType () ||
152- openedExistential == root) &&
153- " one too many open existentials" );
154- openedExistential = root;
155- } else {
156- hasArchetypes = true ;
157- }
158- }
159- };
160-
161- // Use the generic signature from the context if the thunk involves
162- // generic parameters.
163- CanGenericSignature genericSig;
164- SubstitutionMap contextSubs;
165- ArchetypeType *newArchetype = nullptr ;
166-
167- if (expectedType->hasArchetype () || sourceType->hasArchetype ()) {
168- expectedType.visit (archetypeVisitor);
169- sourceType.visit (archetypeVisitor);
170- genericSig =
171- buildThunkSignature (fn, hasArchetypes, openedExistential, genericEnv,
172- contextSubs, interfaceSubs, newArchetype);
173- }
174-
175- auto substTypeHelper = [&](SubstitutableType *type) -> Type {
176- if (CanType (type) == openedExistential)
177- return newArchetype;
178- return Type (type).subst (contextSubs);
179- };
180- auto substConformanceHelper = LookUpConformanceInSubstitutionMap (contextSubs);
181-
182- // Utility function to apply contextSubs, and also replace the
183- // opened existential with the new archetype.
184- auto substLoweredTypeIntoThunkContext =
185- [&](CanSILFunctionType t) -> CanSILFunctionType {
186- return SILType::getPrimitiveObjectType (t)
187- .subst (fn->getModule (), substTypeHelper, substConformanceHelper)
188- .castTo <SILFunctionType>();
189- };
190-
191- sourceType = substLoweredTypeIntoThunkContext (sourceType);
192- expectedType = substLoweredTypeIntoThunkContext (expectedType);
193-
194- // If our parent function was pseudogeneric, this thunk must also be
195- // pseudogeneric, since we have no way to pass generic parameters.
196- if (genericSig)
197- if (fn->getLoweredFunctionType ()->isPseudogeneric ())
198- extInfoBuilder = extInfoBuilder.withIsPseudogeneric ();
199-
200- // Add the function type as the parameter.
201- auto contextConvention =
202- SILType::getPrimitiveObjectType (sourceType).isTrivial (*fn)
203- ? ParameterConvention::Direct_Unowned
204- : ParameterConvention::Direct_Guaranteed;
205- SmallVector<SILParameterInfo, 4 > params;
206- params.append (expectedType->getParameters ().begin (),
207- expectedType->getParameters ().end ());
208- // Add reabstraction function parameter only if building a reabstraction thunk
209- // type.
210- if (thunkKind == DifferentiationThunkKind::Reabstraction)
211- params.push_back ({sourceType, sourceType->getExtInfo ().hasContext ()
212- ? contextConvention
213- : ParameterConvention::Direct_Unowned});
214-
215- auto mapTypeOutOfContext = [&](CanType type) -> CanType {
216- return type->mapTypeOutOfContext ()->getCanonicalType (genericSig);
217- };
218-
219- // Map the parameter and expected types out of context to get the interface
220- // type of the thunk.
221- SmallVector<SILParameterInfo, 4 > interfaceParams;
222- interfaceParams.reserve (params.size ());
223- for (auto ¶m : params) {
224- auto interfaceParam = param.map (mapTypeOutOfContext);
225- interfaceParams.push_back (interfaceParam);
226- }
227-
228- SmallVector<SILYieldInfo, 4 > interfaceYields;
229- for (auto &yield : expectedType->getYields ()) {
230- auto interfaceYield = yield.map (mapTypeOutOfContext);
231- interfaceYields.push_back (interfaceYield);
232- }
233-
234- SmallVector<SILResultInfo, 4 > interfaceResults;
235- for (auto &result : expectedType->getResults ()) {
236- auto interfaceResult = result.map (mapTypeOutOfContext);
237- interfaceResults.push_back (interfaceResult);
238- }
239-
240- Optional<SILResultInfo> interfaceErrorResult;
241- if (expectedType->hasErrorResult ()) {
242- auto errorResult = expectedType->getErrorResult ();
243- interfaceErrorResult = errorResult.map (mapTypeOutOfContext);
244- }
245-
246- // The type of the thunk function.
247- return SILFunctionType::get (
248- genericSig, extInfoBuilder.build (), expectedType->getCoroutineKind (),
249- ParameterConvention::Direct_Unowned, interfaceParams, interfaceYields,
250- interfaceResults, interfaceErrorResult,
251- expectedType->getPatternSubstitutions (), SubstitutionMap (),
252- fn->getASTContext ());
46+ CanType inputSubstType;
47+ CanType outputSubstType;
48+ CanType dynamicSelfType;
49+ return buildSILFunctionThunkType (
50+ fn, sourceType, expectedType, inputSubstType, outputSubstType, genericEnv,
51+ interfaceSubs, dynamicSelfType, withoutActuallyEscaping, thunkKind);
25352}
25453
25554// / Forward function arguments, handling ownership convention mismatches.
0 commit comments