@@ -235,27 +235,6 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
235235 decl->getASTContext ().getClangModuleLoader ()->importDeclDirectly (
236236 newFn));
237237
238- if (auto fn = dyn_cast<FuncDecl>(decl)) {
239- if (newFn->getNumParams () != fn->getParameters ()->size ()) {
240- // We added additional metatype parameters to aid template
241- // specialization, which are no longer now that we've specialized
242- // this function. Create a thunk that only forwards the original
243- // parameters along to the clang function.
244- auto thunkTypeAndParamList = substituteFunctionTypeAndParamList (decl->getASTContext (),
245- fn, subst);
246- auto thunk = FuncDecl::createImplicit (
247- fn->getASTContext (), fn->getStaticSpelling (), fn->getName (),
248- fn->getNameLoc (), fn->hasAsync (), fn->hasThrows (),
249- /* genericParams=*/ nullptr , thunkTypeAndParamList.second ,
250- thunkTypeAndParamList.first ->getResult (), fn->getDeclContext ());
251- thunk->copyFormalAccessFrom (fn);
252- thunk->setBodySynthesizer (synthesizeForwardingThunkBody, cast<FuncDecl>(newDecl));
253- thunk->setSelfAccessKind (fn->getSelfAccessKind ());
254-
255- newDecl = thunk;
256- }
257- }
258-
259238 if (auto fn = dyn_cast<AbstractFunctionDecl>(newDecl)) {
260239 // On Windows x86-64 we have to hack around the fact that
261240 // Int -> long long -> Int64. So we re-write the parameters mapping
@@ -273,8 +252,17 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
273252 ->getInterfaceType ()
274253 ->getAs <GenericFunctionType>()
275254 ->substGenericArgs (subst);
276- assert (fn->getParameters ()->size () ==
277- originalFnSubst->getParams ().size ());
255+ // The constructor type is a function type as follows:
256+ // (CType.Type) -> (Generic) -> CType
257+ // And a method's function type is as follows:
258+ // (inout CType) -> (Generic) -> Void
259+ // In either case, we only want the result of that function type because that
260+ // is the function type with the generic params that need to be substituted:
261+ // (Generic) -> CType
262+ if (isa<ConstructorDecl>(decl) || decl->isInstanceMember () ||
263+ decl->isStatic ())
264+ originalFnSubst = cast<FunctionType>(originalFnSubst->getResult ().getPointer ());
265+
278266 SmallVector<ParamDecl *, 4 > fixedParameters;
279267 unsigned parameterIndex = 0 ;
280268 for (auto *newFnParam : *fn->getParameters ()) {
@@ -293,8 +281,6 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
293281 parameterIndex++;
294282 }
295283
296- assert (fn->getParameters ()->size () == fixedParameters.size ());
297-
298284 auto fixedParams =
299285 ParameterList::create (fn->getASTContext (), fixedParameters);
300286 fn->setParameters (fixedParams);
@@ -306,17 +292,46 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
306292 fn->getASTContext ().getUIntType ())) {
307293 // Constructors don't have a result.
308294 if (auto func = dyn_cast<FuncDecl>(fn)) {
309- newDecl = FuncDecl::createImplicit (
310- func->getASTContext (), func->getStaticSpelling (),
311- func->getName (), func->getNameLoc (), func->hasAsync (),
312- func->hasThrows (),
313- /* genericParams=*/ nullptr , fixedParams,
314- originalFnSubst->getResult (), func->getDeclContext ());
295+ // We have to rebuild the whole function.
296+ auto newFnDecl = FuncDecl::createImported (
297+ func->getASTContext (), func->getNameLoc (),
298+ func->getName (), func->getNameLoc (),
299+ func->hasAsync (), func->hasThrows (),
300+ fixedParams, originalFnSubst->getResult (),
301+ /* genericParams=*/ nullptr , func->getDeclContext (), newFn);
302+ if (func->isStatic ()) newFnDecl->setStatic ();
303+ if (func->isImportAsStaticMember ()) newFnDecl->setImportAsStaticMember ();
304+ if (!func->getDeclContext ()->isModuleScopeContext ()) {
305+ newFnDecl->setSelfAccessKind (func->getSelfAccessKind ());
306+ newFnDecl->setSelfIndex (func->getSelfIndex ());
307+ }
308+ newDecl = newFnDecl;
315309 }
316310 }
317311 }
318312 }
319313
314+ if (auto fn = dyn_cast<FuncDecl>(decl)) {
315+ if (newFn->getNumParams () != fn->getParameters ()->size ()) {
316+ // We added additional metatype parameters to aid template
317+ // specialization, which are no longer now that we've specialized
318+ // this function. Create a thunk that only forwards the original
319+ // parameters along to the clang function.
320+ auto thunkTypeAndParamList = substituteFunctionTypeAndParamList (decl->getASTContext (),
321+ fn, subst);
322+ auto thunk = FuncDecl::createImplicit (
323+ fn->getASTContext (), fn->getStaticSpelling (), fn->getName (),
324+ fn->getNameLoc (), fn->hasAsync (), fn->hasThrows (),
325+ /* genericParams=*/ nullptr , thunkTypeAndParamList.second ,
326+ thunkTypeAndParamList.first ->getResult (), fn->getDeclContext ());
327+ thunk->copyFormalAccessFrom (fn);
328+ thunk->setBodySynthesizer (synthesizeForwardingThunkBody, cast<FuncDecl>(newDecl));
329+ thunk->setSelfAccessKind (fn->getSelfAccessKind ());
330+
331+ newDecl = thunk;
332+ }
333+ }
334+
320335 return ConcreteDeclRef (newDecl);
321336 }
322337
0 commit comments