Skip to content

Commit 47ca44c

Browse files
committed
SIL: Fix printing of opaque parameter types
While printing them as `some P` makes sense in the AST since they only ever appear at their definition point, in the body of a SIL function, opaque parameter types can be referenced by various instructions, like any other generic parameter type. Instead of printing out `some P` or `<anonymous>` depending on context, neither of which actually parsed, instead print them with the canonical type `τ_d_i` notation. Since it's printed this way in the generic parameter list as well, it parses back in. Fixes rdar://problem/119823811.
1 parent 9e2123b commit 47ca44c

File tree

4 files changed

+38
-2
lines changed

4 files changed

+38
-2
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7756,10 +7756,20 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
77567756
// canonical types to sugared types.
77577757
if (Options.GenericSig)
77587758
T = Options.GenericSig->getSugaredType(T);
7759+
7760+
decl = T->getDecl();
77597761
}
77607762

77617763
// Print opaque types as "some ..."
77627764
if (decl && decl->isOpaqueType()) {
7765+
// For SIL, we print opaque parameter types as canonical types, and parse
7766+
// them that way too (because they're printed in this way in the SIL
7767+
// generic parameter list).
7768+
if (Options.PrintInSILBody) {
7769+
Printer.printName(cast<GenericTypeParamType>(T->getCanonicalType())->getName());
7770+
return;
7771+
}
7772+
77637773
// If we have and should print based on the type representation, do so.
77647774
if (auto opaqueRepr = decl->getOpaqueTypeRepr()) {
77657775
if (willUseTypeReprPrinting(opaqueRepr, Type(), Options)) {

lib/SIL/IR/SILPrinter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,12 @@ static void printSILFunctionNameAndType(
526526
for (auto *paramTy : genSig.getGenericParams()) {
527527
// Get a uniqued sugared name for the generic parameter type.
528528
auto sugaredTy = genEnv->getGenericSignature()->getSugaredType(paramTy);
529+
530+
// Opaque parameter types are printed as their canonical types and not
531+
// the unparseable "<anonymous>".
532+
if (sugaredTy->getDecl() && sugaredTy->getDecl()->isOpaqueType())
533+
continue;
534+
529535
Identifier name = sugaredTy->getName();
530536
while (!usedNames.insert(name).second) {
531537
disambiguatedNameBuf.clear();
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
// RUN: %target-swift-frontend -emit-silgen %s | %target-sil-opt | %FileCheck %s
3+
4+
protocol P {}
5+
6+
func bar(_: some P) {}
7+
8+
func foo(_ x: some P) {
9+
bar(x)
10+
}
11+
12+
// CHECK-LABEL: sil hidden [ossa] @$s26opaque_parameter_roundtrip3fooyyxAA1PRzlF : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> () {
13+
// CHECK: bb0(%0 : $*τ_0_0):
14+
// CHECK-NEXT: debug_value %0 : $*τ_0_0, let, name "x", argno 1, expr op_deref
15+
// CHECK-NEXT: // function_ref bar<A>(_:)
16+
// CHECK-NEXT: [[FN:%.*]] = function_ref @$s26opaque_parameter_roundtrip3baryyxAA1PRzlF : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
17+
// CHECK-NEXT: apply [[FN]]<τ_0_0>(%0) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
18+
// CHECK-NEXT: [[RESULT:%.*]] = tuple ()
19+
// CHECK-NEXT: return [[RESULT]] : $()
20+
// CHECK-NEXT: } // end sil function '$s26opaque_parameter_roundtrip3fooyyxAA1PRzlF'

test/SILGen/objc_async.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,9 +303,9 @@ extension OptionalMemberLookups {
303303
}
304304

305305

306-
// CHECK-LABEL: sil {{.*}} @$s10objc_async12checkHotdogsySSSgx_So8NSObjectCtYaKSo16HotdogCompetitorRzlF
306+
// CHECK-LABEL: sil {{.*}} @$s10objc_async12checkHotdogsySSSgx_So8NSObjectCtYaKSo16HotdogCompetitorRzlF : $@convention(thin) @async <τ_0_0 where τ_0_0 : HotdogCompetitor> (@guaranteed τ_0_0, @guaranteed NSObject) -> (@owned Optional<String>, @error any Error) {
307307
// CHECK: hop_to_executor {{.*}} : $MainActor
308-
// CHECK: [[AUTO_REL_STR:%.*]] = apply {{.*}}<some HotdogCompetitor>({{.*}}) : $@convention(objc_method)
308+
// CHECK: [[AUTO_REL_STR:%.*]] = apply {{.*}}<τ_0_0>({{.*}}) : $@convention(objc_method)
309309
// CHECK: [[UNMANAGED_OPTIONAL:%.*]] = load [trivial] {{.*}} : $*@sil_unmanaged Optional<NSError>
310310
// CHECK: [[MANAGED_OPTIONAL:%.*]] = unmanaged_to_ref [[UNMANAGED_OPTIONAL]] : $@sil_unmanaged Optional<NSError> to $Optional<NSError>
311311
// CHECK: [[RETAINED_OPTIONAL:%.*]] = copy_value [[MANAGED_OPTIONAL]] : $Optional<NSError>

0 commit comments

Comments
 (0)