Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions compiler/src/dmd/templatesem.d
Original file line number Diff line number Diff line change
Expand Up @@ -7183,6 +7183,19 @@ MATCH deduceType(scope RootObject o, scope Scope* sc, scope Type tparam,
return;
}

// https://github.com/dlang/dmd/issues/19718
// The argument's safety must satisfy what the parameter type requires;
// an @system (or unmarked) function/delegate cannot match an @safe or
// @trusted parameter type. Without this check, template argument
// deduction only compares parameter lists and ignores the function's
// own attributes, so an unsafe argument can be wrongly deduced to
// match an @safe (or stronger) parameter type.
if (t.trust <= TRUST.system && tp.trust >= TRUST.trusted)
{
result = MATCH.nomatch;
return;
}

foreach (fparam; *tp.parameterList.parameters)
{
// https://issues.dlang.org/show_bug.cgi?id=2579
Expand Down
27 changes: 27 additions & 0 deletions compiler/test/fail_compilation/test19718.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
TEST_OUTPUT:
---
fail_compilation/test19718.d(27): Error: none of the overloads of template `test19718.execute` are callable using argument types `!()(int function(ref Struct rng) @system)`
fail_compilation/test19718.d(15): Candidates are: `execute(T)(T function(ref Struct) @safe dg)`
fail_compilation/test19718.d(21): `execute(T)(T delegate(ref Struct) @safe dg)`
---
*/

struct Struct
{
int get() { return 1; }
}

public T execute (T)(T function(ref Struct) @safe dg)
{
Struct rng;
return dg(rng);
}

public T execute (T)(T delegate(ref Struct) @safe dg)
{
Struct rng;
return dg(rng);
}

auto x = execute((ref Struct rng) { return rng.get(); });
Loading