Skip to content

Commit 047749a

Browse files
author
Harlan Haskins
authored
Merge pull request swiftlang#25419 from harlanhaskins/property-reprs
[ModuleInterface] Qualify all types in module interfaces
2 parents 60a844e + 5a3761d commit 047749a

32 files changed

+300
-203
lines changed

include/swift/AST/PrintOptions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ struct PrintOptions {
494494
/// consistent and well-formed.
495495
///
496496
/// \see swift::emitParseableInterface
497-
static PrintOptions printParseableInterfaceFile();
497+
static PrintOptions printParseableInterfaceFile(bool preferTypeRepr);
498498

499499
static PrintOptions printModuleInterface();
500500
static PrintOptions printTypeInterface(Type T);

include/swift/Frontend/ParseableInterfaceSupport.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ class ModuleDecl;
2727

2828
/// Options for controlling the generation of the .swiftinterface output.
2929
struct ParseableInterfaceOptions {
30+
/// Should we prefer printing TypeReprs when writing out types in a module
31+
/// interface, or should we fully-qualify them?
32+
bool PreserveTypesAsWritten = false;
33+
3034
/// Copy of all the command-line flags passed at .swiftinterface
3135
/// generation time, re-applied to CompilerInvocation when reading
3236
/// back .swiftinterface and reconstructing .swiftmodule.

include/swift/Option/FrontendOptions.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,11 @@ def build_module_from_parseable_interface :
535535
Alias<compile_module_from_interface>,
536536
ModeOpt;
537537

538+
def module_interface_preserve_types_as_written :
539+
Flag<["-"], "module-interface-preserve-types-as-written">,
540+
HelpText<"When emitting a module interface, preserve types as they were "
541+
"written in the source">;
542+
538543
def prebuilt_module_cache_path :
539544
Separate<["-"], "prebuilt-module-cache-path">,
540545
HelpText<"Directory of prebuilt modules for loading module interfaces">;

lib/AST/ASTPrinter.cpp

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ static bool contributesToParentTypeStorage(const AbstractStorageDecl *ASD) {
9494
return !ND->isResilient() && ASD->hasStorage() && !ASD->isStatic();
9595
}
9696

97-
PrintOptions PrintOptions::printParseableInterfaceFile() {
97+
PrintOptions PrintOptions::printParseableInterfaceFile(bool preferTypeRepr) {
9898
PrintOptions result;
9999
result.PrintLongAttrsOnSeparateLines = true;
100100
result.TypeDefinitions = true;
@@ -110,6 +110,7 @@ PrintOptions PrintOptions::printParseableInterfaceFile() {
110110
result.EnumRawValues = EnumRawValueMode::PrintObjCOnly;
111111
result.OpaqueReturnTypePrinting =
112112
OpaqueReturnTypePrintingMode::StableReference;
113+
result.PreferTypeRepr = preferTypeRepr;
113114

114115
// We should print __consuming, __owned, etc for the module interface file.
115116
result.SkipUnderscoredKeywords = false;
@@ -1004,7 +1005,18 @@ void PrintAST::printAttributes(const Decl *D) {
10041005
void PrintAST::printTypedPattern(const TypedPattern *TP) {
10051006
printPattern(TP->getSubPattern());
10061007
Printer << ": ";
1007-
printTypeLoc(TP->getTypeLoc());
1008+
1009+
// Make sure to check if the underlying var decl is an implicitly unwrapped
1010+
// optional.
1011+
bool isIUO = false;
1012+
if (auto *named = dyn_cast<NamedPattern>(TP->getSubPattern()))
1013+
if (auto decl = named->getDecl())
1014+
isIUO = decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
1015+
1016+
if (isIUO)
1017+
printTypeLocForImplicitlyUnwrappedOptional(TP->getTypeLoc());
1018+
else
1019+
printTypeLoc(TP->getTypeLoc());
10081020
}
10091021

10101022
/// Determines if we are required to print the name of a property declaration,
@@ -2530,6 +2542,14 @@ void PrintAST::visitVarDecl(VarDecl *decl) {
25302542
tyLoc = TypeLoc::withoutLoc(decl->getInterfaceType());
25312543

25322544
Printer.printDeclResultTypePre(decl, tyLoc);
2545+
2546+
// HACK: When printing result types for vars with opaque result types,
2547+
// always print them using the `some` keyword instead of printing
2548+
// the full stable reference.
2549+
llvm::SaveAndRestore<PrintOptions::OpaqueReturnTypePrintingMode>
2550+
x(Options.OpaqueReturnTypePrinting,
2551+
PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword);
2552+
25332553
if (decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
25342554
printTypeLocForImplicitlyUnwrappedOptional(tyLoc);
25352555
else
@@ -2805,6 +2825,14 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) {
28052825

28062826
Printer.printDeclResultTypePre(decl, ResultTyLoc);
28072827
Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);
2828+
2829+
// HACK: When printing result types for funcs with opaque result types,
2830+
// always print them using the `some` keyword instead of printing
2831+
// the full stable reference.
2832+
llvm::SaveAndRestore<PrintOptions::OpaqueReturnTypePrintingMode>
2833+
x(Options.OpaqueReturnTypePrinting,
2834+
PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword);
2835+
28082836
if (decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
28092837
printTypeLocForImplicitlyUnwrappedOptional(ResultTyLoc);
28102838
else
@@ -2947,6 +2975,14 @@ void PrintAST::visitSubscriptDecl(SubscriptDecl *decl) {
29472975
Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);
29482976
if (!elementTy.getTypeRepr())
29492977
elementTy = TypeLoc::withoutLoc(decl->getElementInterfaceType());
2978+
2979+
// HACK: When printing result types for subscripts with opaque result types,
2980+
// always print them using the `some` keyword instead of printing
2981+
// the full stable reference.
2982+
llvm::SaveAndRestore<PrintOptions::OpaqueReturnTypePrintingMode>
2983+
x(Options.OpaqueReturnTypePrinting,
2984+
PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword);
2985+
29502986
if (decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
29512987
printTypeLocForImplicitlyUnwrappedOptional(elementTy);
29522988
else

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2046,17 +2046,8 @@ TypeDecl *EquivalenceClass::lookupNestedType(
20462046
continue;
20472047
}
20482048

2049-
// If this is another type declaration, determine whether we should
2050-
// record it.
2049+
// If this is another type declaration, record it.
20512050
if (auto type = dyn_cast<TypeDecl>(member)) {
2052-
// FIXME: Filter out type declarations that aren't in the same
2053-
// module as the protocol itself. This is an unprincipled hack, but
2054-
// provides consistent lookup semantics for the generic signature
2055-
// builder in all contents.
2056-
if (type->getDeclContext()->getParentModule()
2057-
!= proto->getParentModule())
2058-
continue;
2059-
20602051
concreteDecls.push_back(type);
20612052
continue;
20622053
}

lib/Frontend/CompilerInvocation.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,14 @@ static void PrintArg(raw_ostream &OS, const char *Arg, StringRef TempDir) {
197197
OS << '"';
198198
}
199199

200+
static void ParseParseableInterfaceArgs(ParseableInterfaceOptions &Opts,
201+
ArgList &Args) {
202+
using namespace options;
203+
204+
Opts.PreserveTypesAsWritten |=
205+
Args.hasArg(OPT_module_interface_preserve_types_as_written);
206+
}
207+
200208
/// Save a copy of any flags marked as ModuleInterfaceOption, if running
201209
/// in a mode that is going to emit a .swiftinterface file.
202210
static void SaveParseableInterfaceArgs(ParseableInterfaceOptions &Opts,
@@ -1306,6 +1314,7 @@ bool CompilerInvocation::parseArgs(
13061314
return true;
13071315
}
13081316

1317+
ParseParseableInterfaceArgs(ParseableInterfaceOpts, ParsedArgs);
13091318
SaveParseableInterfaceArgs(ParseableInterfaceOpts, FrontendOpts,
13101319
ParsedArgs, Diags);
13111320

lib/Frontend/ParseableInterfaceSupport.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,8 @@ bool swift::emitParseableInterface(raw_ostream &out,
411411
printToolVersionAndFlagsComment(out, Opts, M);
412412
printImports(out, M);
413413

414-
const PrintOptions printOptions = PrintOptions::printParseableInterfaceFile();
414+
const PrintOptions printOptions = PrintOptions::printParseableInterfaceFile(
415+
Opts.PreserveTypesAsWritten);
415416
InheritedProtocolCollector::PerTypeMap inheritedProtocolMap;
416417

417418
SmallVector<Decl *, 16> topLevelDecls;

stdlib/public/Darwin/XCTest/CMakeLists.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,14 @@ add_swift_target_library(swiftXCTest ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS
77
XCTestCaseAdditions.mm
88
XCTest.swift
99

10-
SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}"
10+
SWIFT_COMPILE_FLAGS
11+
"${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}"
12+
13+
# XCTest has a type called XCTest, which exposes an issue in module
14+
# interfaces -- because types are fully-qualified, the compiler currently
15+
# doesn't disambiguate between XCTest-the-module and XCTest-the-class.
16+
# rdar://48445154
17+
-Xfrontend -module-interface-preserve-types-as-written
1118
LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}"
1219
TARGET_SDKS OSX IOS IOS_SIMULATOR TVOS TVOS_SIMULATOR
1320
SWIFT_MODULE_DEPENDS ObjectiveC Foundation
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
public protocol AnExternalProtocol {}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-swift-frontend -emit-module-path %t/ExternalProtocol.swiftmodule %S/Inputs/external-protocol.swift -module-name ExternalProtocol
4+
// RUN: %target-swift-frontend -typecheck -I %t %s
5+
6+
import ExternalProtocol
7+
8+
extension AnExternalProtocol {
9+
typealias TypeAlias = Int
10+
11+
func methodUsingAlias(_ alias: Self.TypeAlias) {}
12+
}

0 commit comments

Comments
 (0)