Bug 23626 – [REG2.096] Template deduction with auto const ref Args... and delegate

Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2023-01-14T16:54:03Z
Last change time
2023-01-16T01:29:49Z
Keywords
industry, pull, rejects-valid
Assigned to
No Owner
Creator
johanengelen
See also
https://issues.dlang.org/show_bug.cgi?id=21518, https://issues.dlang.org/show_bug.cgi?id=22186

Attachments

IDFilenameSummaryContent-TypeSize
1865template_bug.zipFiles to reproduce the bugapplication/zip2093

Comments

Comment #0 by johanengelen — 2023-01-14T16:54:03Z
Created attachment 1865 Files to reproduce the bug It's unfortunate, i spent a lot of time reducing this to a manageable test case, but it is still 4 files. Compiles with DMD 2.095.1, fails with 2.096.1, fails with different error with 2.100.0. > /Users/johan/dcompilers/dmd-2.095.1/osx/bin/dmd -o- -c static_hash.d space_reclaimer.d tiering_policies.d Succes. /Users/johan/dcompilers/dmd-2.096.1/osx/bin/dmd -o- -c static_hash.d space_reclaimer.d tiering_policies.d Errors: space_reclaimer.d(35): Error: template `tracing.__trace_maybeDumpTupleToFile` cannot deduce function from argument types `!()(void delegate() nothrow @nogc @system)`, candidates are: tracing.d(5): `__trace_maybeDumpTupleToFile(Args...)(auto ref const Args args)` space_reclaimer.d(39): Error: template instance `space_reclaimer.ReclamationBatch.func_2!(void delegate() nothrow @nogc @system)` error instantiating /Users/johan/dcompilers/dmd-2.100.0/osx/bin/dmd -o- -c static_hash.d space_reclaimer.d tiering_policies.d Errors: space_reclaimer.d(35): Error: none of the overloads of template `tracing.__trace_maybeDumpTupleToFile` are callable using argument types `!()(void delegate() nothrow @nogc @system)` tracing.d(5): Candidate is: `__trace_maybeDumpTupleToFile(Args...)(auto const ref Args args)` space_reclaimer.d(39): Error: template instance `space_reclaimer.ReclamationBatch.func_2!(void delegate() nothrow @nogc @system)` error instantiating Files: static_hash.d ``` module static_hash; struct StaticHashTable(V) { V v ; } ``` space_reclaimer.d ``` import tracing; auto as(Func)(Func) {} @nogc void foo() { } void assertOp(string OPERATION, LHS, RHS)(LHS lhs, RHS) { as({ try { try as(lhs); catch(Throwable) foo(); } catch(Throwable) assert(false); }); } struct FixedArray(T, size_t capacity_) { int a = getStructInfoEx!FixedArray; T* some_function() { assertOp !""(1, 1); return null; } alias some_function this; } struct ReclamationBatch { FixedArray !(uint,1) dummy; @nogc nothrow void some_inout_func() inout { } void func_2(Dlg)(Dlg dlg) { __trace_maybeDumpTupleToFile(dlg); } void _reclaimBatch() { func_2({ some_inout_func; }); } } ``` tiering_policies.d ``` interface Timeline { } struct Policy { alias OldTagCallback = void delegate() @nogc nothrow; Timeline timeline; OldTagCallback oldTagCB; } import static_hash; struct Tiering { StaticHashTable!(Policy) policies; } ``` tracing.d ``` import std.traits : fullyQualifiedName; void __trace_maybeDumpTupleToFile(Args...)(auto ref const Args args) nothrow @nogc { } int getStructInfoEx(T)() { enum Ctx = fullyQualifiedName!T; return 0; } ```
Comment #1 by johanengelen — 2023-01-14T16:58:46Z
This frontend change "fixes" the errors (3 lines removed): diff dmd/mtype.d: ``` /** Extends TypeNext.constConv by also checking for matching attributes **/ override MATCH constConv(Type to) { - // Attributes need to match exactly, otherwise it's an implicit conversion - if (this.ty != to.ty || !this.attributesEqual(cast(TypeFunction) to)) - return MATCH.nomatch; ```
Comment #2 by ibuclaw — 2023-01-14T17:43:02Z
(In reply to johanengelen from comment #1) > This frontend change "fixes" the errors (3 lines removed): > diff dmd/mtype.d: > ``` > /** Extends TypeNext.constConv by also checking for matching attributes > **/ > override MATCH constConv(Type to) > { > - // Attributes need to match exactly, otherwise it's an implicit > conversion > - if (this.ty != to.ty || !this.attributesEqual(cast(TypeFunction) > to)) > - return MATCH.nomatch; > ``` Those three lines come from https://github.com/dlang/dmd/pull/12090 which was first released in v2.096.0. This conveniently fits your timeline, so is a possible introducer of the regression.
Comment #3 by ibuclaw — 2023-01-14T18:31:30Z
FYI, `import std.traits;` can be replaced with --- template fullyQualifiedName(T...) { enum fullyQualifiedName = !T[0]; } --- To remove all phobos dependencies.
Comment #4 by ibuclaw — 2023-01-14T18:53:48Z
(In reply to johanengelen from comment #0) > void func_2(Dlg)(Dlg dlg) { > __trace_maybeDumpTupleToFile(dlg); > } Just a suggestion, should this be `const Dlg` instead?
Comment #5 by ibuclaw — 2023-01-14T19:24:41Z
Still 3 files, but one possible reduction. space_reclaimer.d ``` void __trace_maybeDumpTupleToFile(Args)(ref const Args ) { } auto as(Func)(Func) {} @nogc void foo() { } void assertOp(LHS)(LHS lhs) { as({ try { try as(lhs); catch(Throwable) foo; } catch(Throwable) assert(false); }); } struct FixedArray(T) { int a = !FixedArray; T* some_function() { assertOp(1); return null; } alias some_function this; } struct ReclamationBatch { FixedArray!(uint) dummy; @nogc nothrow void some_inout_func() { } void func_2(Dlg)(Dlg dlg) { __trace_maybeDumpTupleToFile(dlg); } void _reclaimBatch() { func_2({ some_inout_func; }); } } ``` tiering_policies.d ``` interface Timeline { } struct Policy { alias OldTagCallback = void delegate() @nogc nothrow; Timeline timeline; OldTagCallback oldTagCB; } import static_hash; struct Tiering { StaticHashTable!(Policy) policies; } ``` static_hash.d ``` struct StaticHashTable(V) { V v; } ``` ------------------------------------ Bonus source file, a minimal object.d to also rule out druntime. ``` module object; alias size_t = ulong; class Object { } class TypeInfo { size_t getHash(const void* ) nothrow { } } class TypeInfo_Const : TypeInfo { } class Throwable { } bool _xopEquals() { } ```
Comment #6 by dlang-bot — 2023-01-14T23:06:35Z
@ibuclaw created dlang/dmd pull request #14818 "fix Issue 23626 - [REG2.096] Template deduction with auto const ref Args... and delegate" fixing this issue: - fix Issue 23626 - [REG2.096] Template deduction with auto const ref Args... and delegate https://github.com/dlang/dmd/pull/14818
Comment #7 by dlang-bot — 2023-01-15T16:57:49Z
dlang/dmd pull request #14818 "fix Issue 23626 - [REG2.096] Template deduction with auto const ref Args... and delegate" was merged into stable: - ca530908ce1ce07d52f0c90aaa5f3824cbc7816e by Iain Buclaw: fix Issue 23626 - [REG2.096] Template deduction with auto const ref Args... and delegate https://github.com/dlang/dmd/pull/14818
Comment #8 by dlang-bot — 2023-01-15T20:36:57Z
dlang/dmd pull request #14823 "merge stable" was merged into master: - 815eb678c704470d190fc63579428d481bf55063 by Iain Buclaw: fix Issue 23626 - [REG2.096] Template deduction with auto const ref Args... and delegate https://github.com/dlang/dmd/pull/14823
Comment #9 by dlang-bot — 2023-01-16T01:29:49Z
dlang/dmd pull request #14821 "follow-up Issue 23626 - invert trustSystemEqualsDefault initializer to true" was merged into master: - c111eaedcdbe6b4a7da372e2b05cca1cbac4b677 by Iain Buclaw: follow-up Issue 23626 - invert trustSystemEqualsDefault initializer to true This is the desired behaviour for any future users of this function. https://github.com/dlang/dmd/pull/14821