Skip to content

Commit d30eb17

Browse files
authored
Merge pull request swiftlang#24143 from jckarter/opaque-type-followup
Serialization: Cross-reference opaque return types by mangled name
2 parents 28507be + 5215290 commit d30eb17

File tree

12 files changed

+139
-14
lines changed

12 files changed

+139
-14
lines changed

include/swift/AST/Decl.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2787,6 +2787,8 @@ class OpaqueTypeDecl : public GenericTypeDecl {
27872787
/// signature of the original declaration.
27882788
Optional<SubstitutionMap> UnderlyingTypeSubstitutions;
27892789

2790+
mutable Identifier OpaqueReturnTypeIdentifier;
2791+
27902792
public:
27912793
OpaqueTypeDecl(ValueDecl *NamingDecl,
27922794
GenericParamList *GenericParams,
@@ -2816,6 +2818,10 @@ class OpaqueTypeDecl : public GenericTypeDecl {
28162818
// Opaque type decls are currently always implicit
28172819
SourceRange getSourceRange() const { return SourceRange(); }
28182820

2821+
// Get the identifier string that can be used to cross-reference unnamed
2822+
// opaque return types across files.
2823+
Identifier getOpaqueReturnTypeIdentifier() const;
2824+
28192825
static bool classof(const Decl *D) {
28202826
return D->getKind() == DeclKind::OpaqueType;
28212827
}

include/swift/AST/PrintOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,7 @@ struct PrintOptions {
521521
result.PrintInSILBody = true;
522522
result.PreferTypeRepr = false;
523523
result.PrintIfConfig = false;
524+
result.PrintStableReferencesToOpaqueReturnTypes = true;
524525
return result;
525526
}
526527

include/swift/Serialization/DeclTypeRecordNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ OTHER(XREF, 249)
188188
OTHER(INLINABLE_BODY_TEXT, 250)
189189
OTHER(SELF_PROTOCOL_CONFORMANCE, 251)
190190

191+
OTHER(XREF_OPAQUE_RETURN_TYPE_PATH_PIECE, 252)
192+
191193
#undef RECORD
192194
#undef DECLTYPERECORDNODES_HAS_RECORD_VAL
193195
#undef RECORD_VAL

include/swift/Serialization/ModuleFormat.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,6 +1416,11 @@ namespace decls_block {
14161416
BCFixed<1>, // restrict to protocol extension
14171417
BCFixed<1> // imported from Clang?
14181418
>;
1419+
1420+
using XRefOpaqueReturnTypePathPieceLayout = BCRecordLayout<
1421+
XREF_OPAQUE_RETURN_TYPE_PATH_PIECE,
1422+
IdentifierIDField // mangled name of defining decl
1423+
>;
14191424

14201425
using XRefValuePathPieceLayout = BCRecordLayout<
14211426
XREF_VALUE_PATH_PIECE,

lib/AST/ASTPrinter.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
#include "swift/Basic/STLExtras.h"
3838
#include "swift/Basic/StringExtras.h"
3939
#include "swift/Config.h"
40-
#include "swift/Demangling/ManglingMacros.h"
4140
#include "swift/Parse/Lexer.h"
4241
#include "swift/Strings.h"
4342
#include "clang/AST/ASTContext.h"
@@ -4173,15 +4172,8 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
41734172
// type.
41744173
Printer << "@_opaqueReturnTypeOf(";
41754174

4176-
SmallString<64> mangleBuf;
4177-
{
4178-
llvm::raw_svector_ostream os(mangleBuf);
4179-
Mangle::ASTMangler mangler;
4180-
os << mangler.mangleDeclAsUSR(decl->getNamingDecl(),
4181-
MANGLING_PREFIX_STR);
4182-
}
4183-
4184-
Printer.printEscapedStringLiteral(mangleBuf);
4175+
Printer.printEscapedStringLiteral(
4176+
decl->getOpaqueReturnTypeIdentifier().str());
41854177

41864178
Printer << ", " << T->getInterfaceType()
41874179
->castTo<GenericTypeParamType>()

lib/AST/Decl.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#include "swift/Basic/Range.h"
5151
#include "swift/Basic/StringExtras.h"
5252
#include "swift/Basic/Statistic.h"
53+
#include "swift/Demangling/ManglingMacros.h"
5354

5455
#include "clang/Basic/CharInfo.h"
5556
#include "clang/AST/Attr.h"
@@ -5993,6 +5994,22 @@ OpaqueTypeDecl::OpaqueTypeDecl(ValueDecl *NamingDecl,
59935994
setImplicit();
59945995
}
59955996

5997+
Identifier OpaqueTypeDecl::getOpaqueReturnTypeIdentifier() const {
5998+
assert(getNamingDecl() && "not an opaque return type");
5999+
if (!OpaqueReturnTypeIdentifier.empty())
6000+
return OpaqueReturnTypeIdentifier;
6001+
6002+
SmallString<64> mangleBuf;
6003+
{
6004+
llvm::raw_svector_ostream os(mangleBuf);
6005+
Mangle::ASTMangler mangler;
6006+
os << mangler.mangleDeclAsUSR(getNamingDecl(), MANGLING_PREFIX_STR);
6007+
}
6008+
6009+
OpaqueReturnTypeIdentifier = getASTContext().getIdentifier(mangleBuf);
6010+
return OpaqueReturnTypeIdentifier;
6011+
}
6012+
59966013
void AbstractFunctionDecl::computeType(AnyFunctionType::ExtInfo info) {
59976014
auto &ctx = getASTContext();
59986015
auto *sig = getGenericSignature();

lib/AST/Module.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1788,9 +1788,8 @@ SourceFile::lookupOpaqueResultType(StringRef MangledName,
17881788
void SourceFile::markDeclWithOpaqueResultTypeAsValidated(ValueDecl *vd) {
17891789
UnvalidatedDeclsWithOpaqueReturnTypes.erase(vd);
17901790
if (auto opaqueDecl = vd->getOpaqueResultTypeDecl()) {
1791-
Mangle::ASTMangler mangler;
1792-
auto name = mangler.mangleDeclAsUSR(vd, MANGLING_PREFIX_STR);
1793-
ValidatedOpaqueReturnTypes.insert({name, opaqueDecl});
1791+
ValidatedOpaqueReturnTypes.insert(
1792+
{opaqueDecl->getOpaqueReturnTypeIdentifier().str(), opaqueDecl});
17941793
}
17951794
}
17961795

lib/Serialization/Deserialization.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,6 +1314,20 @@ ModuleFile::resolveCrossReference(ModuleID MID, uint32_t pathLen) {
13141314
importedFromClang, isStatic, None, values);
13151315
break;
13161316
}
1317+
1318+
case XREF_OPAQUE_RETURN_TYPE_PATH_PIECE: {
1319+
IdentifierID DefiningDeclNameID;
1320+
1321+
XRefOpaqueReturnTypePathPieceLayout::readRecord(scratch, DefiningDeclNameID);
1322+
1323+
auto name = getIdentifier(DefiningDeclNameID);
1324+
pathTrace.addOpaqueReturnType(name);
1325+
1326+
if (auto opaque = baseModule->lookupOpaqueResultType(name.str(), nullptr)) {
1327+
values.push_back(opaque);
1328+
}
1329+
break;
1330+
}
13171331

13181332
case XREF_EXTENSION_PATH_PIECE:
13191333
llvm_unreachable("can only extend a nominal");
@@ -1377,6 +1391,22 @@ ModuleFile::resolveCrossReference(ModuleID MID, uint32_t pathLen) {
13771391
result = getIdentifier(IID);
13781392
break;
13791393
}
1394+
case XREF_OPAQUE_RETURN_TYPE_PATH_PIECE: {
1395+
IdentifierID IID;
1396+
XRefOpaqueReturnTypePathPieceLayout::readRecord(scratch, IID);
1397+
auto mangledName = getIdentifier(IID);
1398+
1399+
SmallString<64> buf;
1400+
{
1401+
llvm::raw_svector_ostream os(buf);
1402+
os << "<<opaque return type of ";
1403+
os << mangledName.str();
1404+
os << ">>";
1405+
}
1406+
1407+
result = getContext().getIdentifier(buf);
1408+
break;
1409+
}
13801410
case XREF_INITIALIZER_PATH_PIECE:
13811411
result = DeclBaseName::createConstructor();
13821412
break;
@@ -1683,6 +1713,22 @@ ModuleFile::resolveCrossReference(ModuleID MID, uint32_t pathLen) {
16831713

16841714
break;
16851715
}
1716+
1717+
case XREF_OPAQUE_RETURN_TYPE_PATH_PIECE: {
1718+
values.clear();
1719+
IdentifierID DefiningDeclNameID;
1720+
1721+
XRefOpaqueReturnTypePathPieceLayout::readRecord(scratch, DefiningDeclNameID);
1722+
1723+
auto name = getIdentifier(DefiningDeclNameID);
1724+
pathTrace.addOpaqueReturnType(name);
1725+
1726+
if (auto opaqueTy = baseModule->lookupOpaqueResultType(name.str(),
1727+
nullptr)) {
1728+
values.push_back(opaqueTy);
1729+
}
1730+
break;
1731+
}
16861732

16871733
default:
16881734
// Unknown xref path piece.

lib/Serialization/DeserializationErrors.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class XRefTracePath {
3838
Extension,
3939
GenericParam,
4040
PrivateDiscriminator,
41+
OpaqueReturnType,
4142
Unknown
4243
};
4344

@@ -61,6 +62,7 @@ class XRefTracePath {
6162
case Kind::Value:
6263
case Kind::Operator:
6364
case Kind::PrivateDiscriminator:
65+
case Kind::OpaqueReturnType:
6466
return getDataAs<DeclBaseName>();
6567
case Kind::Type:
6668
case Kind::OperatorFilter:
@@ -146,6 +148,9 @@ class XRefTracePath {
146148
case Kind::PrivateDiscriminator:
147149
os << "(in " << getDataAs<Identifier>() << ")";
148150
break;
151+
case Kind::OpaqueReturnType:
152+
os << "opaque return type of " << getDataAs<DeclBaseName>();
153+
break;
149154
case Kind::Unknown:
150155
os << "unknown xref kind " << getDataAs<uintptr_t>();
151156
break;
@@ -196,6 +201,10 @@ class XRefTracePath {
196201
void addUnknown(uintptr_t kind) {
197202
path.push_back({ PathPiece::Kind::Unknown, kind });
198203
}
204+
205+
void addOpaqueReturnType(Identifier name) {
206+
path.push_back({ PathPiece::Kind::OpaqueReturnType, name });
207+
}
199208

200209
DeclBaseName getLastName() const {
201210
for (auto &piece : reversed(path)) {

lib/Serialization/Serialization.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1916,9 +1916,24 @@ void Serializer::writeCrossReference(const DeclContext *DC, uint32_t pathLen) {
19161916
break;
19171917

19181918
case DeclContextKind::GenericTypeDecl: {
1919+
auto generic = cast<GenericTypeDecl>(DC);
1920+
1921+
// Opaque return types are unnamed and need a special xref.
1922+
if (auto opaque = dyn_cast<OpaqueTypeDecl>(generic)) {
1923+
if (!opaque->hasName()) {
1924+
abbrCode = DeclTypeAbbrCodes[XRefOpaqueReturnTypePathPieceLayout::Code];
1925+
1926+
XRefOpaqueReturnTypePathPieceLayout::emitRecord(Out, ScratchRecord,
1927+
abbrCode,
1928+
addDeclBaseNameRef(opaque->getOpaqueReturnTypeIdentifier()));
1929+
break;
1930+
}
1931+
}
1932+
1933+
assert(generic->hasName());
1934+
19191935
writeCrossReference(DC->getParent(), pathLen + 1);
19201936

1921-
auto generic = cast<GenericTypeDecl>(DC);
19221937
abbrCode = DeclTypeAbbrCodes[XRefTypePathPieceLayout::Code];
19231938

19241939
Identifier discriminator;
@@ -2073,6 +2088,14 @@ void Serializer::writeCrossReference(const Decl *D) {
20732088

20742089
writeCrossReference(D->getDeclContext());
20752090

2091+
if (auto opaque = dyn_cast<OpaqueTypeDecl>(D)) {
2092+
abbrCode = DeclTypeAbbrCodes[XRefOpaqueReturnTypePathPieceLayout::Code];
2093+
XRefOpaqueReturnTypePathPieceLayout::emitRecord(Out, ScratchRecord,
2094+
abbrCode,
2095+
addDeclBaseNameRef(opaque->getOpaqueReturnTypeIdentifier()));
2096+
return;
2097+
}
2098+
20762099
if (auto genericParam = dyn_cast<GenericTypeParamDecl>(D)) {
20772100
assert(!D->getDeclContext()->isModuleScopeContext() &&
20782101
"Cannot cross reference a generic type decl at module scope.");
@@ -4252,6 +4275,7 @@ void Serializer::writeAllDeclsAndTypes() {
42524275
registerDeclTypeAbbr<TopLevelCodeDeclContextLayout>();
42534276

42544277
registerDeclTypeAbbr<XRefTypePathPieceLayout>();
4278+
registerDeclTypeAbbr<XRefOpaqueReturnTypePathPieceLayout>();
42554279
registerDeclTypeAbbr<XRefValuePathPieceLayout>();
42564280
registerDeclTypeAbbr<XRefExtensionPathPieceLayout>();
42574281
registerDeclTypeAbbr<XRefOperatorOrAccessorPathPieceLayout>();
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
public protocol Butt {}
2+
extension Int: Butt {}
3+
4+
public func exportsOpaqueReturn() -> some Butt { return 0 }
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/OpaqueReturnTypeExporter.swiftmodule -module-name OpaqueReturnTypeExporter %S/Inputs/OpaqueReturnTypeExporter.swift
3+
// RUN: %target-sil-opt -I %t %s -emit-sib -module-name test -o %t/test.sib
4+
// RUN: %target-swift-frontend -I %t -emit-ir %t/test.sib
5+
6+
import OpaqueReturnTypeExporter
7+
8+
typealias SomeButt = @_opaqueReturnTypeOf("$s24OpaqueReturnTypeExporter07exportsaB0QryF", 0) opaque
9+
10+
sil @$s24OpaqueReturnTypeExporter07exportsaB0QryF : $@convention(thin) () -> @out SomeButt
11+
12+
sil @use_opaque_type : $@convention(thin) () -> () {
13+
entry:
14+
%f = function_ref @$s24OpaqueReturnTypeExporter07exportsaB0QryF : $@convention(thin) () -> @out SomeButt
15+
%x = alloc_stack $SomeButt
16+
apply %f(%x) : $@convention(thin) () -> @out SomeButt
17+
destroy_addr %x : $*SomeButt
18+
dealloc_stack %x : $*SomeButt
19+
return undef : $()
20+
}

0 commit comments

Comments
 (0)