Skip to content

Commit

Permalink
Fix Bugzilla 14138 - std.parallelism.task breaks @safety
Browse files Browse the repository at this point in the history
  • Loading branch information
ntrel committed Jul 28, 2024
1 parent c00a5ee commit 1ca9f47
Showing 1 changed file with 17 additions and 2 deletions.
19 changes: 17 additions & 2 deletions std/parallelism.d
Original file line number Diff line number Diff line change
Expand Up @@ -884,11 +884,26 @@ identical to the non-@safe case, but safety introduces some restrictions:
*/
@trusted auto task(F, Args...)(F fun, Args args)
if (is(typeof(fun(args))) && isSafeTask!F)
if (__traits(compiles, () @safe => fun(args)) && isSafeTask!F)
{
return new Task!(run, F, Args)(fun, args);
}

@safe unittest
{
static struct Oops {
int convert() {
*cast(int*)0xcafebabe = 0xdeadbeef;
return 0;
}
alias convert this;
}
static void foo(int) @safe {}

static assert(!__traits(compiles, task(&foo, Oops.init)));
static assert(!__traits(compiles, scopedTask(&foo, Oops.init)));
}

/**
These functions allow the creation of `Task` objects on the stack rather
than the GC heap. The lifetime of a `Task` created by `scopedTask`
Expand Down Expand Up @@ -928,7 +943,7 @@ if (is(typeof(delegateOrFp(args))) && !isSafeTask!F)

/// Ditto
@trusted auto scopedTask(F, Args...)(F fun, Args args)
if (is(typeof(fun(args))) && isSafeTask!F)
if (__traits(compiles, () @safe => fun(args)) && isSafeTask!F)
{
auto ret = Task!(run, F, Args)(fun, args);
ret.isScoped = true;
Expand Down

0 comments on commit 1ca9f47

Please sign in to comment.