Skip to content

Commit a11325c

Browse files
authored
Merge pull request #39850 from DougGregor/infer-isolated-closure-parameters
2 parents efc884d + b72f939 commit a11325c

File tree

5 files changed

+57
-5
lines changed

5 files changed

+57
-5
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,6 +1200,9 @@ class Solution {
12001200
llvm::SmallMapVector<const CaseLabelItem *, CaseLabelItemInfo, 4>
12011201
caseLabelItems;
12021202

1203+
/// The set of parameters that have been inferred to be 'isolated'.
1204+
llvm::SmallVector<ParamDecl *, 2> isolatedParams;
1205+
12031206
/// The set of functions that have been transformed by a result builder.
12041207
llvm::MapVector<AnyFunctionRef, AppliedBuilderTransform>
12051208
resultBuilderTransformed;
@@ -2360,6 +2363,9 @@ class ConstraintSystem {
23602363
llvm::SmallMapVector<const CaseLabelItem *, CaseLabelItemInfo, 4>
23612364
caseLabelItems;
23622365

2366+
/// The set of parameters that have been inferred to be 'isolated'.
2367+
llvm::SmallSetVector<ParamDecl *, 2> isolatedParams;
2368+
23632369
/// Maps closure parameters to type variables.
23642370
llvm::DenseMap<const ParamDecl *, TypeVariableType *>
23652371
OpenedParameterTypes;
@@ -2924,6 +2930,9 @@ class ConstraintSystem {
29242930
/// The length of \c caseLabelItems.
29252931
unsigned numCaseLabelItems;
29262932

2933+
/// The length of \c isolatedParams.
2934+
unsigned numIsolatedParams;
2935+
29272936
/// The length of \c ImplicitValueConversions.
29282937
unsigned numImplicitValueConversions;
29292938

lib/Sema/CSClosure.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,6 +1370,12 @@ SolutionApplicationToFunctionResult ConstraintSystem::applySolution(
13701370
auto *params = closure->getParameters();
13711371
TypeChecker::coerceParameterListToType(params, closureFnType);
13721372

1373+
// Find any isolated parameters in this closure and mark them as isolated.
1374+
for (auto param : solution.isolatedParams) {
1375+
if (param->getDeclContext() == closure)
1376+
param->setIsolated(true);
1377+
}
1378+
13731379
// Coerce the result type, if it was written explicitly.
13741380
if (closure->hasExplicitResultType()) {
13751381
closure->setExplicitResultType(closureFnType->getResult());

lib/Sema/CSSimplify.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1854,7 +1854,8 @@ static bool isSingleTupleParam(ASTContext &ctx,
18541854
return false;
18551855

18561856
const auto &param = params.front();
1857-
if (param.isVariadic() || param.isInOut() || param.hasLabel())
1857+
if (param.isVariadic() || param.isInOut() || param.hasLabel() ||
1858+
param.isIsolated())
18581859
return false;
18591860

18601861
auto paramType = param.getPlainType();
@@ -8988,15 +8989,22 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
89888989
auto param = inferredClosureType->getParams()[i];
89898990
auto *paramDecl = paramList->get(i);
89908991

8991-
// In case of anonymous or name-only parameters, let's infer inout/variadic
8992-
// flags from context, that helps to propagate type information into the
8993-
// internal type of the parameter and reduces inference solver has to make.
8992+
// In case of anonymous or name-only parameters, let's infer
8993+
// inout/variadic/isolated flags from context, that helps to propagate
8994+
// type information into the internal type of the parameter and reduces
8995+
// inference solver has to make.
89948996
if (!paramDecl->getTypeRepr()) {
89958997
if (auto contextualParam = getContextualParamAt(i)) {
89968998
auto flags = param.getParameterFlags();
8999+
9000+
// Note when a parameter is inferred to be isolated.
9001+
if (contextualParam->isIsolated() && !flags.isIsolated() && paramDecl)
9002+
isolatedParams.insert(paramDecl);
9003+
89979004
param =
89989005
param.withFlags(flags.withInOut(contextualParam->isInOut())
8999-
.withVariadic(contextualParam->isVariadic()));
9006+
.withVariadic(contextualParam->isVariadic())
9007+
.withIsolated(contextualParam->isIsolated()));
90009008
}
90019009
}
90029010

lib/Sema/CSSolver.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ Solution ConstraintSystem::finalize() {
186186

187187
solution.solutionApplicationTargets = solutionApplicationTargets;
188188
solution.caseLabelItems = caseLabelItems;
189+
solution.isolatedParams.append(isolatedParams.begin(), isolatedParams.end());
189190

190191
for (const auto &transformed : resultBuilderTransformed) {
191192
solution.resultBuilderTransformed.insert(transformed);
@@ -292,6 +293,10 @@ void ConstraintSystem::applySolution(const Solution &solution) {
292293
setCaseLabelItemInfo(info.first, info.second);
293294
}
294295

296+
for (auto param : solution.isolatedParams) {
297+
isolatedParams.insert(param);
298+
}
299+
295300
for (const auto &transformed : solution.resultBuilderTransformed) {
296301
resultBuilderTransformed.push_back(transformed);
297302
}
@@ -521,6 +526,7 @@ ConstraintSystem::SolverScope::SolverScope(ConstraintSystem &cs)
521526
numContextualTypes = cs.contextualTypes.size();
522527
numSolutionApplicationTargets = cs.solutionApplicationTargets.size();
523528
numCaseLabelItems = cs.caseLabelItems.size();
529+
numIsolatedParams = cs.isolatedParams.size();
524530
numImplicitValueConversions = cs.ImplicitValueConversions.size();
525531
numArgumentLists = cs.ArgumentLists.size();
526532

@@ -629,6 +635,9 @@ ConstraintSystem::SolverScope::~SolverScope() {
629635
// Remove any case label item infos.
630636
truncate(cs.caseLabelItems, numCaseLabelItems);
631637

638+
// Remove any isolated parameters.
639+
truncate(cs.isolatedParams, numIsolatedParams);
640+
632641
// Remove any implicit value conversions.
633642
truncate(cs.ImplicitValueConversions, numImplicitValueConversions);
634643

test/Concurrency/isolated_parameters.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,23 @@ func testTuplingIsolated(_ a: isolated A, _ b: isolated A) {
111111
// expected-error@-1 {{generic parameter 'Ts' could not be inferred}}
112112
// expected-error@-2 {{cannot convert value of type '(isolated A, isolated A) -> ()' to expected argument type '(Ts) -> Void'}}
113113
}
114+
115+
// Inference of "isolated" on closure parameters.
116+
@available(SwiftStdlib 5.5, *)
117+
func testIsolatedClosureInference(a: A) {
118+
let _: (isolated A) -> Void = {
119+
$0.f()
120+
}
121+
122+
let _: (isolated A) -> Void = {
123+
$0.f()
124+
}
125+
126+
let _: (isolated A) -> Void = { a2 in
127+
a2.f()
128+
}
129+
130+
let _: (isolated A) -> Void = { (a2: isolated A) in
131+
a2.f()
132+
}
133+
}

0 commit comments

Comments
 (0)