Skip to content

Commit 15f216e

Browse files
committed
Fix ASTPrinter for substituted SILFunctionTypes to print the interface type in its own generic context
1 parent 800f7d6 commit 15f216e

File tree

1 file changed

+63
-38
lines changed

1 file changed

+63
-38
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 63 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4003,54 +4003,79 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
40034003
printFunctionExtInfo(T->getExtInfo(),
40044004
T->getWitnessMethodConformanceOrNone());
40054005
printCalleeConvention(T->getCalleeConvention());
4006-
if (auto sig = T->getSubstGenericSignature()) {
4007-
printGenericSignature(sig,
4008-
PrintAST::PrintParams |
4009-
PrintAST::PrintRequirements);
4010-
Printer << " ";
4011-
if (T->isGenericSignatureImplied()) {
4012-
Printer << "in ";
4013-
}
4006+
4007+
// If this is a substituted function type, then its generic signature is
4008+
// independent of the enclosing context, and defines the parameters active
4009+
// in the interface params and results. Unsubstituted types use the existing
4010+
// environment, which may be a sil decl's generic environment.
4011+
//
4012+
// Yeah, this is fiddly. In the end, we probably want all decls to have
4013+
// substituted types in terms of a generic signature declared on the decl,
4014+
// which would make this logic more uniform.
4015+
TypePrinter *sub = this;
4016+
Optional<TypePrinter> subBuffer;
4017+
PrintOptions subOptions = Options;
4018+
if (T->getSubstitutions()) {
4019+
subOptions.GenericEnv = nullptr;
4020+
subBuffer.emplace(Printer, subOptions);
4021+
sub = &*subBuffer;
40144022
}
4023+
4024+
// Capture list used here to ensure we don't print anything using `this`
4025+
// printer, but only the sub-Printer.
4026+
[T, sub, &subOptions]{
4027+
if (auto sig = T->getSubstGenericSignature()) {
4028+
sub->printGenericSignature(sig,
4029+
PrintAST::PrintParams |
4030+
PrintAST::PrintRequirements);
4031+
sub->Printer << " ";
4032+
if (T->isGenericSignatureImplied()) {
4033+
sub->Printer << "in ";
4034+
}
4035+
}
40154036

4016-
Printer << "(";
4017-
bool first = true;
4018-
for (auto param : T->getParameters()) {
4019-
Printer.printSeparator(first, ", ");
4020-
param.print(Printer, Options);
4021-
}
4022-
Printer << ") -> ";
4037+
sub->Printer << "(";
4038+
bool first = true;
4039+
for (auto param : T->getParameters()) {
4040+
sub->Printer.printSeparator(first, ", ");
4041+
param.print(sub->Printer, subOptions);
4042+
}
4043+
sub->Printer << ") -> ";
40234044

4024-
unsigned totalResults =
4025-
T->getNumYields() + T->getNumResults() + unsigned(T->hasErrorResult());
4045+
unsigned totalResults =
4046+
T->getNumYields() + T->getNumResults() + unsigned(T->hasErrorResult());
40264047

4027-
if (totalResults != 1) Printer << "(";
4048+
if (totalResults != 1)
4049+
sub->Printer << "(";
40284050

4029-
first = true;
4051+
first = true;
40304052

4031-
for (auto yield : T->getYields()) {
4032-
Printer.printSeparator(first, ", ");
4033-
Printer << "@yields ";
4034-
yield.print(Printer, Options);
4035-
}
4053+
for (auto yield : T->getYields()) {
4054+
sub->Printer.printSeparator(first, ", ");
4055+
sub->Printer << "@yields ";
4056+
yield.print(sub->Printer, subOptions);
4057+
}
40364058

4037-
for (auto result : T->getResults()) {
4038-
Printer.printSeparator(first, ", ");
4039-
result.print(Printer, Options);
4040-
}
4059+
for (auto result : T->getResults()) {
4060+
sub->Printer.printSeparator(first, ", ");
4061+
result.print(sub->Printer, subOptions);
4062+
}
40414063

4042-
if (T->hasErrorResult()) {
4043-
// The error result is implicitly @owned; don't print that.
4044-
assert(T->getErrorResult().getConvention() == ResultConvention::Owned);
4045-
Printer.printSeparator(first, ", ");
4046-
Printer << "@error ";
4047-
T->getErrorResult().getInterfaceType().print(Printer, Options);
4048-
}
4064+
if (T->hasErrorResult()) {
4065+
// The error result is implicitly @owned; don't print that.
4066+
assert(T->getErrorResult().getConvention() == ResultConvention::Owned);
4067+
sub->Printer.printSeparator(first, ", ");
4068+
sub->Printer << "@error ";
4069+
T->getErrorResult().getInterfaceType().print(sub->Printer, subOptions);
4070+
}
40494071

4050-
if (totalResults != 1) Printer << ")";
4072+
if (totalResults != 1)
4073+
sub->Printer << ")";
4074+
}();
40514075

4076+
// The substitution types are always in terms of the outer environment.
40524077
if (auto substitutions = T->getSubstitutions()) {
4053-
Printer << " for ";
4078+
Printer << " for";
40544079
printSubstitutions(substitutions);
40554080
}
40564081
}
@@ -4073,7 +4098,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
40734098
[&sub, T]{
40744099
if (auto sig = T->getLayout()->getGenericSignature()) {
40754100
sub.printGenericSignature(sig,
4076-
PrintAST::PrintParams | PrintAST::PrintRequirements);
4101+
PrintAST::PrintParams | PrintAST::PrintRequirements);
40774102
sub.Printer << " ";
40784103
}
40794104
sub.Printer << "{";

0 commit comments

Comments
 (0)