How to properly reference a type and module with the same name?

I haven't yet "learned" to shy away from the apparent complication of making a swift module that has a struct with the exact same name as the module. Prior to swift 5.6, I found that if I referenced the name with ``ModuleName`` as the symbol in the module documentation, it renders acceptably, and I could still reference the underlying struct with the same name using the symbols reference from the module down to the struct ``ModuleName/StructName``.

As a specific example: ``CameraControlARView`` is the name of the module, and when I want to reference the struct that has the same name, I use ``CameraControlARView/CameraControlARView``.

WIth Swift 5.6 released (using Xcode Version 13.3 (13E113)), I went to rebuild the docs and noticed a warning in that top-level documentation file for the module:
Redeclaration of ''; this file will be skipped. While file it regarded as duplicate also seemed to change (sometimes the module, sometimes the struct) when I was invoking the build through Xcode.

Is there a "right way" to handle the scenario where I have a symbol with the same name as the module? (aside from never using a struct or class with the same name as your module?)

Hi Joseph!

This should still hold true in Swift 5.6.

I think you're seeing this because there are two files in your DocC catalog named

Because articles in Swift-DocC are linked to via their file name (not file path), docc raises an error upon encountering multiple articles with the same name. However, in your case, you have two documentation extensions with the same file name so I don't think this should cause an error - I would view this is a bug in Swift-DocC's diagnostics.

As a workaround, you could name the second documentation extension something like and I think you'll see that diagnostic go away. But a bug on for documentation extensions with equal file names would be great as well.

- Ethan


Ahh!! thank you @ethankusters - I'd never made the mental link that an extension page was basically mapped identically to articles since they're called separate things in the templates. As you suggested, renaming the extension page worked perfectly and resolved the warning scenario.


is there a reason the explicit module name is required?

(Not sure if I'm quite understanding what you're asking)

For the top-level module documentation in the catalog, I think the symbol that matched the module name was required. Without it in place, regardless of the name of the file itself, the content isn't mapped to match the top level of the documentation. (for example, in CameraControlARView/ at main · heckj/CameraControlARView · GitHub if you clip out line 1 and build the docs, the module will appear in the docs as a "No overview available".

1 Like

oh, got it. swift-biome uses package names to solve this problem. right now, every package in the biome starts with swift-, and the hyphen cannot appear in a swift identifier, so it is unambiguous. at some point i’m planning on migrating to an “absolute path” scheme where /foomodule always stands for FooModule.

Makes sense - and I've seen a number of projects have that pattern - especially when they're supporting more than one language (automerge-swift comes to mind), or just have a different name for the module than anything within that module. I knew it was supported, but I completely recognize that I made things harder on myself by not having a different module name for this quickie thing.

1 Like

for what it’s worth, swift-json, swift-grammar, swift-png, and jpeg all have this problem too. it’s more of a problem for jpeg because it doesn’t have the swift- prefix.

this is part of the reason i’m putting so much effort into swift-biome’s URI resolution algorithm.

coming back to this, isn’t this behavior the opposite of how name resolution usually works in swift?

import Foo

// error: 'Foo' is not a member type of enum 'Foo.Foo'
var foo:Foo.Foo 

moreover, if the module Foo contains a type named Foo, it should also be impossible to reference any of the other symbols in Foo with a module-qualified name:

import Foo

// error: 'Bar' is not a member type of enum 'Foo.Foo'
var bar:Foo.Bar