@@ -4006,54 +4006,79 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
4006
4006
printFunctionExtInfo (T->getExtInfo (),
4007
4007
T->getWitnessMethodConformanceOrInvalid ());
4008
4008
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;
4017
4025
}
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
+ }
4018
4039
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 << " ) -> " ;
4026
4047
4027
- unsigned totalResults =
4028
- T->getNumYields () + T->getNumResults () + unsigned (T->hasErrorResult ());
4048
+ unsigned totalResults =
4049
+ T->getNumYields () + T->getNumResults () + unsigned (T->hasErrorResult ());
4029
4050
4030
- if (totalResults != 1 ) Printer << " (" ;
4051
+ if (totalResults != 1 )
4052
+ sub->Printer << " (" ;
4031
4053
4032
- first = true ;
4054
+ first = true ;
4033
4055
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
+ }
4039
4061
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
+ }
4044
4066
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
+ }
4052
4074
4053
- if (totalResults != 1 ) Printer << " )" ;
4075
+ if (totalResults != 1 )
4076
+ sub->Printer << " )" ;
4077
+ }();
4054
4078
4079
+ // The substitution types are always in terms of the outer environment.
4055
4080
if (auto substitutions = T->getSubstitutions ()) {
4056
- Printer << " for " ;
4081
+ Printer << " for" ;
4057
4082
printSubstitutions (substitutions);
4058
4083
}
4059
4084
}
@@ -4076,7 +4101,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
4076
4101
[&sub, T]{
4077
4102
if (auto sig = T->getLayout ()->getGenericSignature ()) {
4078
4103
sub.printGenericSignature (sig,
4079
- PrintAST::PrintParams | PrintAST::PrintRequirements);
4104
+ PrintAST::PrintParams | PrintAST::PrintRequirements);
4080
4105
sub.Printer << " " ;
4081
4106
}
4082
4107
sub.Printer << " {" ;
0 commit comments