Skip to content

Commit a7e0f9c

Browse files
committed
ASTPrinter: Refactor printing of RequirementSignatures
1 parent 5aa9f53 commit a7e0f9c

File tree

7 files changed

+110
-22
lines changed

7 files changed

+110
-22
lines changed

include/swift/AST/RequirementSignature.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,16 @@ class RequirementSignature final {
7373
GenericSignatureErrors getErrors() const {
7474
return Errors;
7575
}
76+
77+
void getRequirementsWithInverses(
78+
ProtocolDecl *owner,
79+
SmallVector<Requirement, 2> &reqs,
80+
SmallVector<InverseRequirement, 2> &inverses) const;
81+
82+
void print(ProtocolDecl *owner, raw_ostream &OS,
83+
const PrintOptions &Options = PrintOptions()) const;
84+
void print(ProtocolDecl *owner, ASTPrinter &Printer,
85+
const PrintOptions &Opts = PrintOptions()) const;
7686
};
7787

7888
} // end namespace swift

lib/AST/ASTPrinter.cpp

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,10 @@ class PrintAST : public ASTVisitor<PrintAST> {
970970
ArrayRef<InverseRequirement> inverses,
971971
bool &isFirstReq, unsigned flags,
972972
llvm::function_ref<bool(const Requirement &)> filter);
973+
void printRequirementSignature(ProtocolDecl *owner,
974+
RequirementSignature sig,
975+
unsigned flags,
976+
llvm::function_ref<bool(const Requirement &)> filter);
973977
void printRequirement(const Requirement &req);
974978
void printRequirement(const InverseRequirement &inverse,
975979
bool forInherited);
@@ -1575,9 +1579,8 @@ void PrintAST::printInheritedFromRequirementSignature(ProtocolDecl *proto,
15751579
else
15761580
llvm_unreachable("nonexhaustive");
15771581

1578-
printGenericSignature(
1579-
proto->getRequirementSignatureAsGenericSignature(),
1580-
PrintInherited,
1582+
printRequirementSignature(
1583+
proto, proto->getRequirementSignature(), PrintInherited,
15811584
[&](const Requirement &req) {
15821585
// Skip the inferred 'Self : AnyObject' constraint if this is an
15831586
// @objc protocol.
@@ -1926,6 +1929,25 @@ void PrintAST::printSingleDepthOfGenericSignature(
19261929
Printer << ">";
19271930
}
19281931

1932+
void PrintAST::printRequirementSignature(ProtocolDecl *owner,
1933+
RequirementSignature sig,
1934+
unsigned flags,
1935+
llvm::function_ref<bool(const Requirement &)> filter) {
1936+
SmallVector<Requirement, 2> requirements;
1937+
SmallVector<InverseRequirement, 2> inverses;
1938+
1939+
if (flags & PrintInverseRequirements) {
1940+
sig.getRequirementsWithInverses(owner, requirements, inverses);
1941+
} else {
1942+
requirements.append(sig.getRequirements().begin(),
1943+
sig.getRequirements().end());
1944+
}
1945+
1946+
printSingleDepthOfGenericSignature(
1947+
owner->getGenericSignature().getGenericParams(), requirements, inverses,
1948+
flags, filter);
1949+
}
1950+
19291951
void PrintAST::printRequirement(const Requirement &req) {
19301952
SmallVector<Type, 2> rootParameterPacks;
19311953
getTransformedType(req.getFirstType())
@@ -7949,6 +7971,23 @@ void GenericSignature::print(ASTPrinter &Printer,
79497971
PrintAST(Printer, Opts).printGenericSignature(*this, flags);
79507972
}
79517973

7974+
void RequirementSignature::print(ProtocolDecl *owner,
7975+
raw_ostream &OS,
7976+
const PrintOptions &Opts) const {
7977+
StreamPrinter Printer(OS);
7978+
print(owner, Printer, Opts);
7979+
}
7980+
7981+
void RequirementSignature::print(ProtocolDecl *owner,
7982+
ASTPrinter &Printer,
7983+
const PrintOptions &Opts) const {
7984+
auto flags = PrintAST::PrintParams | PrintAST::PrintRequirements;
7985+
if (Opts.PrintInverseRequirements)
7986+
flags |= PrintAST::PrintInverseRequirements;
7987+
PrintAST(Printer, Opts).printRequirementSignature(owner, *this, flags,
7988+
[](Requirement) { return true; });
7989+
}
7990+
79527991
void Requirement::print(raw_ostream &os, const PrintOptions &opts) const {
79537992
StreamPrinter printer(os);
79547993
PrintAST(printer, opts).printRequirement(*this);

lib/AST/GenericSignature.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,6 +1285,62 @@ void GenericSignatureImpl::getRequirementsWithInverses(
12851285
continue;
12861286
}
12871287

1288+
reqs.push_back(req);
1289+
}
1290+
}
1291+
1292+
void RequirementSignature::getRequirementsWithInverses(
1293+
ProtocolDecl *owner,
1294+
SmallVector<Requirement, 2> &reqs,
1295+
SmallVector<InverseRequirement, 2> &inverses) const {
1296+
auto &ctx = owner->getASTContext();
1297+
1298+
if (!SWIFT_ENABLE_EXPERIMENTAL_NONCOPYABLE_GENERICS) {
1299+
reqs.append(getRequirements().begin(), getRequirements().end());
1300+
return;
1301+
}
1302+
1303+
auto sig = owner->getGenericSignature();
1304+
1305+
llvm::SmallDenseSet<CanType, 2> assocTypes;
1306+
1307+
auto visit = [&](Type interfaceType) {
1308+
assocTypes.insert(interfaceType->getCanonicalType());
1309+
1310+
// Any associated type declaration with a superclass bound or concrete type
1311+
// does not have an inverse.
1312+
if (sig->getSuperclassBound(interfaceType) ||
1313+
sig->getConcreteType(interfaceType))
1314+
return;
1315+
1316+
for (auto ip : InvertibleProtocolSet::full()) {
1317+
auto *proto = ctx.getProtocol(getKnownProtocolKind(ip));
1318+
1319+
// If we can derive a conformance to this protocol, then don't add an
1320+
// inverse.
1321+
if (sig->requiresProtocol(interfaceType, proto))
1322+
continue;
1323+
1324+
// Nothing implies a conformance to this protocol, so record the inverse.
1325+
inverses.push_back({interfaceType, proto, SourceLoc()});
1326+
}
1327+
};
1328+
1329+
visit(owner->getSelfInterfaceType());
1330+
1331+
// Record the absence of conformances to invertible protocols.
1332+
for (auto assocType : owner->getAssociatedTypeMembers()) {
1333+
visit(assocType->getDeclaredInterfaceType());
1334+
}
1335+
1336+
// Filter out explicit conformances to invertible protocols.
1337+
for (auto req : getRequirements()) {
1338+
if (req.getKind() == RequirementKind::Conformance &&
1339+
assocTypes.count(req.getFirstType()->getCanonicalType()) &&
1340+
req.getProtocolDecl()->getInvertibleProtocolKind()) {
1341+
continue;
1342+
}
1343+
12881344
reqs.push_back(req);
12891345
}
12901346
}

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3448,7 +3448,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
34483448
TypeChecker::inferDefaultWitnesses(PD);
34493449

34503450
if (Ctx.TypeCheckerOpts.DebugGenericSignatures) {
3451-
auto sig = PD->getRequirementSignatureAsGenericSignature();
3451+
auto sig = PD->getRequirementSignature();
34523452
llvm::errs() << "\n";
34533453
llvm::errs() << "Protocol requirement signature:\n";
34543454
PD->dumpRef(llvm::errs());
@@ -3457,14 +3457,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
34573457
PrintOptions Opts;
34583458
Opts.ProtocolQualifiedDependentMemberTypes = true;
34593459
Opts.PrintInverseRequirements = true;
3460-
sig->print(llvm::errs(), Opts);
3461-
llvm::errs() << "\n";
3462-
3463-
llvm::errs() << "Canonical requirement signature: ";
3464-
auto canSig =
3465-
CanGenericSignature::getCanonical(sig.getGenericParams(),
3466-
sig.getRequirements());
3467-
canSig->print(llvm::errs(), Opts);
3460+
sig.print(PD, llvm::errs(), Opts);
34683461
llvm::errs() << "\n";
34693462
}
34703463

test/Frontend/debug-generic-signatures.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
// CHECK-NEXT: Canonical generic signature: <τ_0_0 where τ_0_0 : P1>
55
// CHECK-LABEL: main.(file).P1@
66
// CHECK: Requirement signature: <Self>
7-
// CHECK-NEXT: Canonical requirement signature: <τ_0_0>
87
protocol P1 {
98
associatedtype A
109
func f() -> A
@@ -15,7 +14,6 @@ protocol P1 {
1514
// CHECK-NEXT: Canonical generic signature: <τ_0_0 where τ_0_0 : P2>
1615
// CHECK-LABEL: main.(file).P2@
1716
// CHECK: Requirement signature: <Self where Self.[P2]A : P2, Self.[P2]B : P2, Self.[P2]A.[P2]A == Self.[P2]B.[P2]A>
18-
// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.[P2]A : P2, τ_0_0.[P2]B : P2, τ_0_0.[P2]A.[P2]A == τ_0_0.[P2]B.[P2]A>
1917
protocol P2 {
2018
associatedtype A: P2
2119
associatedtype B: P2 where Self.A.A == Self.B.A
@@ -26,7 +24,6 @@ protocol P2 {
2624
// CHECK-NEXT: Canonical generic signature: <τ_0_0 where τ_0_0 : P3>
2725
// CHECK-LABEL: main.(file).P3@
2826
// CHECK: Requirement signature: <Self where Self.[P3]A : P3>
29-
// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.[P3]A : P3>
3027
protocol P3 {
3128
associatedtype A: P3
3229
}

test/Generics/derived_via_concrete_in_protocol.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,20 @@ class X3 { }
2323

2424
// CHECK-LABEL: .P25a@
2525
// CHECK-NEXT: Requirement signature: <Self where Self.[P25a]A == X24<Self.[P25a]B>, Self.[P25a]B : P20>
26-
// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.[P25a]A == X24<τ_0_0.[P25a]B>, τ_0_0.[P25a]B : P20>
2726
protocol P25a {
2827
associatedtype A: P24 // expected-warning{{redundant conformance constraint 'X24<Self.B>' : 'P24'}}
2928
associatedtype B: P20 where A == X24<B>
3029
}
3130

3231
// CHECK-LABEL: .P25b@
3332
// CHECK-NEXT: Requirement signature: <Self where Self.[P25b]A == X24<Self.[P25b]B>, Self.[P25b]B : P20>
34-
// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.[P25b]A == X24<τ_0_0.[P25b]B>, τ_0_0.[P25b]B : P20>
3533
protocol P25b {
3634
associatedtype A
3735
associatedtype B: P20 where A == X24<B>
3836
}
3937

4038
// CHECK-LABEL: .P27a@
4139
// CHECK-NEXT: Requirement signature: <Self where Self.[P27a]A == X26<Self.[P27a]B>, Self.[P27a]B : X3>
42-
// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.[P27a]A == X26<τ_0_0.[P27a]B>, τ_0_0.[P27a]B : X3>
4340
protocol P27a {
4441
associatedtype A: P26 // expected-warning{{redundant conformance constraint 'X26<Self.B>' : 'P26'}}
4542

@@ -48,7 +45,6 @@ protocol P27a {
4845

4946
// CHECK-LABEL: .P27b@
5047
// CHECK-NEXT: Requirement signature: <Self where Self.[P27b]A == X26<Self.[P27b]B>, Self.[P27b]B : X3>
51-
// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.[P27b]A == X26<τ_0_0.[P27b]B>, τ_0_0.[P27b]B : X3>
5248
protocol P27b {
5349
associatedtype A
5450
associatedtype B: X3 where A == X26<B>

test/Generics/requirement_inference.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,6 @@ struct X22<T, U> {
287287
// CHECK: Protocol requirement signature:
288288
// CHECK: .P22@
289289
// CHECK-NEXT: Requirement signature: <Self where Self.[P22]A == X20<Self.[P22]B>, Self.[P22]B : P20>
290-
// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.[P22]A == X20<τ_0_0.[P22]B>, τ_0_0.[P22]B : P20>
291290
protocol P22 {
292291
associatedtype A
293292
associatedtype B: P20 where A == X20<B>
@@ -298,7 +297,6 @@ protocol P22 {
298297
// CHECK: Protocol requirement signature:
299298
// CHECK: .P23@
300299
// CHECK-NEXT: Requirement signature: <Self where Self.[P23]A == X20<Self.[P23]B>, Self.[P23]B : P20>
301-
// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.[P23]A == X20<τ_0_0.[P23]B>, τ_0_0.[P23]B : P20>
302300
protocol P23 {
303301
associatedtype A
304302
associatedtype B: P20
@@ -333,7 +331,6 @@ struct X28 : P2 {
333331

334332
// CHECK-LABEL: .P28@
335333
// CHECK-NEXT: Requirement signature: <Self where Self : P3, Self.[P3]P3Assoc == X28>
336-
// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0 : P3, τ_0_0.[P3]P3Assoc == X28>
337334
protocol P28: P3 {
338335
typealias P3Assoc = X28 // expected-warning{{typealias overriding associated type}}
339336
}

0 commit comments

Comments
 (0)