@@ -1855,6 +1855,32 @@ struct TargetExtendedExistentialTypeShape
18551855 // / Flags for the existential shape.
18561856 ExtendedExistentialTypeShapeFlags Flags;
18571857
1858+ // / The mangling of the generalized existential type, expressed
1859+ // / (if necessary) in terms of the type parameters of the
1860+ // / generalization signature.
1861+ // /
1862+ // / If this shape is non-unique, this is always a flat string, not a
1863+ // / "symbolic" mangling which can contain relative references. This
1864+ // / allows uniquing to simply compare the string content.
1865+ // /
1866+ // / In principle, the content of the requirement signature and type
1867+ // / expression are derivable from this type. We store them separately
1868+ // / so that code which only needs to work with the logical content of
1869+ // / the type doesn't have to break down the existential type string.
1870+ // / This both (1) allows those operations to work substantially more
1871+ // / efficiently (and without needing code to produce a requirement
1872+ // / signature from an existential type to exist in the runtime) and
1873+ // / (2) potentially allows old runtimes to support new existential
1874+ // / types without as much invasive code.
1875+ // /
1876+ // / The content of this string is *not* necessarily derivable from
1877+ // / the requirement signature. This is because there may be multiple
1878+ // / existential types that have equivalent logical content but which
1879+ // / we nonetheless distinguish at compile time. Storing this also
1880+ // / allows us to far more easily produce a formal type from this
1881+ // / shape reflectively.
1882+ RelativeStringPointer ExistentialType;
1883+
18581884 // / The header describing the requirement signature of the existential.
18591885 TargetGenericContextDescriptorHeader<Runtime> ReqSigHeader;
18601886
@@ -2024,6 +2050,9 @@ struct UniqueHash {
20242050
20252051// / A descriptor for an extended existential type descriptor which
20262052// / needs to be uniqued at runtime.
2053+ // /
2054+ // / Uniquing is performed by comparing the existential type strings
2055+ // / of the shapes.
20272056template <typename Runtime>
20282057struct TargetNonUniqueExtendedExistentialTypeShape {
20292058 // / A reference to memory that can be used to cache a globally-unique
@@ -2032,10 +2061,12 @@ struct TargetNonUniqueExtendedExistentialTypeShape {
20322061 std::atomic<ConstTargetMetadataPointer<Runtime,
20332062 TargetExtendedExistentialTypeShape>>> UniqueCache;
20342063
2035- // / A hash of the mangling of the existential shape.
2036- // /
2037- // / TODO: describe that mangling here
2038- UniqueHash Hash;
2064+ llvm::StringRef getExistentialTypeStringForUniquing () const {
2065+ // When we have a non-unique shape, we're guaranteed that
2066+ // ExistentialType contains no symbolic references, so we can just
2067+ // recover it this way rather than having to parse it.
2068+ return LocalCopy.ExistentialType .get ();
2069+ }
20392070
20402071 // / The local copy of the existential shape descriptor.
20412072 TargetExtendedExistentialTypeShape<Runtime> LocalCopy;
0 commit comments