@@ -181,7 +181,8 @@ namespace {
181
181
ProtocolConformance *
182
182
parseProtocolConformanceHelper (ProtocolDecl *&proto,
183
183
GenericEnvironment *GenericEnv,
184
- bool localScope);
184
+ bool localScope,
185
+ ProtocolDecl *defaultForProto);
185
186
public:
186
187
SILParser (Parser &P)
187
188
: P(P), SILMod(static_cast <SILParserTUState *>(P.SIL)->M),
@@ -391,15 +392,18 @@ namespace {
391
392
bool isStartOfSILInstruction ();
392
393
393
394
bool parseSubstitutions (SmallVectorImpl<ParsedSubstitution> &parsed,
394
- GenericEnvironment *GenericEnv=nullptr );
395
+ GenericEnvironment *GenericEnv=nullptr ,
396
+ ProtocolDecl *defaultForProto = nullptr );
395
397
396
398
ProtocolConformance *parseProtocolConformance (ProtocolDecl *&proto,
397
399
GenericEnvironment *&genericEnv,
398
- bool localScope);
399
- ProtocolConformance *parseProtocolConformance () {
400
+ bool localScope,
401
+ ProtocolDecl *defaultForProto);
402
+ ProtocolConformance *parseProtocolConformance (
403
+ ProtocolDecl *defaultForProto) {
400
404
ProtocolDecl *dummy;
401
405
GenericEnvironment *env;
402
- return parseProtocolConformance (dummy, env, true );
406
+ return parseProtocolConformance (dummy, env, true , defaultForProto );
403
407
}
404
408
405
409
Optional<llvm::coverage::Counter>
@@ -1012,6 +1016,8 @@ bool SILParser::performTypeLocChecking(TypeLoc &T, bool IsSILType,
1012
1016
1013
1017
if (!DC)
1014
1018
DC = &P.SF ;
1019
+ else if (!GenericEnv)
1020
+ GenericEnv = DC->getGenericEnvironmentOfContext ();
1015
1021
1016
1022
return swift::performTypeLocChecking (P.Context , T,
1017
1023
/* isSILMode=*/ true , IsSILType,
@@ -1510,10 +1516,46 @@ bool SILParser::parseSILBBArgsAtBranch(SmallVector<SILValue, 6> &Args,
1510
1516
return false ;
1511
1517
}
1512
1518
1519
+ // / Bind any unqualified 'Self' references to the given protocol's 'Self'
1520
+ // / generic parameter.
1521
+ // /
1522
+ // / FIXME: This is a hack to work around the lack of a DeclContext for
1523
+ // / witness tables.
1524
+ static void bindProtocolSelfInTypeRepr (TypeLoc &TL, ProtocolDecl *proto) {
1525
+ if (auto typeRepr = TL.getTypeRepr ()) {
1526
+ // AST walker to update 'Self' references.
1527
+ class BindProtocolSelf : public ASTWalker {
1528
+ ProtocolDecl *proto;
1529
+ GenericTypeParamDecl *selfParam;
1530
+ Identifier selfId;
1531
+
1532
+ public:
1533
+ BindProtocolSelf (ProtocolDecl *proto)
1534
+ : proto(proto),
1535
+ selfParam (proto->getProtocolSelfType ()->getDecl()),
1536
+ selfId(proto->getASTContext ().Id_Self) {
1537
+ }
1538
+
1539
+ virtual bool walkToTypeReprPre (TypeRepr *T) override {
1540
+ if (auto ident = dyn_cast<IdentTypeRepr>(T)) {
1541
+ auto firstComponent = ident->getComponentRange ().front ();
1542
+ if (firstComponent->getIdentifier () == selfId)
1543
+ firstComponent->setValue (selfParam, proto);
1544
+ }
1545
+
1546
+ return true ;
1547
+ }
1548
+ };
1549
+
1550
+ typeRepr->walk (BindProtocolSelf(proto));
1551
+ }
1552
+ }
1553
+
1513
1554
// / Parse the substitution list for an apply instruction or
1514
1555
// / specialized protocol conformance.
1515
1556
bool SILParser::parseSubstitutions (SmallVectorImpl<ParsedSubstitution> &parsed,
1516
- GenericEnvironment *GenericEnv) {
1557
+ GenericEnvironment *GenericEnv,
1558
+ ProtocolDecl *defaultForProto) {
1517
1559
// Check for an opening '<' bracket.
1518
1560
if (!P.Tok .isContextualPunctuator (" <" ))
1519
1561
return false ;
@@ -1529,7 +1571,10 @@ bool SILParser::parseSubstitutions(SmallVectorImpl<ParsedSubstitution> &parsed,
1529
1571
if (TyR.isNull ())
1530
1572
return true ;
1531
1573
TypeLoc Ty = TyR.get ();
1532
- if (performTypeLocChecking (Ty, /* IsSILType=*/ false , GenericEnv))
1574
+ if (defaultForProto)
1575
+ bindProtocolSelfInTypeRepr (Ty, defaultForProto);
1576
+ if (performTypeLocChecking (Ty, /* IsSILType=*/ false , GenericEnv,
1577
+ defaultForProto))
1533
1578
return true ;
1534
1579
parsed.push_back ({Loc, Ty.getType ()});
1535
1580
} while (P.consumeIf (tok::comma));
@@ -5725,7 +5770,8 @@ static NormalProtocolConformance *parseNormalProtocolConformance(Parser &P,
5725
5770
ProtocolConformance *SILParser::parseProtocolConformance (
5726
5771
ProtocolDecl *&proto,
5727
5772
GenericEnvironment *&genericEnv,
5728
- bool localScope) {
5773
+ bool localScope,
5774
+ ProtocolDecl *defaultForProto) {
5729
5775
// Parse generic params for the protocol conformance. We need to make sure
5730
5776
// they have the right scope.
5731
5777
Optional<Scope> GenericsScope;
@@ -5741,7 +5787,8 @@ ProtocolConformance *SILParser::parseProtocolConformance(
5741
5787
}
5742
5788
5743
5789
ProtocolConformance *retVal =
5744
- parseProtocolConformanceHelper (proto, genericEnv, localScope);
5790
+ parseProtocolConformanceHelper (proto, genericEnv, localScope,
5791
+ defaultForProto);
5745
5792
5746
5793
if (localScope) {
5747
5794
GenericsScope.reset ();
@@ -5752,13 +5799,19 @@ ProtocolConformance *SILParser::parseProtocolConformance(
5752
5799
ProtocolConformance *SILParser::parseProtocolConformanceHelper (
5753
5800
ProtocolDecl *&proto,
5754
5801
GenericEnvironment *witnessEnv,
5755
- bool localScope) {
5802
+ bool localScope,
5803
+ ProtocolDecl *defaultForProto) {
5756
5804
// Parse AST type.
5757
5805
ParserResult<TypeRepr> TyR = P.parseType ();
5758
5806
if (TyR.isNull ())
5759
5807
return nullptr ;
5760
5808
TypeLoc Ty = TyR.get ();
5761
- if (performTypeLocChecking (Ty, /* IsSILType=*/ false , witnessEnv))
5809
+ if (defaultForProto) {
5810
+ bindProtocolSelfInTypeRepr (Ty, defaultForProto);
5811
+ }
5812
+
5813
+ if (performTypeLocChecking (Ty, /* IsSILType=*/ false , witnessEnv,
5814
+ defaultForProto))
5762
5815
return nullptr ;
5763
5816
auto ConformingTy = Ty.getType ();
5764
5817
@@ -5770,15 +5823,16 @@ ProtocolConformance *SILParser::parseProtocolConformanceHelper(
5770
5823
5771
5824
// Parse substitutions for specialized conformance.
5772
5825
SmallVector<ParsedSubstitution, 4 > parsedSubs;
5773
- if (parseSubstitutions (parsedSubs, witnessEnv))
5826
+ if (parseSubstitutions (parsedSubs, witnessEnv, defaultForProto ))
5774
5827
return nullptr ;
5775
5828
5776
5829
if (P.parseToken (tok::l_paren, diag::expected_sil_witness_lparen))
5777
5830
return nullptr ;
5778
5831
ProtocolDecl *dummy;
5779
5832
GenericEnvironment *specializedEnv;
5780
5833
auto genericConform =
5781
- parseProtocolConformance (dummy, specializedEnv, localScope);
5834
+ parseProtocolConformance (dummy, specializedEnv, localScope,
5835
+ defaultForProto);
5782
5836
if (!genericConform)
5783
5837
return nullptr ;
5784
5838
if (P.parseToken (tok::r_paren, diag::expected_sil_witness_rparen))
@@ -5799,7 +5853,7 @@ ProtocolConformance *SILParser::parseProtocolConformanceHelper(
5799
5853
5800
5854
if (P.parseToken (tok::l_paren, diag::expected_sil_witness_lparen))
5801
5855
return nullptr ;
5802
- auto baseConform = parseProtocolConformance ();
5856
+ auto baseConform = parseProtocolConformance (defaultForProto );
5803
5857
if (!baseConform)
5804
5858
return nullptr ;
5805
5859
if (P.parseToken (tok::r_paren, diag::expected_sil_witness_rparen))
@@ -5812,41 +5866,6 @@ ProtocolConformance *SILParser::parseProtocolConformanceHelper(
5812
5866
return retVal;
5813
5867
}
5814
5868
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
-
5850
5869
// / Parser a single SIL vtable entry and add it to either \p witnessEntries
5851
5870
// / or \c conditionalConformances.
5852
5871
static bool parseSILVTableEntry (
@@ -5859,6 +5878,7 @@ static bool parseSILVTableEntry(
5859
5878
std::vector<SILWitnessTable::Entry> &witnessEntries,
5860
5879
std::vector<SILWitnessTable::ConditionalConformance>
5861
5880
&conditionalConformances) {
5881
+ ProtocolDecl *defaultForProto = isDefaultWitnessTable ? proto : nullptr ;
5862
5882
Identifier EntryKeyword;
5863
5883
SourceLoc KeywordLoc;
5864
5884
if (P.parseIdentifier (EntryKeyword, KeywordLoc,
@@ -5878,7 +5898,8 @@ static bool parseSILVTableEntry(
5878
5898
return true ;
5879
5899
if (P.parseToken (tok::colon, diag::expected_sil_witness_colon))
5880
5900
return true ;
5881
- ProtocolConformance *conform = witnessState.parseProtocolConformance ();
5901
+ ProtocolConformance *conform =
5902
+ witnessState.parseProtocolConformance (defaultForProto);
5882
5903
if (!conform) // Ignore this witness entry for now.
5883
5904
return false ;
5884
5905
@@ -5925,7 +5946,7 @@ static bool parseSILVTableEntry(
5925
5946
5926
5947
ProtocolConformanceRef conformance (proto);
5927
5948
if (P.Tok .getText () != " dependent" ) {
5928
- auto concrete = witnessState.parseProtocolConformance ();
5949
+ auto concrete = witnessState.parseProtocolConformance (defaultForProto );
5929
5950
if (!concrete) // Ignore this witness entry for now.
5930
5951
return false ;
5931
5952
conformance = ProtocolConformanceRef (concrete);
@@ -6045,7 +6066,8 @@ bool SILParserTUState::parseSILWitnessTable(Parser &P) {
6045
6066
GenericEnvironment *witnessEnv;
6046
6067
auto conf = WitnessState.parseProtocolConformance (proto,
6047
6068
witnessEnv,
6048
- false /* localScope*/ );
6069
+ false /* localScope*/ ,
6070
+ nullptr );
6049
6071
WitnessState.ContextGenericEnv = witnessEnv;
6050
6072
6051
6073
NormalProtocolConformance *theConformance = conf ?
0 commit comments