diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 28a1b9ed17ba1..d57a7b3ed3b0e 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -4566,6 +4566,10 @@ ERROR(concurrent_access_of_local_capture,none, "%select{mutation of|reference to}0 captured %1 %2 in " "concurrently-executing code", (bool, DescriptiveDeclKind, DeclName)) +ERROR(concurrent_access_of_inout_param,none, + "mutable capture of 'inout' parameter %0 is not allowed in " + "concurrently-executing code", + (DeclName)) ERROR(non_sendable_capture,none, "capture of %1 with non-sendable type %0 in a `@Sendable` closure", (Type, DeclName)) diff --git a/lib/Sema/TypeCheckConcurrency.cpp b/lib/Sema/TypeCheckConcurrency.cpp index 69028eaa81af0..1d5be53dc479b 100644 --- a/lib/Sema/TypeCheckConcurrency.cpp +++ b/lib/Sema/TypeCheckConcurrency.cpp @@ -2553,6 +2553,13 @@ namespace { return false; } + if (auto param = dyn_cast(value)){ + if(param->isInOut()){ + ctx.Diags.diagnose(loc, diag::concurrent_access_of_inout_param, param->getName()); + return true; + } + } + // Otherwise, we have concurrent access. Complain. ctx.Diags.diagnose( loc, diag::concurrent_access_of_local_capture, diff --git a/test/Concurrency/async_tasks.swift b/test/Concurrency/async_tasks.swift index 63f01b2897966..1201386a09eba 100644 --- a/test/Concurrency/async_tasks.swift +++ b/test/Concurrency/async_tasks.swift @@ -128,3 +128,12 @@ func test_detached_throwing() async -> String { print("caught: \(error)") } } + +// ==== Detached Tasks with inout Params--------------------------------------- +@available(SwiftStdlib 5.1, *) +func printOrderNumber(n: inout Int) async { + Task.detached { + n+=1 //expected-error {{mutable capture of 'inout' parameter 'n' is not allowed in concurrently-executing code}} + print(n) //expected-error {{mutable capture of 'inout' parameter 'n' is not allowed in concurrently-executing code}} + } +} diff --git a/test/Concurrency/taskgroup_cancelAll_from_child.swift b/test/Concurrency/taskgroup_cancelAll_from_child.swift index 11dd5a7683014..cf065c0e373e0 100644 --- a/test/Concurrency/taskgroup_cancelAll_from_child.swift +++ b/test/Concurrency/taskgroup_cancelAll_from_child.swift @@ -13,7 +13,8 @@ func test_taskGroup_cancelAll() async { group.spawn { group.cancelAll() //expected-warning{{capture of 'group' with non-sendable type 'TaskGroup' in a `@Sendable` closure}} - //expected-error@-1{{reference to captured parameter 'group' in concurrently-executing code}} + //expected-error@-1{{mutable capture of 'inout' parameter 'group' is not allowed in concurrently-executing code}} + return 0 } group.spawn { [group] in