Name mangling "AC"

I'm trying to wrap my head around substitutions in mangling:

I'm getting:


public struct Theo<T> {
  public func John(_ a: Int, _ B: Theo<T>){}
}

$s5carlo4TheoV4JohnyySi_ACyxGtF

My question is about the ACyxG now yxG is generics, but the "AC" I don't get.

I thought word substitution worked for well, words, but independent of the nr of words, the type for Theo always ends up written as AC. Can someone explain what I'm missing?

if I do:


public struct StructTest<T> {
  public var x: T

  public func Fred(_ a: Int, _ b: StructTest<T>) {}
}

I get:
$s5carlo10StructTestV4FredyySi_ACyxGtF

Which also uses AC to denote StructTest, despite it being two words.

Does anyone here know enough about the mangling to explain how this works?

1 Like

AC means substitution for 3rd element of substitution array.
In this case, array is [carlo(string), StructTest(string), StructTest(type), ...].
So AC represents StructTest type which is type of parameter b.

Document about substitution is here. swift/Mangling.rst at main ¡ apple/swift ¡ GitHub

This my presentation might be helpful for you.

So you can also see AB by this code.

$ cat carlo.swift 
public struct StructTest<T> {
  public var x: T

  public func Fred(_ a: Int, StructTest: StructTest<T>) {}
}

$ swiftc -emit-sil carlo.swift
...
// StructTest.Fred(_:StructTest:)
sil @$s5carlo10StructTestV4Fred_ABySi_ACyxGtF
...

Thanks! So I think i completely misunderstood the substitution. I thought it worked on words separated by uppercase characters or numbers, but it really seems to work on entities?

ie "carlo" is the module name, given it's written first, a reference to that would be "A"?
and if the module name was "HelloWorld", it would still be A?

and in this case, StructTest would be B? What I don't get is why C then refers to StructTest again?

and when to use lowercase letters for substitution.

but it really seems to work on entities?

Yes, substitution are used for both keywords and type entities.
And substitution array has elements which is mixed with these two kinds.

a reference to that would be "A"?

Yes.
This code generates AA.

// carlo.swift
public struct StructTest<T> {
  public var x: T

  public func Fred(carlo a: Int, _ b: StructTest<T>) {}
}

// StructTest.Fred(carlo:_:)
sil @$s5carlo10StructTestV4FredAA_ySi_ACyxGtF

if the module name was "HelloWorld", it would still be A?

In module HelloWorld, AA represents HelloWorld.

So, this code which is only differ on filename does not generates AA.

// HelloWorld.swift
public struct StructTest<T> {
  public var x: T

  public func Fred(carlo a: Int, _ b: StructTest<T>) {}
}

// StructTest.Fred(carlo:_:)
sil @$s2hw10StructTestV4Fred5carlo_ySi_ACyxGtF

and in this case, StructTest would be B? What I don't get is why C then refers to StructTest again?

StructTest for AB is keyword.
it used at keyword position such like parameter labels.

StructTest for AC is type entity.
it used at type position such like parameter types.

when to use lowercase letters for substitution.

Continuous substitution uses lowercase letters to compress them.
For example, AA + AB is compressed into AaB.

Here is example:

public struct StructTest<T> {
  public var x: T

  public func Fred(carlo a: Int, StructTest b: StructTest<T>) {}
}

// StructTest.Fred(carlo:StructTest:)
sil @$s5carlo10StructTestV4FredAaBySi_ACyxGtF
1 Like