Usr vs typeusr in sourcekit

I started looking into and stumbled into a roadblock

struct Aaa { }
var bbb = Aaa()

If I log the dict received from sourcekit, the usr for Aaa is "s:3foo3AaaV", and typeusr for bbb is "$s3foo3AaaVD" which is nothing alike. It seems typeusr isn't the USR.

The usr of Aaa s:3foo3AaaV is a normal USR. This matches the index data.

The "typeusr" of bbb, $s3foo3AaaVD is a mangled symbol name.

It looks like the implementation of printDeclTypeUSR and printTypeUSR are not using the USR prefix. @Xi_Ge was this just an oversight? I see you implemented this back in 2016.

In CursorInfo response, include the mangle name of the type of the underlying decl.
commit a5e51a349436a8f009956b22278c55a0202fdc3f
Author: Xi Ge <>
Date:   Tue Jul 12 12:01:37 2016

    [SourceKit] In CursorInfo response, include the mangle name of the type of the underlying decl.
    The mangled name of the type is identical to those for debugger. These
    mangled names allow us to reconstruct the type from AST and generate interface
    specifically for that type.
    Related rdar://27306890

The trailing "D" in the mangling of the type is a bit more mysterious to me. I can see it's added in mangleDeclType and in mangleTypeForDebugger. @Xi_Ge and @Erik_Eckstein what's the point of the "D" here? Shouldn't we want this USR to match the decl USR?

1 Like

Also, @Xi_Ge what do you think of the approach of using "typeusr" to find the definition of the type from the index in general? I guess this might not be sufficient for generic types?

1 Like

TypeUSR as a concept is probably problematic since USRs are usually for indexing purposes and not all TypeUSR is indexable, such ad generic types as @blangmuir mentioned. I think we should rename the sourcekit entry for TypeUSR to mangledTypeName and the client needs to demangle that name to find the actual decl name they are looking for.

1 Like

What do you think of adding a new optional field in cursor info that contains the USR of the type decl if there is one? That should handle generic types, and for anything non-nominal, like a tuple or function, we can just say it's null.

var a =1 // a-> Int
var b = [1] // b -> Array
var c = (1, 2) // c -> nil
func test<T>(d: [T]) {} // d-> Array
1 Like

I think that makes sense. This field should allow us to find the top-level type definition conveniently.

1 Like

I've updated to describe this approach, thanks.

1 Like
Terms of Service

Privacy Policy

Cookie Policy