Skip to content

Commit aa99cbc

Browse files
committed
[Concurrency] Always diagnose invalid isolated parameter types in type resolution.
1 parent e32fd8a commit aa99cbc

File tree

4 files changed

+36
-49
lines changed

4 files changed

+36
-49
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5528,10 +5528,8 @@ NOTE(protocol_isolated_to_global_actor_here,none,
55285528
"%0 is isolated to global actor %1 here", (Type, Type))
55295529

55305530
ERROR(isolated_parameter_not_actor,none,
5531-
"'isolated' parameter has non-actor type %0", (Type))
5532-
ERROR(isolated_parameter_no_actor_conformance,none,
5533-
"'isolated' parameter %0 must conform to 'Actor' "
5534-
"or 'DistributedActor' protocol", (Type))
5531+
"'isolated' parameter type %0 does not conform to 'Actor' "
5532+
"or 'DistributedActor'", (Type))
55355533
ERROR(isolated_parameter_duplicate,none,
55365534
"cannot have more than one 'isolated' parameter", ())
55375535
ERROR(isolated_parameter_duplicate_type,none,

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4759,27 +4759,8 @@ ActorIsolation ActorIsolationRequest::evaluate(
47594759
checkDeclWithIsolatedParameter(value);
47604760

47614761
ParamDecl *param = getParameterList(value)->get(*paramIdx);
4762-
Type paramType = param->getInterfaceType();
4763-
if (paramType->isTypeParameter()) {
4764-
paramType = param->getDeclContext()->mapTypeIntoContext(paramType);
4765-
4766-
auto &ctx = value->getASTContext();
4767-
auto conformsTo = [&](KnownProtocolKind kind) {
4768-
if (auto *proto = ctx.getProtocol(kind))
4769-
return value->getModuleContext()->checkConformance(paramType, proto);
4770-
return ProtocolConformanceRef::forInvalid();
4771-
};
4772-
4773-
// The type parameter must be bound by Actor or DistributedActor, as they
4774-
// have an unownedExecutor. AnyActor does NOT have an unownedExecutor!
4775-
if (!conformsTo(KnownProtocolKind::Actor)
4776-
&& !conformsTo(KnownProtocolKind::DistributedActor)) {
4777-
ctx.Diags.diagnose(param->getLoc(),
4778-
diag::isolated_parameter_no_actor_conformance,
4779-
paramType);
4780-
}
4781-
}
4782-
4762+
Type paramType = param->getDeclContext()->mapTypeIntoContext(
4763+
param->getInterfaceType());
47834764
Type actorType;
47844765
if (auto wrapped = paramType->getOptionalObjectType()) {
47854766
actorType = wrapped;

lib/Sema/TypeCheckType.cpp

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3927,18 +3927,6 @@ NeverNullType TypeResolver::resolveASTFunctionType(
39273927
repr->setWarned();
39283928
}
39293929

3930-
// Use parameter isolation if we have any. This overrides all other
3931-
// forms (and should cause conflict diagnostics).
3932-
if (numIsolatedParams > 0) {
3933-
isolation = FunctionTypeIsolation::forParameter();
3934-
3935-
if (isolatedAttr) {
3936-
diagnose(repr->getLoc(), diag::isolated_parameter_isolated_attr_type,
3937-
isolatedAttr->getIsolationKindName());
3938-
isolatedAttr->setInvalid();
3939-
}
3940-
}
3941-
39423930
if (attrs) {
39433931
CustomAttr *globalActorAttr = nullptr;
39443932
Type globalActor = resolveGlobalActor(repr->getLoc(), parentOptions,
@@ -3996,6 +3984,18 @@ NeverNullType TypeResolver::resolveASTFunctionType(
39963984
auto params =
39973985
resolveASTFunctionTypeParams(repr->getArgsTypeRepr(), options, diffKind);
39983986

3987+
// Use parameter isolation if we have any. This overrides all other
3988+
// forms (and should cause conflict diagnostics).
3989+
if (hasIsolatedParameter(params)) {
3990+
isolation = FunctionTypeIsolation::forParameter();
3991+
3992+
if (isolatedAttr) {
3993+
diagnose(repr->getLoc(), diag::isolated_parameter_isolated_attr_type,
3994+
isolatedAttr->getIsolationKindName());
3995+
isolatedAttr->setInvalid();
3996+
}
3997+
}
3998+
39993999
auto resultOptions = options.withoutContext();
40004000
resultOptions.setContext(TypeResolverContext::FunctionResult);
40014001
auto outputTy = resolveType(repr->getResultTypeRepr(), resultOptions);
@@ -4891,14 +4891,18 @@ TypeResolver::resolveIsolatedTypeRepr(IsolatedTypeRepr *repr,
48914891
if (auto dynamicSelfType = dyn_cast<DynamicSelfType>(unwrappedType)) {
48924892
unwrappedType = dynamicSelfType->getSelfType();
48934893
}
4894+
// here
48944895

4895-
// isolated parameters must be of actor type
4896-
if (!unwrappedType->isTypeParameter() &&
4897-
!unwrappedType->isAnyActorType() &&
4898-
!unwrappedType->hasError()) {
4899-
diagnoseInvalid(
4900-
repr, repr->getSpecifierLoc(), diag::isolated_parameter_not_actor, type);
4901-
return ErrorType::get(type);
4896+
if (inStage(TypeResolutionStage::Interface)) {
4897+
if (auto *env = resolution.getGenericSignature().getGenericEnvironment())
4898+
unwrappedType = env->mapTypeIntoContext(unwrappedType);
4899+
4900+
if (!unwrappedType->isAnyActorType() && !unwrappedType->hasError()) {
4901+
diagnoseInvalid(
4902+
repr, repr->getSpecifierLoc(),
4903+
diag::isolated_parameter_not_actor, type);
4904+
return ErrorType::get(type);
4905+
}
49024906
}
49034907

49044908
return type;

test/Concurrency/isolated_parameters.swift

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ extension Actor {
2020
func testA<T: Actor>(
2121
a: isolated A, // expected-note{{previous 'isolated' parameter 'a'}}
2222
b: isolated T, // expected-warning{{cannot have more than one 'isolated' parameter; this is an error in Swift 6}}
23-
c: isolated Int // expected-error {{'isolated' parameter has non-actor type 'Int'}}
23+
c: isolated Int // expected-error {{'isolated' parameter type 'Int' does not conform to 'Actor' or 'DistributedActor'}}
2424
) {
2525
a.f()
2626
a.g()
@@ -350,14 +350,14 @@ func getValues(
350350
}
351351

352352
func isolated_generic_bad_1<T>(_ t: isolated T) {}
353-
// expected-error@-1 {{'isolated' parameter 'T' must conform to 'Actor' or 'DistributedActor' protocol}}
353+
// expected-error@-1 {{'isolated' parameter type 'T' does not conform to 'Actor' or 'DistributedActor'}}
354354
func isolated_generic_bad_2<T: Equatable>(_ t: isolated T) {}
355-
// expected-error@-1 {{'isolated' parameter 'T' must conform to 'Actor' or 'DistributedActor' protocol}}
355+
// expected-error@-1 {{'isolated' parameter type 'T' does not conform to 'Actor' or 'DistributedActor'}}
356356
func isolated_generic_bad_3<T: AnyActor>(_ t: isolated T) {}
357-
// expected-error@-1 {{'isolated' parameter 'T' must conform to 'Actor' or 'DistributedActor' protocol}}
357+
// expected-error@-1 {{'isolated' parameter type 'T' does not conform to 'Actor' or 'DistributedActor'}}
358358

359359
func isolated_generic_bad_4<T>(_ t: isolated Array<T>) {}
360-
// expected-error@-1 {{'isolated' parameter has non-actor type 'Array<T>'}}
360+
// expected-error@-1 {{'isolated' parameter type 'Array<T>' does not conform to 'Actor' or 'DistributedActor'}}
361361

362362
func isolated_generic_ok_1<T: Actor>(_ t: isolated T) {}
363363

@@ -473,3 +473,7 @@ func preciseIsolated(a: isolated MyActor) async {
473473
nonisolated func fromNonisolated(ns: NotSendable) async -> NotSendable {
474474
await pass(value: ns, isolation: nil)
475475
}
476+
477+
func invalidIsolatedClosureParam<A: AnyActor> (
478+
_: (isolated A) async throws -> Void // expected-error {{'isolated' parameter type 'A' does not conform to 'Actor' or 'DistributedActor'}}
479+
) {}

0 commit comments

Comments
 (0)