How to get a protocol's name in its extensions

I have hard-coded the protocol names in the print statements below.

protocol Foo {

extension Foo {
    func go () {
        print (type (of:self), "Foo", #function)

protocol Bar: Foo {

extension Bar {
    func go() {
        print (type (of:self), "Bar", #function)

        func _super (self:some Foo) {
            print (type (of:self), "Bar", #function)

        _super(self: self)

struct Clever: Bar {

Is there a way to get the name of a protocol, analogous to #function or type (of:self), so that I don't have to hard-code them?

1 Like

You can use Swift Runtime to do so

// Module A
protocol P {
    func hello()

private func _getTypeName(_ type: Any.Type, qualified: Bool)
  -> (UnsafePointer<UInt8>, Int)

print(String(cString: _getTypeName(P.self, qualified: true).0)) 
// Print A.P

print(String(cString: _getTypeName(P.self, qualified: false).0))
// Print P

Here is my Library's usage


Swift Standard Library actually already shipped it as an underscore API.

You can also just use it directly

import Swift // Implicitly added for all Swift file

print(_typeName(P.self)) // A.P
print(_typeName(P.self, qualified: false)) // P

Relative Code is here

1 Like

Thank you, @Kyle-Ye, but the protocol name is still hard-coded in the examples.

I am beginning to think that this, getting the name of a protocol in its extensions, is currently not possible. It would be really nice if we had something like #protocol analogous to #function.

1 Like

Seems like a perfect fit for a user-defined expression macro!

The standard library contains the following set of macros:

macro function<T>() -> T

Produces the name of the declaration in which it appears.

macro file<T>() -> T

Produces the path to the file in which it appears.

macro fileID<T>() -> T

Produces a unique identifier for the source file in which the macro appears.

macro filePath<T>() -> T

Produces the complete path to the file in which the macro appears.

macro line<T>() -> T

Produces the line number on which it appears.

macro column<T>() -> T

Produces the column number in which the macro begins.

I wish it had one more:

macro type<T>() -> T

Produces the name of the type in which the macro appears or the name of the protocol in an extension of which the macro appears.

I wonder why this particular one is missing.

1 Like