Skip to content

Commit 0367f8a

Browse files
committed
Fix ASTPrinter for substituted SILFunctionTypes to print the interface type in its own generic context
1 parent 4d6392b commit 0367f8a

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

4019-
Printer << "(";
4020-
bool first = true;
4021-
for (auto param : T->getParameters()) {
4022-
Printer.printSeparator(first, ", ");
4023-
param.print(Printer, Options);
4024-
}
4025-
Printer << ") -> ";
4040+
sub->Printer << "(";
4041+
bool first = true;
4042+
for (auto param : T->getParameters()) {
4043+
sub->Printer.printSeparator(first, ", ");
4044+
param.print(sub->Printer, subOptions);
4045+
}
4046+
sub->Printer << ") -> ";
40264047

4027-
unsigned totalResults =
4028-
T->getNumYields() + T->getNumResults() + unsigned(T->hasErrorResult());
4048+
unsigned totalResults =
4049+
T->getNumYields() + T->getNumResults() + unsigned(T->hasErrorResult());
40294050

4030-
if (totalResults != 1) Printer << "(";
4051+
if (totalResults != 1)
4052+
sub->Printer << "(";
40314053

4032-
first = true;
4054+
first = true;
40334055

4034-
for (auto yield : T->getYields()) {
4035-
Printer.printSeparator(first, ", ");
4036-
Printer << "@yields ";
4037-
yield.print(Printer, Options);
4038-
}
4056+
for (auto yield : T->getYields()) {
4057+
sub->Printer.printSeparator(first, ", ");
4058+
sub->Printer << "@yields ";
4059+
yield.print(sub->Printer, subOptions);
4060+
}
40394061

4040-
for (auto result : T->getResults()) {
4041-
Printer.printSeparator(first, ", ");
4042-
result.print(Printer, Options);
4043-
}
4062+
for (auto result : T->getResults()) {
4063+
sub->Printer.printSeparator(first, ", ");
4064+
result.print(sub->Printer, subOptions);
4065+
}
40444066

4045-
if (T->hasErrorResult()) {
4046-
// The error result is implicitly @owned; don't print that.
4047-
assert(T->getErrorResult().getConvention() == ResultConvention::Owned);
4048-
Printer.printSeparator(first, ", ");
4049-
Printer << "@error ";
4050-
T->getErrorResult().getInterfaceType().print(Printer, Options);
4051-
}
4067+
if (T->hasErrorResult()) {
4068+
// The error result is implicitly @owned; don't print that.
4069+
assert(T->getErrorResult().getConvention() == ResultConvention::Owned);
4070+
sub->Printer.printSeparator(first, ", ");
4071+
sub->Printer << "@error ";
4072+
T->getErrorResult().getInterfaceType().print(sub->Printer, subOptions);
4073+
}
40524074

4053-
if (totalResults != 1) Printer << ")";
4075+
if (totalResults != 1)
4076+
sub->Printer << ")";
4077+
}();
40544078

4079+
// The substitution types are always in terms of the outer environment.
40554080
if (auto substitutions = T->getSubstitutions()) {
4056-
Printer << " for ";
4081+
Printer << " for";
40574082
printSubstitutions(substitutions);
40584083
}
40594084
}
@@ -4076,7 +4101,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
40764101
[&sub, T]{
40774102
if (auto sig = T->getLayout()->getGenericSignature()) {
40784103
sub.printGenericSignature(sig,
4079-
PrintAST::PrintParams | PrintAST::PrintRequirements);
4104+
PrintAST::PrintParams | PrintAST::PrintRequirements);
40804105
sub.Printer << " ";
40814106
}
40824107
sub.Printer << "{";

0 commit comments

Comments
 (0)