Skip to content

Commit 85068f0

Browse files
authored
Merge pull request #76300 from tshortli/module-interface-patterns-with-opaque-results
ModuleInterface: Print patterns with opaque result types using `some` keyword
2 parents d653a01 + a770371 commit 85068f0

File tree

4 files changed

+64
-22
lines changed

4 files changed

+64
-22
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,24 @@ static bool shouldPrintAllSemanticDetails(const PrintOptions &options) {
182182
return false;
183183
}
184184

185+
/// Forces printing types with the `some` keyword, instead of the full stable
186+
/// reference.
187+
struct PrintWithOpaqueResultTypeKeywordRAII {
188+
PrintWithOpaqueResultTypeKeywordRAII(PrintOptions &Options)
189+
: Options(Options) {
190+
SavedMode = Options.OpaqueReturnTypePrinting;
191+
Options.OpaqueReturnTypePrinting =
192+
PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword;
193+
}
194+
~PrintWithOpaqueResultTypeKeywordRAII() {
195+
Options.OpaqueReturnTypePrinting = SavedMode;
196+
}
197+
198+
private:
199+
PrintOptions &Options;
200+
PrintOptions::OpaqueReturnTypePrintingMode SavedMode;
201+
};
202+
185203
PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
186204
bool preferTypeRepr,
187205
bool printFullConvention,
@@ -1317,6 +1335,8 @@ void PrintAST::printTypedPattern(const TypedPattern *TP) {
13171335
printPattern(TP->getSubPattern());
13181336
Printer << ": ";
13191337

1338+
PrintWithOpaqueResultTypeKeywordRAII x(Options);
1339+
13201340
// Make sure to check if the underlying var decl is an implicitly unwrapped
13211341
// optional.
13221342
bool isIUO = false;
@@ -3745,13 +3765,7 @@ void PrintAST::visitVarDecl(VarDecl *decl) {
37453765
}
37463766
Printer.printDeclResultTypePre(decl, tyLoc);
37473767

3748-
// HACK: When printing result types for vars with opaque result types,
3749-
// always print them using the `some` keyword instead of printing
3750-
// the full stable reference.
3751-
llvm::SaveAndRestore<PrintOptions::OpaqueReturnTypePrintingMode>
3752-
x(Options.OpaqueReturnTypePrinting,
3753-
PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword);
3754-
3768+
PrintWithOpaqueResultTypeKeywordRAII x(Options);
37553769
printTypeLocForImplicitlyUnwrappedOptional(
37563770
tyLoc, decl->isImplicitlyUnwrappedOptional());
37573771
}
@@ -4127,13 +4141,7 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) {
41274141
}
41284142
}
41294143

4130-
// HACK: When printing result types for funcs with opaque result types,
4131-
// always print them using the `some` keyword instead of printing
4132-
// the full stable reference.
4133-
llvm::SaveAndRestore<PrintOptions::OpaqueReturnTypePrintingMode>
4134-
x(Options.OpaqueReturnTypePrinting,
4135-
PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword);
4136-
4144+
PrintWithOpaqueResultTypeKeywordRAII x(Options);
41374145
printTypeLocForImplicitlyUnwrappedOptional(
41384146
ResultTyLoc, decl->isImplicitlyUnwrappedOptional());
41394147
Printer.printStructurePost(PrintStructureKind::FunctionReturnType);
@@ -4283,13 +4291,7 @@ void PrintAST::visitSubscriptDecl(SubscriptDecl *decl) {
42834291
Printer.printDeclResultTypePre(decl, elementTy);
42844292
Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);
42854293

4286-
// HACK: When printing result types for subscripts with opaque result types,
4287-
// always print them using the `some` keyword instead of printing
4288-
// the full stable reference.
4289-
llvm::SaveAndRestore<PrintOptions::OpaqueReturnTypePrintingMode>
4290-
x(Options.OpaqueReturnTypePrinting,
4291-
PrintOptions::OpaqueReturnTypePrintingMode::WithOpaqueKeyword);
4292-
4294+
PrintWithOpaqueResultTypeKeywordRAII x(Options);
42934295
printTypeLocForImplicitlyUnwrappedOptional(
42944296
elementTy, decl->isImplicitlyUnwrappedOptional());
42954297
Printer.printStructurePost(PrintStructureKind::FunctionReturnType);

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2771,7 +2771,18 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
27712771
// Properties with an opaque return type need an initializer to
27722772
// determine their underlying type.
27732773
if (var->getOpaqueResultTypeDecl()) {
2774-
var->diagnose(diag::opaque_type_var_no_init);
2774+
// ...but don't enforce this for SIL or module interface files.
2775+
switch (SF->Kind) {
2776+
case SourceFileKind::Interface:
2777+
case SourceFileKind::SIL:
2778+
break;
2779+
case SourceFileKind::DefaultArgument:
2780+
case SourceFileKind::Main:
2781+
case SourceFileKind::Library:
2782+
case SourceFileKind::MacroExpansion:
2783+
var->diagnose(diag::opaque_type_var_no_init);
2784+
break;
2785+
}
27752786
}
27762787

27772788
// Non-member observing properties need an initializer.

test/ModuleInterface/Inputs/opaque-result-types-client.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,19 @@ func someTypeIsTheSame() {
6060
f = barString.foo(MyFoo()) // expected-error{{cannot assign}}
6161
f = barInt.foo(YourFoo()) // expected-error{{cannot convert value of type 'YourFoo' to expected argument type 'MyFoo'}}
6262
f = barString.foo(MyFoo()) // expected-error{{cannot assign}}
63+
64+
var g = globalComputedVar
65+
g = globalVar // expected-error{{cannot assign}}
66+
g = globalComputedVar
67+
g = 123 // expected-error{{cannot assign}}
68+
69+
var h = globalVar
70+
h = globalComputedVar // expected-error{{cannot assign}}
71+
h = globalVar
72+
h = 123 // expected-error{{cannot assign}}
73+
74+
var i = globalVarTuple
75+
i = (123, foo(123)) // expected-error{{cannot assign}}
76+
i = globalVarTuple
77+
i = (globalVarTuple.0, globalVarTuple.1)
6378
}

test/ModuleInterface/opaque-result-types.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,20 @@ public func foo<T: Foo>(_ x: T) -> some Foo {
2525
return x
2626
}
2727

28+
// CHECK-LABEL: public var globalComputedVar: some OpaqueResultTypes.Foo {
29+
// CHECK-NEXT: get
30+
// CHECK-NEXT: }
31+
@available(SwiftStdlib 5.1, *)
32+
public var globalComputedVar: some Foo { 123 }
33+
34+
// CHECK-LABEL: public var globalVar: some OpaqueResultTypes.Foo{{$}}
35+
@available(SwiftStdlib 5.1, *)
36+
public var globalVar: some Foo = 123
37+
38+
// CHECK-LABEL: public var globalVarTuple: (some OpaqueResultTypes.Foo, some OpaqueResultTypes.Foo){{$}}
39+
@available(SwiftStdlib 5.1, *)
40+
public var globalVarTuple: (some Foo, some Foo) = (123, foo(123))
41+
2842
public protocol AssocTypeInference {
2943
associatedtype Assoc: Foo
3044
associatedtype AssocProperty: Foo

0 commit comments

Comments
 (0)