@@ -5812,6 +5812,41 @@ ProtocolConformance *SILParser::parseProtocolConformanceHelper(
5812
5812
return retVal;
5813
5813
}
5814
5814
5815
+ // / Bind any unqualified 'Self' references to the given protocol's 'Self'
5816
+ // / generic parameter.
5817
+ // /
5818
+ // / FIXME: This is a hack to work around the lack of a DeclContext for
5819
+ // / witness tables.
5820
+ static void bindProtocolSelfInTypeRepr (TypeLoc &TL, ProtocolDecl *proto) {
5821
+ if (auto typeRepr = TL.getTypeRepr ()) {
5822
+ // AST walker to update 'Self' references.
5823
+ class BindProtocolSelf : public ASTWalker {
5824
+ ProtocolDecl *proto;
5825
+ GenericTypeParamDecl *selfParam;
5826
+ Identifier selfId;
5827
+
5828
+ public:
5829
+ BindProtocolSelf (ProtocolDecl *proto)
5830
+ : proto(proto),
5831
+ selfParam (proto->getProtocolSelfType ()->getDecl()),
5832
+ selfId(proto->getASTContext ().Id_Self) {
5833
+ }
5834
+
5835
+ virtual bool walkToTypeReprPre (TypeRepr *T) override {
5836
+ if (auto ident = dyn_cast<IdentTypeRepr>(T)) {
5837
+ auto firstComponent = ident->getComponentRange ().front ();
5838
+ if (firstComponent->getIdentifier () == selfId)
5839
+ firstComponent->setValue (selfParam, proto);
5840
+ }
5841
+
5842
+ return true ;
5843
+ }
5844
+ };
5845
+
5846
+ typeRepr->walk (BindProtocolSelf(proto));
5847
+ }
5848
+ }
5849
+
5815
5850
// / Parser a single SIL vtable entry and add it to either \p witnessEntries
5816
5851
// / or \c conditionalConformances.
5817
5852
static bool parseSILVTableEntry (
@@ -5820,6 +5855,7 @@ static bool parseSILVTableEntry(
5820
5855
ProtocolDecl *proto,
5821
5856
GenericEnvironment *witnessEnv,
5822
5857
SILParser &witnessState,
5858
+ bool isDefaultWitnessTable,
5823
5859
std::vector<SILWitnessTable::Entry> &witnessEntries,
5824
5860
std::vector<SILWitnessTable::ConditionalConformance>
5825
5861
&conditionalConformances) {
@@ -5865,6 +5901,8 @@ static bool parseSILVTableEntry(
5865
5901
if (TyR.isNull ())
5866
5902
return true ;
5867
5903
TypeLoc Ty = TyR.get ();
5904
+ if (isDefaultWitnessTable)
5905
+ bindProtocolSelfInTypeRepr (Ty, proto);
5868
5906
if (swift::performTypeLocChecking (P.Context , Ty,
5869
5907
/* isSILMode=*/ false ,
5870
5908
/* isSILType=*/ false ,
@@ -5921,6 +5959,8 @@ static bool parseSILVTableEntry(
5921
5959
if (TyR.isNull ())
5922
5960
return true ;
5923
5961
TypeLoc Ty = TyR.get ();
5962
+ if (isDefaultWitnessTable)
5963
+ bindProtocolSelfInTypeRepr (Ty, proto);
5924
5964
if (swift::performTypeLocChecking (P.Context , Ty,
5925
5965
/* isSILMode=*/ false ,
5926
5966
/* isSILType=*/ false ,
@@ -6046,7 +6086,7 @@ bool SILParserTUState::parseSILWitnessTable(Parser &P) {
6046
6086
6047
6087
if (P.Tok .isNot (tok::r_brace)) {
6048
6088
do {
6049
- if (parseSILVTableEntry (P, M, proto, witnessEnv, WitnessState,
6089
+ if (parseSILVTableEntry (P, M, proto, witnessEnv, WitnessState, false ,
6050
6090
witnessEntries, conditionalConformances))
6051
6091
return true ;
6052
6092
} while (P.Tok .isNot (tok::r_brace) && P.Tok .isNot (tok::eof));
@@ -6092,6 +6132,8 @@ bool SILParserTUState::parseSILDefaultWitnessTable(Parser &P) {
6092
6132
6093
6133
// Parse the protocol.
6094
6134
ProtocolDecl *protocol = parseProtocolDecl (P, WitnessState);
6135
+ if (!protocol)
6136
+ return true ;
6095
6137
6096
6138
// Parse the body.
6097
6139
SourceLoc LBraceLoc = P.Tok .getLoc ();
@@ -6106,8 +6148,9 @@ bool SILParserTUState::parseSILDefaultWitnessTable(Parser &P) {
6106
6148
6107
6149
if (P.Tok .isNot (tok::r_brace)) {
6108
6150
do {
6109
- if (parseSILVTableEntry (P, M, protocol, nullptr , WitnessState,
6110
- witnessEntries, conditionalConformances))
6151
+ if (parseSILVTableEntry (P, M, protocol, protocol->getGenericEnvironment (),
6152
+ WitnessState, true , witnessEntries,
6153
+ conditionalConformances))
6111
6154
return true ;
6112
6155
} while (P.Tok .isNot (tok::r_brace) && P.Tok .isNot (tok::eof));
6113
6156
}
0 commit comments