Skip to content

Commit 9a0efca

Browse files
authored
Merge pull request swiftlang#30548 from AnthonyLatsis/sr-7855
2 parents bdabeae + 1a4fe77 commit 9a0efca

File tree

5 files changed

+51
-26
lines changed

5 files changed

+51
-26
lines changed

include/swift/AST/Decl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,6 +1434,8 @@ class alignas(RequirementRepr) TrailingWhereClause final :
14341434
return SourceRange(WhereLoc,
14351435
getRequirements().back().getSourceRange().End);
14361436
}
1437+
1438+
void print(llvm::raw_ostream &OS, bool printWhereKeyword) const;
14371439
};
14381440

14391441
// A private class for forcing exact field layout.

lib/AST/ASTDumper.cpp

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,23 @@ void RequirementRepr::print(ASTPrinter &out) const {
164164
printImpl(out, /*AsWritten=*/true);
165165
}
166166

167+
static void printTrailingRequirements(ASTPrinter &Printer,
168+
ArrayRef<RequirementRepr> Reqs,
169+
bool printWhereKeyword) {
170+
if (Reqs.empty()) return;
171+
172+
if (printWhereKeyword)
173+
Printer << " where ";
174+
interleave(
175+
Reqs,
176+
[&](const RequirementRepr &req) {
177+
Printer.callPrintStructurePre(PrintStructureKind::GenericRequirement);
178+
req.print(Printer);
179+
Printer.printStructurePost(PrintStructureKind::GenericRequirement);
180+
},
181+
[&] { Printer << ", "; });
182+
}
183+
167184
void GenericParamList::print(llvm::raw_ostream &OS) const {
168185
OS << '<';
169186
interleave(*this,
@@ -176,14 +193,9 @@ void GenericParamList::print(llvm::raw_ostream &OS) const {
176193
},
177194
[&] { OS << ", "; });
178195

179-
if (!getRequirements().empty()) {
180-
OS << " where ";
181-
interleave(getRequirements(),
182-
[&](const RequirementRepr &req) {
183-
req.print(OS);
184-
},
185-
[&] { OS << ", "; });
186-
}
196+
StreamPrinter Printer(OS);
197+
printTrailingRequirements(Printer, getRequirements(),
198+
/*printWhereKeyword*/true);
187199
OS << '>';
188200
}
189201

@@ -192,6 +204,13 @@ void GenericParamList::dump() const {
192204
llvm::errs() << '\n';
193205
}
194206

207+
void TrailingWhereClause::print(llvm::raw_ostream &OS,
208+
bool printWhereKeyword) const {
209+
StreamPrinter Printer(OS);
210+
printTrailingRequirements(Printer, getRequirements(),
211+
printWhereKeyword);
212+
}
213+
195214
static void printGenericParameters(raw_ostream &OS, GenericParamList *Params) {
196215
if (!Params)
197216
return;
@@ -664,9 +683,7 @@ namespace {
664683
}
665684
if (auto whereClause = decl->getTrailingWhereClause()) {
666685
OS << " where requirements: ";
667-
interleave(whereClause->getRequirements(),
668-
[&](const RequirementRepr &req) { req.print(OS); },
669-
[&] { OS << ", "; });
686+
whereClause->print(OS, /*printWhereKeyword*/false);
670687
}
671688
if (decl->overriddenDeclsComputed()) {
672689
OS << " overridden=";

lib/AST/ASTPrinter.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -802,7 +802,6 @@ class PrintAST : public ASTVisitor<PrintAST> {
802802
Decl *attachingTo);
803803
void printWhereClauseFromRequirementSignature(ProtocolDecl *proto,
804804
Decl *attachingTo);
805-
void printTrailingWhereClause(TrailingWhereClause *whereClause);
806805

807806
void printGenericSignature(GenericSignature genericSig,
808807
unsigned flags);
@@ -1361,18 +1360,6 @@ void PrintAST::printWhereClauseFromRequirementSignature(ProtocolDecl *proto,
13611360
});
13621361
}
13631362

1364-
void PrintAST::printTrailingWhereClause(TrailingWhereClause *whereClause) {
1365-
Printer << " " << tok::kw_where << " ";
1366-
interleave(
1367-
whereClause->getRequirements(),
1368-
[&](const RequirementRepr &req) {
1369-
Printer.callPrintStructurePre(PrintStructureKind::GenericRequirement);
1370-
req.print(Printer);
1371-
Printer.printStructurePost(PrintStructureKind::GenericRequirement);
1372-
},
1373-
[&] { Printer << ", "; });
1374-
}
1375-
13761363
/// A helper function to return the depth of a requirement.
13771364
static unsigned getDepthOfRequirement(const Requirement &req) {
13781365
switch (req.getKind()) {

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3940,8 +3940,8 @@ ConstraintResult GenericSignatureBuilder::expandConformanceRequirement(
39403940

39413941
// Retrieve the set of requirements that a given associated type declaration
39423942
// produces, in the form that would be seen in the where clause.
3943-
auto getAssociatedTypeReqs = [&](AssociatedTypeDecl *assocType,
3944-
const char *start) {
3943+
const auto getAssociatedTypeReqs = [&](const AssociatedTypeDecl *assocType,
3944+
const char *start) {
39453945
std::string result;
39463946
{
39473947
llvm::raw_string_ostream out(result);
@@ -3955,6 +3955,13 @@ ConstraintResult GenericSignatureBuilder::expandConformanceRequirement(
39553955
}, [&] {
39563956
out << ", ";
39573957
});
3958+
3959+
if (const auto whereClause = assocType->getTrailingWhereClause()) {
3960+
if (!assocType->getInherited().empty())
3961+
out << ", ";
3962+
3963+
whereClause->print(out, /*printWhereKeyword*/false);
3964+
}
39583965
}
39593966
return result;
39603967
};

test/Generics/associated_type_where_clause_hints.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ struct X1 { }
99

1010
protocol P1 {
1111
associatedtype A // expected-note 2{{'A' declared here}}
12+
associatedtype A2 // expected-note {{'A2' declared here}}
13+
associatedtype A3 // expected-note {{'A3' declared here}}
14+
associatedtype A4 // expected-note {{'A4' declared here}}
1215
}
1316

1417
// A typealias in a subprotocol should be written as a same-type
@@ -21,6 +24,13 @@ protocol P2 : P1 {
2124
// should be written via a where clause.
2225
protocol P3a : P1 {
2326
associatedtype A: P0, P0b // expected-warning{{redeclaration of associated type 'A' from protocol 'P1' is better expressed as a 'where' clause on the protocol}}{{18-18= where A: P0, A: P0b}}{{3-29=}}
27+
associatedtype A2: P0, P0b where A2.A == Never, A2: P1 // expected-warning{{redeclaration of associated type 'A2' from protocol 'P1' is better expressed as a 'where' clause on the protocol}}{{18-18= where A2: P0, A2: P0b, A2.A == Never, A2 : P1}}{{3-58=}}
28+
associatedtype A3 where A3: P0 // expected-warning{{redeclaration of associated type 'A3' from protocol 'P1' is better expressed as a 'where' clause on the protocol}}{{18-18= where A3 : P0}}{{3-34=}}
29+
30+
// expected-warning@+1 {{redeclaration of associated type 'A4' from protocol 'P1' is better expressed as a 'where' clause on the protocol}}{{18-18= where A4: P0, A4 : Collection, A4.Element == A4.Index, A4.SubSequence == A4}}{{3-52=}}
31+
associatedtype A4: P0 where A4: Collection,
32+
A4.Element == A4.Index,
33+
A4.SubSequence == A4 // {{3-52=}} is this line, so it is correct.
2434
}
2535

2636
// ... unless it has adds a default type witness
@@ -30,10 +40,12 @@ protocol P3b : P1 {
3040

3141
protocol P4: P1 {
3242
associatedtype B // expected-note{{'B' declared here}}
43+
associatedtype B2 // expected-note{{'B2' declared here}}
3344
}
3445

3546
protocol P5: P4 where A: P0 {
3647
typealias B = X1 // expected-warning{{typealias overriding associated type 'B' from protocol 'P4' is better expressed as same-type constraint on the protocol}}{{28-28=, B == X1}}{{3-20=}}
48+
associatedtype B2: P5 // expected-warning{{redeclaration of associated type 'B2' from protocol 'P4' is better expressed as a 'where' clause on the protocol}}{{28-28=, B2: P5}} {{3-25=}}
3749
}
3850

3951

0 commit comments

Comments
 (0)