Skip to content

Commit 7c8766f

Browse files
authored
Merge pull request #85571 from sepy97/desugar-inherited-ParaProtoType
ModuleInterface: Avoid printing generic arguments of a ParameterizedProtocolType in inheritance clause
2 parents 1b6da50 + 480b64e commit 7c8766f

File tree

2 files changed

+103
-1
lines changed

2 files changed

+103
-1
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8248,6 +8248,39 @@ static void getSyntacticInheritanceClause(const ProtocolDecl *proto,
82488248
}
82498249
}
82508250

8251+
static Type stripParameterizedProtocolArgs(Type type) {
8252+
if (!type)
8253+
return type;
8254+
8255+
// For each ParameterizedProtocolType process each member recursively
8256+
if (auto *compositionType = type->getAs<ProtocolCompositionType>()) {
8257+
SmallVector<Type, 4> processedMembers;
8258+
bool hasChanged = false;
8259+
for (auto member : compositionType->getMembers()) {
8260+
Type processedMember = stripParameterizedProtocolArgs(member);
8261+
if (!processedMember)
8262+
continue;
8263+
processedMembers.push_back(processedMember);
8264+
if (processedMember.getPointer() != member.getPointer())
8265+
hasChanged = true;
8266+
}
8267+
// Rebuild ProtocolCompositionType if at least one member had generic args
8268+
if (hasChanged) {
8269+
return ProtocolCompositionType::get(
8270+
type->getASTContext(), processedMembers,
8271+
compositionType->getInverses(),
8272+
compositionType->hasExplicitAnyObject());
8273+
}
8274+
return type;
8275+
}
8276+
8277+
// Strip generic arguments of a single ParameterizedProtocolType
8278+
if (auto *paramProto = type->getAs<ParameterizedProtocolType>()) {
8279+
return paramProto->getBaseType();
8280+
}
8281+
return type;
8282+
}
8283+
82518284
void
82528285
swift::getInheritedForPrinting(
82538286
const Decl *decl, const PrintOptions &options,
@@ -8317,7 +8350,16 @@ swift::getInheritedForPrinting(
83178350
}
83188351
}
83198352

8320-
Results.push_back(inherited.getEntry(i));
8353+
auto entry = inherited.getEntry(i);
8354+
if (auto type = entry.getType()) {
8355+
Type strippedType = stripParameterizedProtocolArgs(type);
8356+
if (strippedType.getPointer() != type.getPointer()) {
8357+
entry = InheritedEntry(TypeLoc::withoutLoc(strippedType),
8358+
entry.getOptions());
8359+
}
8360+
}
8361+
8362+
Results.push_back(entry);
83218363
}
83228364

83238365
// Collect synthesized conformances.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// RUN: %target-swift-emit-module-interface(%t/Fancy.swiftinterface) %s -module-name Library
2+
// RUN: %target-swift-typecheck-module-from-interface(%t/Fancy.swiftinterface) -module-name Library
3+
// RUN: %FileCheck %s < %t/Fancy.swiftinterface
4+
5+
public protocol Fancy<Stuff> {
6+
associatedtype Stuff
7+
}
8+
9+
// CHECK: public struct T : Library.Fancy {
10+
// CHECK: public typealias Stuff = Swift.Float64
11+
public struct T: Fancy<Float64> {
12+
}
13+
14+
public protocol Q {
15+
}
16+
17+
// CHECK: public struct S : Library.Fancy & Library.Q {
18+
// CHECK: public typealias Stuff = Swift.Int
19+
public struct S: Fancy<Int> & Q {
20+
}
21+
22+
public protocol P {
23+
}
24+
25+
// CHECK: public struct V : Library.Fancy & Library.P & Library.Q {
26+
// CHECK: public typealias Stuff = Swift.CChar32
27+
public struct V: ((Fancy<CChar32> & P) & Q) {
28+
}
29+
30+
public protocol Bar<T> {
31+
associatedtype T
32+
}
33+
34+
// CHECK: public struct X : Library.Bar & Library.Fancy
35+
// CHECK: public typealias Stuff = Swift.CChar32
36+
// CHECK: public typealias T = Swift.Int
37+
public struct X: Fancy<CChar32> & Bar<Int> {
38+
}
39+
40+
public class Base {
41+
}
42+
43+
public protocol B<A>: ~Copyable {
44+
associatedtype A
45+
}
46+
47+
// CHECK: public class Derived : Library.Base & Library.B {
48+
// CHECK: public typealias A = Swift.Int
49+
public class Derived: Base & B<Int> {
50+
}
51+
52+
public protocol R<E>: ~Copyable & ~Escapable {
53+
associatedtype E
54+
}
55+
56+
// CHECK: public struct N : Library.B & Library.R & ~Copyable {
57+
// CHECK: public typealias A = Swift.Float64
58+
// CHECK: public typealias E = Swift.Int
59+
public struct N: R<Int> & B<Float64> & ~Copyable {
60+
}

0 commit comments

Comments
 (0)