@@ -4003,54 +4003,79 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
4003
4003
printFunctionExtInfo (T->getExtInfo (),
4004
4004
T->getWitnessMethodConformanceOrNone ());
4005
4005
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;
4014
4022
}
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
+ }
4015
4036
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 << " ) -> " ;
4023
4044
4024
- unsigned totalResults =
4025
- T->getNumYields () + T->getNumResults () + unsigned (T->hasErrorResult ());
4045
+ unsigned totalResults =
4046
+ T->getNumYields () + T->getNumResults () + unsigned (T->hasErrorResult ());
4026
4047
4027
- if (totalResults != 1 ) Printer << " (" ;
4048
+ if (totalResults != 1 )
4049
+ sub->Printer << " (" ;
4028
4050
4029
- first = true ;
4051
+ first = true ;
4030
4052
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
+ }
4036
4058
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
+ }
4041
4063
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
+ }
4049
4071
4050
- if (totalResults != 1 ) Printer << " )" ;
4072
+ if (totalResults != 1 )
4073
+ sub->Printer << " )" ;
4074
+ }();
4051
4075
4076
+ // The substitution types are always in terms of the outer environment.
4052
4077
if (auto substitutions = T->getSubstitutions ()) {
4053
- Printer << " for " ;
4078
+ Printer << " for" ;
4054
4079
printSubstitutions (substitutions);
4055
4080
}
4056
4081
}
@@ -4073,7 +4098,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
4073
4098
[&sub, T]{
4074
4099
if (auto sig = T->getLayout ()->getGenericSignature ()) {
4075
4100
sub.printGenericSignature (sig,
4076
- PrintAST::PrintParams | PrintAST::PrintRequirements);
4101
+ PrintAST::PrintParams | PrintAST::PrintRequirements);
4077
4102
sub.Printer << " " ;
4078
4103
}
4079
4104
sub.Printer << " {" ;
0 commit comments