Skip to content

Commit fdb417a

Browse files
authored
Revert "[cxx-interop] Start to import dependent types as Any"
1 parent 9285965 commit fdb417a

File tree

8 files changed

+51
-321
lines changed

8 files changed

+51
-321
lines changed

lib/ClangImporter/ImportType.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -881,8 +881,6 @@ namespace {
881881
ImportResult Visit##KIND##Type(const clang::KIND##Type *type) { \
882882
if (type->isSugared()) \
883883
return Visit(type->desugar()); \
884-
if (type->isDependentType()) \
885-
return Impl.SwiftContext.TheAnyType; \
886884
return Type(); \
887885
}
888886
MAYBE_SUGAR_TYPE(TypeOfExpr)
@@ -1861,9 +1859,7 @@ ImportedType ClangImporter::Implementation::importFunctionParamsAndReturnType(
18611859
isa<clang::TemplateSpecializationType>(clangDecl->getReturnType())) ||
18621860
// TODO: we currently don't lazily load operator return types, but
18631861
// this should be trivial to add.
1864-
clangDecl->isOverloadedOperator() ||
1865-
// Dependant types are trivially mapped as Any.
1866-
clangDecl->getReturnType()->isDependentType()) {
1862+
clangDecl->isOverloadedOperator()) {
18671863
importedType =
18681864
importFunctionReturnType(dc, clangDecl, allowNSUIntegerAsInt);
18691865
if (!importedType) {

lib/Sema/CSApply.cpp

Lines changed: 43 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ Solution::computeSubstitutions(GenericSignature sig,
112112
// On Windows and 32-bit platforms we need to force "Int" to actually be
113113
// re-imported as "Int." This is needed because otherwise, we cannot round-trip
114114
// "Int" and "UInt". For example, on Windows, "Int" will be imported into C++ as
115-
// "long long" and then back into Swift as "Int64" not "Int."
115+
// "long long" and then back into Swift as "Int64" not "Int."
116116
static ValueDecl *rewriteIntegerTypes(SubstitutionMap subst, ValueDecl *oldDecl,
117117
AbstractFunctionDecl *newDecl) {
118118
auto originalFnSubst = cast<AbstractFunctionDecl>(oldDecl)
@@ -172,116 +172,51 @@ static ValueDecl *rewriteIntegerTypes(SubstitutionMap subst, ValueDecl *oldDecl,
172172
newFnDecl->setSelfAccessKind(func->getSelfAccessKind());
173173
newFnDecl->setSelfIndex(func->getSelfIndex());
174174
}
175-
176175
return newFnDecl;
177176
}
178177
}
179178

180179
return newDecl;
181180
}
182181

183-
// Synthesize a thunk body for the function created in
184-
// "addThunkForDependentTypes". This will just cast all params and forward them
185-
// along to the specialized function. It will also cast the result before
186-
// returning it.
187-
static std::pair<BraceStmt *, bool>
188-
synthesizeDependentTypeThunkParamForwarding(AbstractFunctionDecl *afd, void *context) {
189-
ASTContext &ctx = afd->getASTContext();
190-
191-
auto thunkDecl = cast<FuncDecl>(afd);
192-
auto specializedFuncDecl = static_cast<FuncDecl *>(context);
193-
194-
SmallVector<Argument, 8> forwardingParams;
195-
unsigned paramIndex = 0;
196-
for (auto param : *thunkDecl->getParameters()) {
197-
if (isa<MetatypeType>(param->getType().getPointer())) {
198-
paramIndex++;
199-
continue;
200-
}
201-
202-
auto paramRefExpr = new (ctx) DeclRefExpr(param, DeclNameLoc(),
203-
/*Implicit=*/true);
204-
paramRefExpr->setType(param->getType());
205-
206-
auto specParamTy = specializedFuncDecl->getParameters()->get(paramIndex)->getType();
207-
auto cast = ForcedCheckedCastExpr::createImplicit(
208-
ctx, paramRefExpr, specParamTy);
209-
210-
forwardingParams.push_back(Argument(SourceLoc(), Identifier(), cast));
211-
paramIndex++;
182+
// Derive a concrete function type for fdecl by substituting the generic args
183+
// and use that to derive the corresponding function type and parameter list.
184+
static std::pair<FunctionType *, ParameterList *>
185+
substituteFunctionTypeAndParamList(ASTContext &ctx, AbstractFunctionDecl *fdecl,
186+
SubstitutionMap subst) {
187+
FunctionType *newFnType = nullptr;
188+
// Create a new ParameterList with the substituted type.
189+
if (auto oldFnType = dyn_cast<GenericFunctionType>(
190+
fdecl->getInterfaceType().getPointer())) {
191+
newFnType = oldFnType->substGenericArgs(subst);
192+
} else {
193+
newFnType = cast<FunctionType>(fdecl->getInterfaceType().getPointer());
212194
}
195+
// The constructor type is a function type as follows:
196+
// (CType.Type) -> (Generic) -> CType
197+
// And a method's function type is as follows:
198+
// (inout CType) -> (Generic) -> Void
199+
// In either case, we only want the result of that function type because that
200+
// is the function type with the generic params that need to be substituted:
201+
// (Generic) -> CType
202+
if (isa<ConstructorDecl>(fdecl) || fdecl->isInstanceMember() ||
203+
fdecl->isStatic())
204+
newFnType = cast<FunctionType>(newFnType->getResult().getPointer());
205+
SmallVector<ParamDecl *, 4> newParams;
206+
unsigned i = 0;
213207

214-
auto *specializedFuncDeclRef = new (ctx) DeclRefExpr(ConcreteDeclRef(specializedFuncDecl),
215-
DeclNameLoc(), true);
216-
specializedFuncDeclRef->setType(specializedFuncDecl->getInterfaceType());
217-
218-
auto argList = ArgumentList::createImplicit(ctx, forwardingParams);
219-
auto *specializedFuncCallExpr = CallExpr::createImplicit(ctx, specializedFuncDeclRef, argList);
220-
specializedFuncCallExpr->setType(specializedFuncDecl->getResultInterfaceType());
221-
specializedFuncCallExpr->setThrows(false);
222-
223-
auto cast = ForcedCheckedCastExpr::createImplicit(
224-
ctx, specializedFuncCallExpr, thunkDecl->getResultInterfaceType());
225-
226-
auto returnStmt = new (ctx) ReturnStmt(SourceLoc(), cast, /*implicit=*/true);
227-
auto body = BraceStmt::create(ctx, SourceLoc(), {returnStmt}, SourceLoc(),
228-
/*implicit=*/true);
229-
return {body, /*isTypeChecked=*/true};
230-
}
231-
232-
// Create a thunk to map functions with dependent types to their specialized
233-
// version. For example, create a thunk with type (Any) -> Any to wrap a
234-
// specialized function template with type (Dependent<T>) -> Dependent<T>.
235-
static ValueDecl *addThunkForDependentTypes(FuncDecl *oldDecl,
236-
FuncDecl *newDecl) {
237-
bool updatedAnyParams = false;
238-
239-
SmallVector<ParamDecl *, 4> fixedParameters;
240-
unsigned parameterIndex = 0;
241-
for (auto *newFnParam : *newDecl->getParameters()) {
242-
// If the un-specialized function had a parameter with type "Any" preserve
243-
// that parameter. Otherwise, use the new function parameter.
244-
auto oldParamType = oldDecl->getParameters()->get(parameterIndex)->getType();
245-
if (oldParamType->isEqual(newDecl->getASTContext().TheAnyType)) {
246-
updatedAnyParams = true;
247-
auto newParam =
248-
ParamDecl::cloneWithoutType(newDecl->getASTContext(), newFnParam);
249-
newParam->setInterfaceType(oldParamType);
250-
fixedParameters.push_back(newParam);
251-
} else {
252-
fixedParameters.push_back(newFnParam);
253-
}
254-
parameterIndex++;
208+
for (auto paramTy : newFnType->getParams()) {
209+
auto *oldParamDecl = fdecl->getParameters()->get(i);
210+
auto *newParamDecl =
211+
ParamDecl::cloneWithoutType(fdecl->getASTContext(), oldParamDecl);
212+
newParamDecl->setInterfaceType(paramTy.getParameterType());
213+
newParams.push_back(newParamDecl);
214+
(void)++i;
255215
}
216+
auto *newParamList =
217+
ParameterList::create(ctx, SourceLoc(), newParams, SourceLoc());
256218

257-
// If we don't need this thunk, bail out.
258-
if (!updatedAnyParams &&
259-
!oldDecl->getResultInterfaceType()->isEqual(
260-
oldDecl->getASTContext().TheAnyType))
261-
return newDecl;
262-
263-
auto fixedParams =
264-
ParameterList::create(newDecl->getASTContext(), fixedParameters);
265-
266-
Type fixedResultType;
267-
if (oldDecl->getResultInterfaceType()->isEqual(
268-
oldDecl->getASTContext().TheAnyType))
269-
fixedResultType = oldDecl->getASTContext().TheAnyType;
270-
else
271-
fixedResultType = newDecl->getResultInterfaceType();
272-
273-
// We have to rebuild the whole function.
274-
auto newFnDecl = FuncDecl::createImplicit(
275-
newDecl->getASTContext(), newDecl->getStaticSpelling(),
276-
newDecl->getName(), newDecl->getNameLoc(), newDecl->hasAsync(),
277-
newDecl->hasThrows(), /*genericParams=*/nullptr, fixedParams,
278-
fixedResultType, newDecl->getDeclContext());
279-
newFnDecl->copyFormalAccessFrom(newDecl);
280-
newFnDecl->setBodySynthesizer(synthesizeDependentTypeThunkParamForwarding, newDecl);
281-
newFnDecl->setSelfAccessKind(newDecl->getSelfAccessKind());
282-
newFnDecl->getAttrs().add(
283-
new (newDecl->getASTContext()) TransparentAttr(/*IsImplicit=*/true));
284-
return newFnDecl;
219+
return {newFnType, newParamList};
285220
}
286221

287222
// Synthesizes the body of a thunk that takes extra metatype arguments and
@@ -332,55 +267,16 @@ static ValueDecl *generateThunkForExtraMetatypes(SubstitutionMap subst,
332267
// specialization, which are no longer now that we've specialized
333268
// this function. Create a thunk that only forwards the original
334269
// parameters along to the clang function.
335-
SmallVector<ParamDecl *, 4> newParams;
336-
337-
for (auto param : *newDecl->getParameters()) {
338-
auto *newParamDecl = ParamDecl::clone(newDecl->getASTContext(), param);
339-
newParams.push_back(newParamDecl);
340-
}
341-
342-
auto originalFnSubst = cast<AbstractFunctionDecl>(oldDecl)
343-
->getInterfaceType()
344-
->getAs<GenericFunctionType>()
345-
->substGenericArgs(subst);
346-
// The constructor type is a function type as follows:
347-
// (CType.Type) -> (Generic) -> CType
348-
// And a method's function type is as follows:
349-
// (inout CType) -> (Generic) -> Void
350-
// In either case, we only want the result of that function type because that
351-
// is the function type with the generic params that need to be substituted:
352-
// (Generic) -> CType
353-
if (isa<ConstructorDecl>(oldDecl) || oldDecl->isInstanceMember() ||
354-
oldDecl->isStatic())
355-
originalFnSubst = cast<FunctionType>(originalFnSubst->getResult().getPointer());
356-
357-
for (auto paramTy : originalFnSubst->getParams()) {
358-
if (!paramTy.getPlainType()->is<MetatypeType>())
359-
continue;
360-
361-
auto dc = newDecl->getDeclContext();
362-
auto paramVarDecl =
363-
new (newDecl->getASTContext()) ParamDecl(
364-
SourceLoc(), SourceLoc(), Identifier(), SourceLoc(),
365-
newDecl->getASTContext().getIdentifier("_"), dc);
366-
paramVarDecl->setInterfaceType(paramTy.getPlainType());
367-
paramVarDecl->setSpecifier(ParamSpecifier::Default);
368-
newParams.push_back(paramVarDecl);
369-
}
370-
371-
auto *newParamList =
372-
ParameterList::create(newDecl->getASTContext(), SourceLoc(), newParams, SourceLoc());
373-
270+
auto thunkTypeAndParamList = substituteFunctionTypeAndParamList(oldDecl->getASTContext(),
271+
oldDecl, subst);
374272
auto thunk = FuncDecl::createImplicit(
375-
newDecl->getASTContext(), newDecl->getStaticSpelling(), oldDecl->getName(),
376-
newDecl->getNameLoc(), newDecl->hasAsync(), newDecl->hasThrows(),
377-
/*genericParams=*/nullptr, newParamList,
378-
newDecl->getResultInterfaceType(), newDecl->getDeclContext());
379-
thunk->copyFormalAccessFrom(newDecl);
273+
oldDecl->getASTContext(), oldDecl->getStaticSpelling(), oldDecl->getName(),
274+
oldDecl->getNameLoc(), oldDecl->hasAsync(), oldDecl->hasThrows(),
275+
/*genericParams=*/nullptr, thunkTypeAndParamList.second,
276+
thunkTypeAndParamList.first->getResult(), oldDecl->getDeclContext());
277+
thunk->copyFormalAccessFrom(oldDecl);
380278
thunk->setBodySynthesizer(synthesizeForwardingThunkBody, newDecl);
381-
thunk->setSelfAccessKind(newDecl->getSelfAccessKind());
382-
thunk->getAttrs().add(
383-
new (newDecl->getASTContext()) TransparentAttr(/*IsImplicit=*/true));
279+
thunk->setSelfAccessKind(oldDecl->getSelfAccessKind());
384280

385281
return thunk;
386282
}
@@ -430,10 +326,6 @@ static ConcreteDeclRef getCXXFunctionTemplateSpecialization(SubstitutionMap subs
430326
}
431327
}
432328

433-
if (auto fn = dyn_cast<FuncDecl>(decl)) {
434-
newDecl = addThunkForDependentTypes(fn, cast<FuncDecl>(newDecl));
435-
}
436-
437329
if (auto fn = dyn_cast<FuncDecl>(decl)) {
438330
if (newFn->getNumParams() != fn->getParameters()->size()) {
439331
newDecl = generateThunkForExtraMetatypes(subst, fn,

test/Interop/Cxx/templates/Inputs/dependent-types.h

Lines changed: 0 additions & 55 deletions
This file was deleted.

test/Interop/Cxx/templates/Inputs/module.modulemap

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,4 @@ module TemplateTypeParameterNotInSignature {
131131
module DefineReferencedInline {
132132
header "define-referenced-inline.h"
133133
requires cplusplus
134-
}
135-
136-
module DependentTypes {
137-
header "dependent-types.h"
138-
requires cplusplus
139-
}
134+
}

test/Interop/Cxx/templates/dependent-types-module-interface.swift

Lines changed: 0 additions & 11 deletions
This file was deleted.

test/Interop/Cxx/templates/dependent-types-silgen.swift

Lines changed: 0 additions & 49 deletions
This file was deleted.

0 commit comments

Comments
 (0)