Bug 20008 – __traits(allMembers) of packages is complete nonsense

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2019-06-26T11:33:20Z
Last change time
2023-06-27T06:45:08Z
Keywords
pull
Assigned to
No Owner
Creator
FeepingCreature
See also
https://issues.dlang.org/show_bug.cgi?id=19590

Comments

Comment #0 by default_357-line — 2019-06-26T11:33:20Z
Consider this code: https://run.dlang.io/is/ANydDv import std.meta; void main() { alias module_ = __traits(parent, main); static assert(anySatisfy!(isSame!main, allMembers!module_)); static assert(anySatisfy!(isSame!std, allMembers!module_)); pragma(msg, __traits(allMembers, std)); // static assert(anySatisfy!(isSame!(std.meta), allMembers!std)); } alias allMembers(alias Sym) = staticMap!(getMember!Sym, __traits(allMembers, Sym)); template getMember(alias Sym) { alias getMember(string ident) = __traits(getMember, Sym, ident); } template isSame(alias Sym1) { enum isSame(alias Sym2) = __traits(isSame, Sym1, Sym2); } As can be seen by the pragma(msg) and the spectacular errors when you comment in the commented-out line, the contents of __traits(allMembers, std) are not at all things that can be written in the form "std.<member>". Expected: tuple("meta") Got: tuple("object", "AliasSeq", "Alias", "OldAlias", "staticIndexOf", "genericIndexOf", "Erase", "GenericErase", "EraseAll", "GenericEraseAll", "EraseAllN", "NoDuplicates", "Replace", "GenericReplace", "ReplaceAll", "GenericReplaceAll", "Reverse", "MostDerived", "DerivedToFront", "staticMap", "allSatisfy", "anySatisfy", "Filter", "templateNot", "templateAnd", "templateOr", "aliasSeqOf", "ApplyLeft", "ApplyRight", "SmartAlias", "Repeat", "staticSort", "staticMerge", "isLessEq", "staticIsSorted", "Stride", "Instantiate", "isSame", "expectType", "expectBool", "Pack") This means it is still impossible to walk all transitive imports.
Comment #1 by b2.temp — 2020-08-25T04:16:28Z
One problem is that "std" as member of the module is actually "std.meta". It appears like that by accident and could lead to what I call symbol leaks. The allmembers traits actually always takes the ident of a symbol but for imports this should be a FQN.
Comment #2 by b2.temp — 2020-08-25T04:47:12Z
with the patch for the FQN in allMembers, this code --- void allMembers(string p)() { alias P = mixin(p); static if (is(P == module) || is(P == package)) { enum members = [__traits(allMembers, P)]; pragma(msg, p, " ", members); static foreach (m; members) static if (m != "object") static if (is(mixin(m) == module) || is(mixin(m) == package)) allMembers!(m); } } import std.algorithm; void main(string[] args) { allMembers!("std.algorithm"); } --- outputs: --- std.algorithm ["object", "std.algorithm.comparison", "std.algorithm.iteration", "std.algorithm.mutation", "std.algorithm.searching", "std.algorithm.setops", "std.algorithm.sorting", "std.functional"] std.algorithm.comparison ["object", "std.functional", "std.range.primitives", "std.traits", "std.meta", "std.typecons", "std.internal.attributes", "among", "indexOfFirstOvershadowingChoiceOnLast", "castSwitch", "clamp", "cmp", "equal", "MaxType", "EditOp", "Levenshtein", "levenshteinDistance", "levenshteinDistanceAndPath", "max", "MinType", "min", "mismatch", "predSwitch", "isSameLength", "AllocateGC", "isPermutation", "either"] std.algorithm.iteration ["object", "std.functional", "std.range.primitives", "std.traits", "std.typecons", "aggregate", "cache", "cacheBidirectional", "_Cache", "map", "MapResult", "each", "filter", "FilterResult", "filterBidirectional", "FilterBidiResult", "group", "Group", "ChunkByChunkImpl", "ChunkByImplIsUnary", "ChunkByImpl", "chunkBy", "joiner", "reduce", "ReduceSeedType", "fold", "cumulativeFold", "splitter", "SplitterResult", "hasDifferentAutodecoding", "substitute", "sum", "sumPairwise", "sumPairwise16", "sumPair", "sumPairwiseN", "sumKahan", "mean", "uniq", "UniqResult", "permutations", "Permutations"] std.algorithm.mutation ["object", "std.range.primitives", "std.traits", "std.meta", "std.typecons", "bringToFront", "bringToFrontImpl", "areCopyCompatibleArrays", "copy", "fill", "initializeAll", "move", "moveImpl", "trustedMoveImpl", "moveEmplaceImpl", "moveEmplace", "moveAll", "moveEmplaceAll", "moveAllImpl", "moveSome", "moveEmplaceSome", "moveSomeImpl", "SwapStrategy", "isValidIntegralTuple", "remove", "removeImpl", "removeUnstable", "removeStable", "removeStableString", "removePredUnstable", "removePredStable", "removePredString", "reverse", "strip", "stripLeft", "stripRight", "swap", "swapAt", "swapFront", "swapRanges", "uninitializedFill"] std.algorithm.searching ["object", "std.functional", "std.range.primitives", "std.traits", "std.typecons", "all", "any", "balancedParens", "BoyerMooreFinder", "boyerMooreFinder", "commonPrefix", "count", "countUntil", "endsWith", "hasConstEmptyMember", "RebindableOrUnqual", "extremum", "find", "simpleMindedFind", "canFind", "findAdjacent", "findAmong", "findSkip", "findSplit", "findSplitBefore", "findSplitAfter", "minCount", "maxCount", "minElement", "maxElement", "minPos", "maxPos", "minIndex", "maxIndex", "skipOver", "startsWith", "skipAll", "OpenRight", "until", "Until"] std.algorithm.setops ["object", "std.range.primitives", "std.functional", "std.traits", "std.meta", "std.algorithm.sorting", "std.typecons", "cartesianProduct", "largestPartialIntersection", "std.algorithm.sorting", "largestPartialIntersectionWeighted", "MultiwayMerge", "multiwayMerge", "nWayUnion", "NWayUnion", "multiwayUnion", "SetDifference", "setDifference", "SetIntersection", "setIntersection", "SetSymmetricDifference", "setSymmetricDifference"] std.algorithm.sorting ["object", "std.algorithm.mutation", "std.functional", "std.range.primitives", "std.typecons", "std.meta", "std.range", "std.traits", "SortOutput", "completeSort", "isSorted", "isStrictlyMonotonic", "ordered", "strictlyOrdered", "partition", "pivotPartition", "isPartitioned", "partition3", "makeIndex", "Merge", "merge", "validPredicates", "multiSort", "multiSortPredFun", "multiSortImpl", "getPivot", "shortSort", "trustedMoveEmplace", "sort5", "sort", "quickSortImpl", "HeapOps", "TimSortImpl", "schwartzSort", "partialSort", "topN", "topNImpl", "topNPartition", "p3", "p4", "topNPartitionOffMedian", "expandPartition", "topNCopy", "topNIndex", "medianOf", "nextPermutation", "nextEvenPermutation", "nthPermutation", "nthPermutationImpl"] --- but apparently not all imports are handled.. for example std.typecons has not its line.
Comment #3 by dkorpel — 2022-09-29T14:23:21Z
*** Issue 11595 has been marked as a duplicate of this issue. ***
Comment #4 by dlang-bot — 2023-06-20T22:17:21Z
@dkorpel created dlang/dmd pull request #15335 "Fix 20008 - __traits(allMembers) of packages is complete nonsense" fixing this issue: - Fix 20008 - __traits(allMembers) of packages is complete nonsense https://github.com/dlang/dmd/pull/15335
Comment #5 by dlang-bot — 2023-06-27T06:45:08Z
dlang/dmd pull request #15335 "Fix 20008 - __traits(allMembers) of packages is complete nonsense" was merged into master: - cf7ac3326918c83ca819ee061b2f65f6fbf0de63 by Dennis Korpel: Fix 20008 - __traits(allMembers) of packages is complete nonsense https://github.com/dlang/dmd/pull/15335