Largest scope in which a mangled symbol name (USR) is unique?

i’m currently working on combined package-wide symbolgraphs, and one of the issues i’m running aground on is the validity of USRs at the package-wide level.

USRs do not encode package or product name, they only encode module name. so local USRs are inherently unique across a package, since local modules cannot have name collisions.

but foreign USRs present a problem, because in theory we should be able to build targets that depend on modules that have name collisions with each other at the package-wide level, as long as colliding modules are never linked together in the same target.


  • TargetA depends on product(name: "Utils", package: "swift-a")
  • TargetB depends on product(name: "Utils", package: "swift-b")

USRs originating from the two Utils modules are therefore ambiguous at the package-wide level.

now, SPM currently does not support this use case, but this always struck me as a limitation of SPM, and the module aliasing workaround presents challenges particular to documentation, because we cannot catalog relationships between symbols if they do not have a fixed identifier.


  • TargetA.ExampleType conforms to _AUtils.AliasedProtocol
  • but _AUtils.AliasedProtocol does not exist! it is called Utils.AliasedProtocol!


1 Like

As we expand the scope that Swift-DocC can work in to include whole packages instead of singular modules, perhaps we should stop relying on USRs as the only mechanism of symbol identification. :thinking: I wonder if we could get away with making Swift-DocC consider the module of a symbol as well as its "unique identifier", for the purposes of deduplication. In SymbolKit this is basically what happens in the GraphCollector type, since individual symbol graphs are first separated by module name. This would have to take the "module aliasing" problem into account, though.

i’m not sure how this design is different from what we have currently; USRs already encode module name. can you elaborate?

Ah, you're right; i misunderstood the problem. We'd need to add another kind of disambiguator that comes from outside the symbol graph itself.

1 Like

The DocC catalog bundle identifier can be used to globally disambiguate above the module level, but it's never been exposed well–you have to create a somewhat esoteric Info.plist file to define it.

I think ideally disambiguation could come from extra bits folks will need to provide anyway for other cross-module linking/hosting features, like the url prefix.