@@ -1566,57 +1566,58 @@ static bool getConformancesForSubstitution(Parser &P,
1566
1566
return false ;
1567
1567
}
1568
1568
1569
- // / Reconstruct AST substitutions from parsed substitutions using archetypes
1570
- // / from a SILFunctionType.
1571
- bool getApplySubstitutionsFromParsed (
1569
+ // / Reconstruct an AST substitution map from parsed substitutions.
1570
+ SubstitutionMap getApplySubstitutionsFromParsed (
1572
1571
SILParser &SP,
1573
1572
GenericEnvironment *env,
1574
- ArrayRef<ParsedSubstitution> parses,
1575
- SmallVectorImpl<Substitution> &subs) {
1573
+ ArrayRef<ParsedSubstitution> parses) {
1576
1574
if (parses.empty ()) {
1577
1575
assert (!env);
1578
- return false ;
1576
+ return SubstitutionMap () ;
1579
1577
}
1580
1578
1581
1579
assert (env);
1582
1580
1583
1581
auto loc = parses[0 ].loc ;
1584
1582
1585
- // The replacement is for the corresponding dependent type by ordering.
1586
- auto result = env->getGenericSignature ()->enumeratePairedRequirements (
1587
- [&](Type depTy, ArrayRef<Requirement> reqts) -> bool {
1588
- if (parses.empty ()) {
1589
- SP.P .diagnose (loc, diag::sil_missing_substitutions);
1590
- return true ;
1591
- }
1592
- auto parsed = parses.front ();
1593
- parses = parses.slice (1 );
1594
-
1595
- SmallVector<ProtocolConformanceRef, 2 > conformances;
1596
- SmallVector<Type, 2 > protocols;
1597
- for (auto reqt : reqts)
1598
- protocols.push_back (reqt.getSecondType ());
1599
-
1600
- if (getConformancesForSubstitution (SP.P ,
1601
- ExistentialLayout::ProtocolTypeArrayRef (protocols),
1602
- parsed.replacement ,
1603
- parsed.loc , conformances))
1604
- return true ;
1605
-
1606
- subs.push_back ({parsed.replacement ,
1607
- SP.P .Context .AllocateCopy (conformances)});
1608
- return false ;
1583
+ // Ensure that we have the right number of type arguments.
1584
+ auto genericSig = env->getGenericSignature ();
1585
+ if (parses.size () != genericSig->getGenericParams ().size ()) {
1586
+ bool hasTooFew = parses.size () < genericSig->getGenericParams ().size ();
1587
+ SP.P .diagnose (loc,
1588
+ hasTooFew ? diag::sil_missing_substitutions
1589
+ : diag::sil_too_many_substitutions);
1590
+ return SubstitutionMap ();
1591
+ }
1592
+
1593
+ bool failed = false ;
1594
+ SubstitutionMap subMap = genericSig->getSubstitutionMap (
1595
+ [&](SubstitutableType *type) -> Type {
1596
+ auto genericParam = dyn_cast<GenericTypeParamType>(type);
1597
+ if (!genericParam) return nullptr ;
1598
+
1599
+ auto index = genericSig->getGenericParamOrdinal (genericParam);
1600
+ assert (index < genericSig->getGenericParams ().size ());
1601
+ assert (index < parses.size ());
1602
+
1603
+ // Provide the replacement type.
1604
+ return parses[index].replacement ;
1605
+ },
1606
+ [&](CanType dependentType, Type replacementType,
1607
+ ProtocolType *protoTy) ->Optional <ProtocolConformanceRef> {
1608
+ auto M = SP.P .SF .getParentModule ();
1609
+ auto conformance = M->lookupConformance (replacementType,
1610
+ protoTy->getDecl ());
1611
+ if (conformance) return conformance;
1612
+
1613
+ SP.P .diagnose (loc, diag::sil_substitution_mismatch, replacementType,
1614
+ protoTy);
1615
+ failed = true ;
1616
+
1617
+ return ProtocolConformanceRef (protoTy->getDecl ());
1609
1618
});
1610
1619
1611
- if (result)
1612
- return true ;
1613
-
1614
- if (!parses.empty ()) {
1615
- SP.P .diagnose (loc, diag::sil_too_many_substitutions);
1616
- return true ;
1617
- }
1618
-
1619
- return false ;
1620
+ return failed ? SubstitutionMap () : subMap;
1620
1621
}
1621
1622
1622
1623
static ArrayRef<ProtocolConformanceRef>
@@ -1993,17 +1994,13 @@ SILParser::parseKeyPathPatternComponent(KeyPathPatternComponent &component,
1993
1994
diag::sil_substitutions_on_non_polymorphic_type);
1994
1995
return true ;
1995
1996
}
1996
- if (getApplySubstitutionsFromParsed (*this , genericEnv,
1997
- parsedSubs, subs))
1998
- return true ;
1999
-
1997
+ subsMap = getApplySubstitutionsFromParsed (*this , genericEnv, parsedSubs);
1998
+ if (!subsMap) return true ;
1999
+
2000
2000
// Map the substitutions out of the pattern context so that they
2001
2001
// use interface types.
2002
- subsMap = genericEnv->getGenericSignature ()
2003
- ->getSubstitutionMap (subs);
2004
2002
subsMap = subsMap.mapReplacementTypesOutOfContext ().getCanonical ();
2005
2003
}
2006
-
2007
2004
2008
2005
auto indexesCopy = P.Context .AllocateCopy (indexes);
2009
2006
@@ -2563,11 +2560,9 @@ bool SILParser::parseSILInstruction(SILBuilder &B) {
2563
2560
P.diagnose (P.Tok , diag::sil_substitutions_on_non_polymorphic_type);
2564
2561
return true ;
2565
2562
}
2566
- SmallVector<Substitution, 4 > subs ;
2567
- if (getApplySubstitutionsFromParsed (* this , genericEnv, parsedSubs, subs) )
2563
+ subMap = getApplySubstitutionsFromParsed (* this , genericEnv, parsedSubs) ;
2564
+ if (!subMap )
2568
2565
return true ;
2569
-
2570
- subMap = genericEnv->getGenericSignature ()->getSubstitutionMap (subs);
2571
2566
}
2572
2567
2573
2568
if (P.Tok .getKind () != tok::l_paren) {
@@ -2913,24 +2908,22 @@ bool SILParser::parseSILInstruction(SILBuilder &B) {
2913
2908
P.diagnose (InstLoc.getSourceLoc (), diag::sil_keypath_no_root);
2914
2909
2915
2910
SmallVector<ParsedSubstitution, 4 > parsedSubs;
2916
- SmallVector<Substitution, 4 > subs;
2917
2911
if (parseSubstitutions (parsedSubs, ContextGenericEnv))
2918
2912
return true ;
2919
2913
2914
+ SubstitutionMap subMap;
2920
2915
if (!parsedSubs.empty ()) {
2921
2916
if (!patternEnv) {
2922
2917
P.diagnose (InstLoc.getSourceLoc (),
2923
2918
diag::sil_substitutions_on_non_polymorphic_type);
2924
2919
return true ;
2925
2920
}
2926
- if (getApplySubstitutionsFromParsed (*this , patternEnv, parsedSubs, subs))
2921
+
2922
+ subMap = getApplySubstitutionsFromParsed (*this , patternEnv, parsedSubs);
2923
+ if (!subMap)
2927
2924
return true ;
2928
2925
}
2929
2926
2930
- SubstitutionMap subMap;
2931
- if (patternEnv && patternEnv->getGenericSignature ())
2932
- subMap = patternEnv->getGenericSignature ()->getSubstitutionMap (subs);
2933
-
2934
2927
SmallVector<SILValue, 4 > operands;
2935
2928
2936
2929
if (P.consumeIf (tok::l_paren)) {
@@ -3312,22 +3305,19 @@ bool SILParser::parseSILInstruction(SILBuilder &B) {
3312
3305
3313
3306
SubstitutionMap InitStorageSubs, SetterSubs;
3314
3307
{
3315
- SmallVector<Substitution, 4 > InitStorageSubsVec, SetterSubsVec;
3316
- if (getApplySubstitutionsFromParsed (*this , InitStorageEnv,
3317
- ParsedInitStorageSubs,
3318
- InitStorageSubsVec)
3319
- || getApplySubstitutionsFromParsed (*this , SetterEnv,
3320
- ParsedSetterSubs, SetterSubsVec))
3321
- return true ;
3322
-
3323
3308
if (InitStorageEnv) {
3324
- InitStorageSubs = InitStorageEnv->getGenericSignature ()
3325
- ->getSubstitutionMap (InitStorageSubsVec);
3309
+ InitStorageSubs =
3310
+ getApplySubstitutionsFromParsed (*this , InitStorageEnv,
3311
+ ParsedInitStorageSubs);
3312
+ if (!InitStorageSubs)
3313
+ return true ;
3326
3314
}
3327
3315
3328
3316
if (SetterEnv) {
3329
- SetterSubs = SetterEnv->getGenericSignature ()
3330
- ->getSubstitutionMap (SetterSubsVec);
3317
+ SetterSubs = getApplySubstitutionsFromParsed (*this , SetterEnv,
3318
+ ParsedSetterSubs);
3319
+ if (!SetterSubs)
3320
+ return true ;
3331
3321
}
3332
3322
}
3333
3323
@@ -4861,14 +4851,11 @@ bool SILParser::parseSILInstruction(SILBuilder &B) {
4861
4851
P.diagnose (typeLoc, diag::sil_substitutions_on_non_polymorphic_type);
4862
4852
return true ;
4863
4853
}
4864
- SmallVector<Substitution, 4 > subs;
4865
- if (getApplySubstitutionsFromParsed (*this ,
4866
- invokeGenericEnv,
4867
- parsedSubs, subs))
4868
- return true ;
4869
4854
4870
- subMap = invokeGenericEnv->getGenericSignature ()
4871
- ->getSubstitutionMap (subs);
4855
+ subMap = getApplySubstitutionsFromParsed (*this , invokeGenericEnv,
4856
+ parsedSubs);
4857
+ if (!subMap)
4858
+ return true ;
4872
4859
}
4873
4860
4874
4861
ResultVal = B.createInitBlockStorageHeader (InstLoc, Val, invokeVal,
@@ -4949,10 +4936,9 @@ bool SILParser::parseCallInstruction(SILLocation InstLoc,
4949
4936
P.diagnose (TypeLoc, diag::sil_substitutions_on_non_polymorphic_type);
4950
4937
return true ;
4951
4938
}
4952
- SmallVector<Substitution, 4 > subsVec ;
4953
- if (getApplySubstitutionsFromParsed (* this , GenericEnv, parsedSubs, subsVec) )
4939
+ subs = getApplySubstitutionsFromParsed (* this , GenericEnv, parsedSubs) ;
4940
+ if (!subs )
4954
4941
return true ;
4955
- subs = GenericEnv->getGenericSignature ()->getSubstitutionMap (subsVec);
4956
4942
}
4957
4943
4958
4944
SILValue FnVal = getLocalValue (FnName, Ty, InstLoc, B);
@@ -5809,13 +5795,11 @@ ProtocolConformance *SILParser::parseProtocolConformanceHelper(
5809
5795
if (P.parseToken (tok::r_paren, diag::expected_sil_witness_rparen))
5810
5796
return nullptr ;
5811
5797
5812
- SmallVector<Substitution, 4 > subs;
5813
- if ( getApplySubstitutionsFromParsed (*this , specializedEnv, parsedSubs,
5814
- subs) )
5798
+ SubstitutionMap subMap =
5799
+ getApplySubstitutionsFromParsed (*this , specializedEnv, parsedSubs);
5800
+ if (!subMap )
5815
5801
return nullptr ;
5816
5802
5817
- auto subMap =
5818
- genericConform->getGenericSignature ()->getSubstitutionMap (subs);
5819
5803
auto result = P.Context .getSpecializedConformance (
5820
5804
ConformingTy, genericConform, subMap);
5821
5805
return result;
0 commit comments