Bug 15425 – std.traits.hasIndirections fails to recognize nested structs

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2015-12-08T21:55:13Z
Last change time
2021-09-14T14:22:54Z
Keywords
pull
Assigned to
No Owner
Creator
Marc Schütz

Comments

Comment #0 by schuetzm — 2015-12-08T21:55:13Z
import std.traits; void foo() { static struct S1 { long a; void bar() { } } struct S2 { long a; void bar() { } } pragma(msg, S1.sizeof); // 8LU static assert(!hasIndirections!S1); // succeeds pragma(msg, S2.sizeof); // 16 LU static assert(hasIndirections!S2); // fails } The larger size of S2 clearly shows that the context pointer is included. (Other functions in std.traits, like hasUnsharedAliasing, may need to be fixed, too.)
Comment #1 by razvan.nitu1305 — 2017-08-31T12:17:50Z
Maybe I am getting this wrong, but both S1 and S2 are free of indirections for as far as I can tell. Even if the sizeof includes the context pointer, it is not a user defined part of the struct. hasIndirections does the following for structs: static if (is(T == struct) || is(T == union)) enum hasIndirections = anySatisfy!(.hasIndirections, FieldTypeTuple!T); As you can see, all the field types are tested (the context pointer is not an actual field of the struct), so in my opinion the output of your program is correct.
Comment #2 by schuetzm — 2017-08-31T14:58:22Z
(In reply to RazvanN from comment #1) > Maybe I am getting this wrong, but both S1 and S2 are free of indirections > for as far as I can tell. Even if the sizeof includes the context pointer, > it is not a user defined part of the struct. > > hasIndirections does the following for structs: > > static if (is(T == struct) || is(T == union)) > enum hasIndirections = anySatisfy!(.hasIndirections, FieldTypeTuple!T); > > As you can see, all the field types are tested (the context pointer is not > an actual field of the struct), so in my opinion the output of your program > is correct. hasIndirections is used (among other things) to check whether a memory allocation needs to be registered with the GC (e.g. in RefCounted), or whether an object can be safely sent to another thread (e.g. hasUnsharedAliasing). For these purposes, it is crucial that it checks _all_ indirections, not just the explicitly declared ones. In std.traits, there is a whole bunch of helper traits like hasRawAliasing, hasRawUnsharedAliasing, hasAliasing with partially overlapping functionality. I don't know what each one is supposed to be used for; maybe hasIndirections actually does what it should. But if so, then it's clearly used wrongly in other places (e.g. RefCounted).
Comment #3 by dlang-bot — 2020-11-17T20:59:43Z
@n8sh created dlang/phobos pull request #7696 "Fix Issue 15425 - std.traits.hasIndirections fails to recognize nested structs" fixing this issue: - Fix Issue 15425 - std.traits.hasIndirections fails to recognize nested structs https://github.com/dlang/phobos/pull/7696
Comment #4 by dlang-bot — 2020-11-18T00:50:33Z
dlang/phobos pull request #7696 "Fix Issue 15425 - std.traits.hasIndirections fails to recognize nested structs" was merged into master: - d6c0c3430ae2faead57bae19ab76488eca0ece64 by Nathan Sashihara: Fix Issue 15425 - std.traits.hasIndirections fails to recognize nested structs https://github.com/dlang/phobos/pull/7696
Comment #5 by dlang-bot — 2021-09-14T14:22:54Z
dlang/druntime pull request #3568 "Backport Fix Issue 15425 to druntime" was merged into master: - 89e206333d10c3b224951a088c6bf34f06ac3d04 by RazvanN7: Backport Fix Issue 15425 to druntime https://github.com/dlang/druntime/pull/3568