Skip to content

Commit 4488c79

Browse files
authored
Merge pull request #77764 from swiftlang/gaborh/conditional-escapability-variadic
[cxx-interop] Support parameter packs in escapability annotations
2 parents 04de349 + 751bcfd commit 4488c79

File tree

2 files changed

+34
-12
lines changed

2 files changed

+34
-12
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5099,21 +5099,29 @@ ClangTypeEscapability::evaluate(Evaluator &evaluator,
50995099
auto &argList = specDecl->getTemplateArgs();
51005100
for (auto argToCheck : argumentsToCheck) {
51015101
auto arg = argList[argToCheck.first];
5102-
if (arg.getKind() != clang::TemplateArgument::Type) {
5103-
desc.impl.diagnose(loc, diag::type_template_parameter_expected,
5104-
argToCheck.second);
5105-
return CxxEscapability::Unknown;
5106-
}
5102+
llvm::SmallVector<clang::TemplateArgument, 1> nonPackArgs;
5103+
if (arg.getKind() == clang::TemplateArgument::Pack) {
5104+
auto pack = arg.getPackAsArray();
5105+
nonPackArgs.assign(pack.begin(), pack.end());
5106+
} else
5107+
nonPackArgs.push_back(arg);
5108+
for (auto nonPackArg : nonPackArgs) {
5109+
if (nonPackArg.getKind() != clang::TemplateArgument::Type) {
5110+
desc.impl.diagnose(loc, diag::type_template_parameter_expected,
5111+
argToCheck.second);
5112+
return CxxEscapability::Unknown;
5113+
}
51075114

5108-
auto argEscapability = evaluateEscapability(
5109-
arg.getAsType()->getUnqualifiedDesugaredType());
5110-
if (argEscapability == CxxEscapability::NonEscapable)
5111-
return CxxEscapability::NonEscapable;
5115+
auto argEscapability = evaluateEscapability(
5116+
nonPackArg.getAsType()->getUnqualifiedDesugaredType());
5117+
if (argEscapability == CxxEscapability::NonEscapable)
5118+
return CxxEscapability::NonEscapable;
5119+
}
51125120
}
5113-
clang::DeclContext *rec = specDecl;
5121+
clang::DeclContext *dc = specDecl;
51145122
specDecl = nullptr;
5115-
while ((rec = rec->getParent())) {
5116-
specDecl = dyn_cast<clang::ClassTemplateSpecializationDecl>(rec);
5123+
while ((dc = dc->getParent())) {
5124+
specDecl = dyn_cast<clang::ClassTemplateSpecializationDecl>(dc);
51175125
if (specDecl)
51185126
break;
51195127
}

test/Interop/Cxx/class/nonescapable-errors.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ Outer<View>::NonTemplated::Inner<Owner> j1();
7777
Outer<Owner>::NonTemplated::Inner<View> j2();
7878
Outer<Owner>::NonTemplated::Inner<Owner> j3();
7979

80+
template<typename... Ts>
81+
struct SWIFT_ESCAPABLE_IF(Ts) MyTuple {};
82+
83+
MyTuple<View> k1();
84+
MyTuple<Owner, View> k2();
85+
MyTuple<Owner, Owner> k3();
86+
8087
//--- test.swift
8188
import Test
8289

@@ -113,6 +120,13 @@ public func noAnnotations() -> View {
113120
// CHECK: nonescapable.h:63:41: error: cannot infer lifetime dependence, no parameters found that are either ~Escapable or Escapable with a borrowing ownership
114121
// CHECK-NO-LIFETIMES: nonescapable.h:63:41: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
115122
j3()
123+
k1();
124+
// CHECK: nonescapable.h:69:15: error: cannot infer lifetime dependence, no parameters found that are either ~Escapable or Escapable with a borrowing ownership
125+
// CHECK-NO-LIFETIMES: nonescapable.h:69:15: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
126+
k2();
127+
// CHECK: nonescapable.h:70:22: error: cannot infer lifetime dependence, no parameters found that are either ~Escapable or Escapable with a borrowing ownership
128+
// CHECK-NO-LIFETIMES: nonescapable.h:70:22: error: returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'
129+
k3();
116130
// CHECK-NOT: error
117131
// CHECK-NOT: warning
118132
return View()

0 commit comments

Comments
 (0)