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.
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.
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.
*** Issue 11595 has been marked as a duplicate of this issue. ***
@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
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