Bug 22210 – std.meta.allSatisfy in mutual recursion classes cannot be compiled
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
druntime
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2021-08-14T09:53:02Z
Last change time
2021-11-12T09:44:18Z
Assigned to
No Owner
Creator
Tomoya Tanjo
Comments
Comment #0 by ttanjo — 2021-08-14T09:53:02Z
The following code works with dmd 2.096.1 but does not work with dmd 2.097.0.
Digger shows that it was introduced by the commit 406e51c68 in druntime.
run.dlang.io: https://run.dlang.io/is/Ot8L6n
```dlang:sample.d
import std.meta : allSatisfy;
enum isHashable(T) = __traits(compiles,
() { T.init; }
);
class A
{
static if (isHashable!B) {}
}
class B
{
static if (isHashable!C) {}
}
class C
{
static if (allSatisfy!(isHashable, int, B)) {}
}
void main() {}
```
Error message:
```console
/dlang/dmd/linux/bin64/../../src/druntime/import/core/internal/traits.d(191): Error: forward reference of variable `isHashable`
/dlang/dmd/linux/bin64/../../src/phobos/std/meta.d(842): Error: template instance `core.internal.traits.allSat!(isHashable, int, B)` error instantiating
onlineapp.d(19): instantiated from here: `allSatisfy!(isHashable, int, B)`
onlineapp.d(14): Error: template instance `onlineapp.isHashable!(C)` error instantiating
onlineapp.d(9): Error: template instance `onlineapp.isHashable!(B)` error instantiating
```
I use the following commands to search for the commit that introduces this issue:
```console
$ cat bisect.ini
bad = master @ v2.097.0
good = master @ v2.096.1
reverse = false
tester = dmd -i -run sample.d
$ dub run digger -- bisect bisect.ini
...
digger: c717e2eda7063a583ada54182f3016139a50a61f is the first bad commit
commit c717e2eda7063a583ada54182f3016139a50a61f
Author: Andrei Alexandrescu <[email protected]>
Date: Tue May 4 15:45:09 2021 -0400
druntime: Simplify anySatisfy, allSatisfy, maxAlignment
diff --git a/druntime b/druntime
index 5cfc074f7..406e51c68 160000
--- a/druntime
+++ b/druntime
@@ -1 +1 @@
-Subproject commit 5cfc074f73d2087841e66871cd859946ba14003a
+Subproject commit 406e51c68c94a65e383da5aaa500c17d0a9c4d0e
```
- If we use `isHashable!int && isHashable!B` instead of `allSatisfy!(isHashable, int, B)`, it works with both of dmd 2.096.1 and dmd 2.097.0.
- If we use `isHashable!B && isHashable!int` instead of `allSatisfy!(isHashable, int, B)`, it is the case of Issue 22184 (does not work with both versions)
Comment #1 by ttanjo — 2021-10-27T04:27:53Z
I found that it works if I changed the order of declaration to B, C and A as follows.
Therefore the source of this issue is issue 20443, I guess.
```dlang:sample.d
import std.meta : allSatisfy;
enum isHashable(T) = __traits(compiles,
() { T.init; }
);
class B
{
static if (isHashable!C) {}
}
class C
{
static if (allSatisfy!(isHashable, int, B)) {}
}
class A
{
static if (isHashable!B) {}
}
void main() {}
```
Comment #2 by dlang-bot — 2021-11-10T03:19:35Z
@tom-tan created dlang/druntime pull request #3618 "Fix issue 22210 - Revert #3459 and #3463" mentioning this issue:
- Add test for issue 22210
https://github.com/dlang/druntime/pull/3618
Comment #3 by dlang-bot — 2021-11-12T08:42:58Z
dlang/druntime pull request #3618 "Fix issue 22210 - Partially revert #3459 and #3463" was merged into stable:
- 9d0a29a896b924030b5aaec92b89ad82437865fd by Tomoya Tanjo:
Add test for issue 22210
https://github.com/dlang/druntime/pull/3618