Codelinks

Codelinks, also known as symbol links, are a Markdown shorthand for referencing Swift declarations in documentation. Documentation engines will automatically resolve and expand these references into hyperlinks to the corresponding symbols.

Codelinks.md

You write codelinks using double backticks. Here are some examples:

``Int``
``String``
``String.Index``

A Swift documentation engine, such as Unidoc or DocC, can resolve and render these codelinks like this:

Int String String.Index

But in a regular Markdown viewer, they will just look like this:

Int String String.Index

Displaying part of a declaration’s name

Use the slash character (/) in place of the period (.) separator to mark where you want the visible portion of a declaration’s name to begin.

SyntaxRenders as
``String.Index``String.Index
``String/Index``Index

Readers using a regular Markdown viewer will see the entire path, but documentation engines will only display the specified path suffix.

Linking to functions and subscripts

If you want to link to a specific function or subscript, you must include all of the function’s argument labels (including defaulted arguments), appending a colon (:) after each label, including the last one.

SyntaxRenders as
``String.init(decoding:as:)``String.init(decoding:as:)

If the function takes no arguments, you can omit the parentheses.

SyntaxRenders as
``Sequence.max``Sequence.max

However, you can add the parentheses anyway to exclude properties (and much more rarely, types) as possible matches.

Linking to operators

To link to an operator, spell it as-is, without replacing or escaping any special characters.

SyntaxRenders as
``Int.+(_:_:)``Int.+(_:_:)
``Int./(_:_:)``Int./(_:_:)
``Comparable....(_:_:)``Comparable....(_:_:)

Linking to types

When linking to types, don’t include the generic parameters.

SyntaxRenders as
``Array``Array
``Dictionary``Dictionary

Linking to modules

You can link to a module by using the module’s name.

SyntaxRenders as
``Foundation``Foundation

Relative and absolute paths

Documentation that is attached to a declaration (such as an inline doccomment) can omit leading components of the codelink path.

For example, if you are documenting a type named Heap.Index that contains a property named offset, you can use all of the following to refer to the property:

``offset``
``Index/offset``
``Heap.Index/offset``

Matches that appear lexically closer to the declaration will take precedence over those from outer scopes.

Qualifying with module names

You can prepend a module name to a codelink to fully qualify it.

SyntaxRenders as
``_Concurrency.AsyncStream``_Concurrency.AsyncStream
``_Concurrency/AsyncStream``AsyncStream

If a module re-exports a declaration from another module, you can use the re-exporting module’s name in place of the original module’s name.

Using absolute paths

You can prepend a slash character (/) to a codelink to force it to resolve from the root of the package hierarchy.

SyntaxRenders as
``/Swift.Int``Swift.Int
``/Swift/Int``Int

This is useful if a module contains a type with the same name as the module itself.

Disambiguation filters

If a codelink is ambiguous, you add disambiguation filters in brackets ([]) after the codelink.

Filtering by phylum

You can filter a codelink by phylum to disambiguate it. For example, if you have a static and an instance property with the same name, you can use [static var] or [var] to specify which one you want.

public
struct Example
{
    public
    let property:Int = 0

    public
    static let property:Int = 1
}
Codelinks.swift
SyntaxRenders as
``Example.property [var]``Example.property
``Example.property [static var]``Example.property

Alternatively, you can replace the spaces with hyphens (-) to encode the codelink with URL-friendly characters. This is useful when you want to display custom link text.

SyntaxRenders as
[custom text](Example.property-[var])custom text
[custom text](Example.property-[static-var])custom text

Below is an exhaustive list of all supported phylum filters.

DisambiguatorNotes
[actor]
[associatedtype]
[enum]
[case]
[class]Matches non-actor classes only.
[class func]
[class subscript]
[class var]
[deinit]
[func]Also matches global operators and functions.
[init]
[macro]
[protocol]
[static func]Also matches scoped operators.
[static subscript]
[static var]
[struct]
[subscript]
[typealias]
[var]Also matches global variables.

Protocol requirements and default implementations

You can use [requirement] (or [requirement: true]) to match only protocol requirements, and [requirement: false] to exclude them.

public
protocol ExampleProtocol
{
    func f()
}
extension ExampleProtocol
{
    public
    func f() {}
}
Codelinks.swift:13
SyntaxRenders as
``ExampleProtocol.f [requirement]``ExampleProtocol.f
``ExampleProtocol.f [requirement: false]``ExampleProtocol.f

Multiple filters

You can specify multiple filters by separating them with commas.

public
protocol AnotherProtocol
{
    func g()
    static func g()
}
extension AnotherProtocol
{
    public
    func g() {}

    public
    static func g() {}
}
Codelinks.swift:33
SyntaxRenders as
``AnotherProtocol.g [func, requirement]``AnotherProtocol.g
``AnotherProtocol.g [func, requirement: false]``AnotherProtocol.g
``AnotherProtocol.g [static func, requirement]``AnotherProtocol.g
``AnotherProtocol.g [static func, requirement: false]``AnotherProtocol.g

Disambiguating overloads

You can disambiguate overloads by specifying the types in their function signatures.

To disambiguate by argument types, write the types in parentheses after the function name and a space.

SyntaxRenders as
``Int.init(_:) (Float)``Int.init(_:)
``Int.init(_:) (Double)``Int.init(_:)

If you like, you can use a hyphen (-) instead of a space.

SyntaxRenders as
``Int.init(_:)-(Float)``Int.init(_:)
``Int.init(_:)-(Double)``Int.init(_:)

The hyphen-joined form is useful when you want to use custom link text, which requires encoding the target as a URL.

SyntaxRenders as
[custom text](Int.init(_:)-(Float))custom text
[custom text](Int.init(_:)-(Double))custom text

Do not include modifiers such as inout, borrowing, or consuming, or attributes such as @escaping or @Sendable in the type signature.

Partial signatures

If overloaded functions have multiple arguments, you can specify only the ones that are different, and omit the rest by using the underscore character (_).

SyntaxRenders as
``Example.f(x:y:) (_, String)``Example.f(x:y:)
``Example.f(x:y:) (_, Substring)``Example.f(x:y:)

Arrays, Dictionaries, and Optionals

When specifying an Array or Dictionary type, use square brackets ([]) and colons (:) to specify the type arguments. Similarly, use a postfix question mark (?) to denote Optional types, or a postfix exclamation mark (!) for implicitly unwrapped optionals.

SyntaxRenders as
``Example.g(_:) ([Int])``Example.g(_:)
``Example.g(_:) ([Int: String])``Example.g(_:)
``Example.g(_:) (Int!)``Example.g(_:)
``Example.g(_:) ([Int].Type)``Example.g(_:)
``Example.g(_:) ([Int: String].Type)``Example.g(_:)
``Example.g(_:) (Int?.Type)``Example.g(_:)

For readability, you can include spaces around the colons, but not between the other special characters.

Variadic arguments

Use a postfix ellipsis (...) to denote variadic arguments.

SyntaxRenders as
``Example.g(_:) (Int...)``Example.g(_:)

Type arguments

When specifying a generic type, use angle brackets (<>) to enclose the type arguments.

SyntaxRenders as
``Example.h(_:) (Set<Int>)``Example.h(_:)
``Example.h(_:) (Int?)``Example.h(_:)
``Example.h(_:) (Dictionary<Int, Int>.Index)``Example.h(_:)

Always use the shorthand form of Array, Dictionary, and Optional types, even if the source declaration uses the full type name.

Generics and existentials

Do not include the any keyword when specifying existential types, just the protocol name. Similarly, do not include the some keyword when specifying generic types.

SyntaxRenders as
``Example.h(_:) (StringProtocol)``Example.h(_:)
``Example.h(_:) (Error)``Example.h(_:)

If the source declaration used a named generic parameter, you must use that same name in the codelink, even if it has an equivalent inline some spelling.

SyntaxRenders as
``Example.h(_:) (T)``Example.h(_:)

This means that renaming generic parameters, although ABI-compatible, is documentation-breaking.

Protocol composition types

When specifying a protocol composition type, use the & character to separate the protocols.

SyntaxRenders as
``Example.k(_:) (Sendable & CustomStringConvertible)``Example.k(_:)
``Example.k(_:) (CustomStringConvertible & Sendable)``Example.k(_:)

The order of the protocols is significant, and must match the order in the source declaration.

As with renaming generic parameters, reordering protocols in a composition type is documentation-breaking, even though it is ABI-compatible.

Tuple types

When specifying a tuple type, use parentheses to enclose the element types. A single-element tuple is equivalent to its element type.

SyntaxRenders as
``Example.l(_:) (())``Example.l(_:)
``Example.l(_:) ((Int))``Example.l(_:)
``Example.l(_:) ((Int, Int))``Example.l(_:)

Function types

When specifying a function type, use the -> token to provide the return type. Do not include function attributes, or keywords such as throws, rethrows, or async.

SyntaxRenders as
``Example.m(_:) ((Int) -> Int)``Example.m(_:)
``Example.m(_:) ((Int) -> ())``Example.m(_:)

Parameter packs

To specify a parameter pack expansion, spell a single instance of the parameter pack. Do not include a trailing ellipsis (as it is not a variadic argument), and do not include the repeat or each keywords.

SyntaxRenders as
``Example.n(_:) ([T])``Example.n(_:)
``Example.n(_:) ([T: Int])``Example.n(_:)

Noncopyable types

Spell types with suppressed conformances with a leading tilde (~) character. Don’t include the ownership specifier.

SyntaxRenders as
``Example.n(_:) (~Copyable)``Example.n(_:)

Typealiases and Self

If the original declaration uses a typealias, you must use the same typealias in the codelink.

The Self type is not a typealias, and is only allowed when it is truly dynamic, such as in a class or protocol member. If Self is an SE-0068 static type, you must replace it with the actual type name, including any generic parameters.

SyntaxRenders as
``Example.o(_:) (Example)``Example.o(_:)
``Example.o(_:) (UTF8.Type)``Example.o(_:)
``Example.o(_:) (Void)``Example.o(_:)
``ExampleProtocol.o(_:) (Self)``ExampleProtocol.o(_:)
``ExampleProtocol.o(_:) (Void)``ExampleProtocol.o(_:)

Disambiguating return types

Overloading on return type is discouraged in Swift, but it is possible to disambiguate by return type similarly to how you disambiguate by argument types.

For the purposes of link resolution, function outputs are treated as splatted tuples, and individual element types can be ignored using the underscore character (_).

Specify return types using the -> token. The spaces around the arrow are optional.

SyntaxRenders as
``Example.r(_:) -> ()``Example.r(_:)
``Example.r(_:) -> Int``Example.r(_:)
``Example.r(_:) -> (Int, String)``Example.r(_:)

If you replace all of the types with underscores, the codelink will match any overload that returns a tuple of that length.

SyntaxRenders as
``Example.r(_:) -> _``Example.r(_:)
``Example.r(_:) -> (_, _)``Example.r(_:)

A single underscore matches only overloads that return a scalar type. To express a true wildcard, simply omit the entire return type.

Methods and subscripts

If needed, you can provide patterns for both the argument types and the return type.

SyntaxRenders as
``Example.s(_:) (Int) -> (Int, String)``Example.s(_:)
``Example.s(_:) (String) -> (Int, String)``Example.s(_:)

Initializers

Even though initializers formally return Self, disambiguating initializers by return type is not supported.

Properties

For the purposes of link resolution, properties are treated as functions with no arguments and a return type of the property’s own type.

SyntaxRenders as
``ExampleProtocol.x -> Int``ExampleProtocol.x
``ExampleProtocol.x -> [Int]``ExampleProtocol.x
``ExampleProtocol.x -> (_, Int)``ExampleProtocol.x

Combining multiple filters

If you need to use filters alongside signature patterns, put the filters in brackets ([]) after the signature.

SyntaxRenders as
``ExampleProtocol/g(_:) (Int32) [requirement]``g(_:)
``ExampleProtocol/g(_:) (Int64) -> () [requirement]``g(_:)
``ExampleProtocol/g(_:) (Int64) -> Int64 [requirement]``g(_:)
``ExampleProtocol/g(_:) (Int32) [requirement: false]``g(_:)
``ExampleProtocol/g(_:) (Int64) -> () [requirement: false]``g(_:)
``ExampleProtocol/g(_:) (Int64) -> Int64 [requirement: false]``g(_:)

Further reading