@@ -698,18 +698,16 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
698
698
return fnTy->substGenericArgs (F.getModule (), M, subs);
699
699
}
700
700
701
- // / Check that for each opened archetype in substitutions, there is an
702
- // / opened archetype operand.
703
- void checkApplySubstitutionsOpenedArchetypes (SILInstruction *AI,
704
- ArrayRef<Substitution> Subs) {
705
- // If we have a substitution whose replacement type is an archetype, make
706
- // sure that the replacement archetype is in the context generic params of
707
- // the caller function.
701
+ // / Check that for each opened archetype in substitutions
702
+ // / or the calle type, there is a type dependent operand.
703
+ void checkApplyTypeDependentArguments (ApplySite AS) {
704
+ SILInstruction *AI = AS.getInstruction ();
705
+
708
706
llvm::DenseSet<CanType> FoundOpenedArchetypes;
709
- for ( auto &Sub : Subs) {
710
- Sub. getReplacement (). visit ([&](Type Ty) {
711
- if (!Ty-> isOpenedExistential ())
712
- return ;
707
+
708
+ // Function to collect opened archetypes in FoundOpenedArchetypes.
709
+ auto HandleType = [&](Type Ty) {
710
+ if (Ty-> isOpenedExistential ()) {
713
711
auto *A = Ty->getAs <ArchetypeType>();
714
712
require (isArchetypeValidInFunction (A, AI->getFunction ()),
715
713
" Archetype to be substituted must be valid in function." );
@@ -718,35 +716,42 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
718
716
// Also check that they are properly tracked inside the current
719
717
// function.
720
718
auto Def =
721
- OpenedArchetypes.getOpenedArchetypeDef (Ty.getCanonicalTypeOrNull ());
719
+ OpenedArchetypes.getOpenedArchetypeDef (Ty.getCanonicalTypeOrNull ());
722
720
require (Def, " Opened archetype should be registered in SILFunction" );
723
721
require (Def == AI ||
724
- Dominance->properlyDominates (cast<SILInstruction>(Def), AI),
722
+ Dominance->properlyDominates (cast<SILInstruction>(Def), AI),
725
723
" Use of an opened archetype should be dominated by a "
726
724
" definition of this opened archetype" );
727
- });
725
+ }
726
+ };
727
+
728
+ // Search for opened archetypes.
729
+ for (auto &Sub : AS.getSubstitutions ()) {
730
+ Sub.getReplacement ().visit (HandleType);
728
731
}
732
+ AS.getSubstCalleeType ().visit (HandleType);
729
733
730
734
require (FoundOpenedArchetypes.size () ==
731
735
AI->getOpenedArchetypeOperands ().size (),
732
- " Number of opened archetypes in the substitutions list should "
733
- " match the number of opened archetype operands" );
736
+ " Number of opened archetypes in the substitutions "
737
+ " list should match the number of type dependent operands" );
734
738
735
739
for (auto &Op : AI->getOpenedArchetypeOperands ()) {
736
740
auto V = Op.get ();
737
741
require (isa<SILInstruction>(V),
738
- " opened archetype operand should refer to a SIL instruction" );
742
+ " opened archetype operand should refer to a SIL instruction" );
739
743
auto Archetype = getOpenedArchetypeOf (cast<SILInstruction>(V));
740
- require (Archetype, " opened archetype operand should define an opened archetype" );
744
+ require (Archetype,
745
+ " opened archetype operand should define an opened archetype" );
741
746
require (FoundOpenedArchetypes.count (Archetype),
742
- " opened archetype operand does not correspond to any opened archetype from "
743
- " the substitutions list" );
747
+ " opened archetype operand does not correspond to any opened "
748
+ " archetype from the substitutions list" );
744
749
}
745
750
}
746
751
747
752
void checkFullApplySite (FullApplySite site) {
748
- checkApplySubstitutionsOpenedArchetypes (site. getInstruction (),
749
- site. getSubstitutions ());
753
+ checkApplyTypeDependentArguments (site);
754
+
750
755
// Then make sure that we have a type that can be substituted for the
751
756
// callee.
752
757
auto substTy = checkApplySubstitutions (site.getSubstitutions (),
@@ -866,7 +871,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
866
871
require (resultInfo->getExtInfo ().hasContext (),
867
872
" result of closure cannot have a thin function type" );
868
873
869
- checkApplySubstitutionsOpenedArchetypes (PAI, PAI-> getSubstitutions () );
874
+ checkApplyTypeDependentArguments (PAI);
870
875
871
876
auto substTy = checkApplySubstitutions (PAI->getSubstitutions (),
872
877
PAI->getCallee ()->getType ());
@@ -1429,9 +1434,10 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
1429
1434
void checkMetatypeInst (MetatypeInst *MI) {
1430
1435
require (MI->getType ().is <MetatypeType>(),
1431
1436
" metatype instruction must be of metatype type" );
1432
- require (MI->getType ().castTo <MetatypeType>()->hasRepresentation (),
1437
+ auto MetaTy = MI->getType ().castTo <MetatypeType>();
1438
+ require (MetaTy->hasRepresentation (),
1433
1439
" metatype instruction must have a metatype representation" );
1434
- verifyOpenedArchetype (MI, MI-> getType (). getSwiftRValueType ());
1440
+ verifyOpenedArchetype (MI, MetaTy. getInstanceType ());
1435
1441
}
1436
1442
void checkValueMetatypeInst (ValueMetatypeInst *MI) {
1437
1443
require (MI->getType ().is <MetatypeType>(),
@@ -1703,7 +1709,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
1703
1709
auto lookupType = AMI->getLookupType ();
1704
1710
if (getOpenedArchetype (lookupType)) {
1705
1711
require (AMI->getOpenedArchetypeOperands ().size () == 1 ,
1706
- " Must have an opened existential operand" );
1712
+ " Must have a type dependent operand for the opened archetype " );
1707
1713
verifyOpenedArchetype (AMI, lookupType);
1708
1714
} else {
1709
1715
require (AMI->getOpenedArchetypeOperands ().empty (),
@@ -1793,6 +1799,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
1793
1799
.getSwiftRValueType ()
1794
1800
->isBindableTo (EMI->getType ().getSwiftRValueType (), nullptr ),
1795
1801
" result must be of the method's type" );
1802
+ verifyOpenedArchetype (EMI, EMI->getType ().getSwiftRValueType ());
1796
1803
}
1797
1804
1798
1805
void checkClassMethodInst (ClassMethodInst *CMI) {
@@ -2075,18 +2082,18 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
2075
2082
SILType resultType = I->getType ();
2076
2083
require (resultType.is <ExistentialMetatypeType>(),
2077
2084
" init_existential_metatype result must be an existential metatype" );
2085
+ auto MetaTy = resultType.castTo <ExistentialMetatypeType>();
2078
2086
require (resultType.isObject (),
2079
2087
" init_existential_metatype result must not be an address" );
2080
- require (resultType. castTo <ExistentialMetatypeType>() ->hasRepresentation (),
2088
+ require (MetaTy ->hasRepresentation (),
2081
2089
" init_existential_metatype result must have a representation" );
2082
- require (resultType. castTo <ExistentialMetatypeType>() ->getRepresentation ()
2090
+ require (MetaTy ->getRepresentation ()
2083
2091
== operandType.castTo <MetatypeType>()->getRepresentation (),
2084
2092
" init_existential_metatype result must match representation of "
2085
2093
" operand" );
2086
2094
2087
2095
checkExistentialProtocolConformances (resultType, I->getConformances ());
2088
- verifyOpenedArchetype (
2089
- I, getOpenedArchetypeOf (I->getType ().getSwiftRValueType ()));
2096
+ verifyOpenedArchetype (I, MetaTy.getInstanceType ());
2090
2097
}
2091
2098
2092
2099
void checkExistentialProtocolConformances (SILType resultType,
@@ -2172,9 +2179,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
2172
2179
void verifyOpenedArchetype (SILInstruction *I, CanType Ty) {
2173
2180
if (!Ty)
2174
2181
return ;
2175
- // Check for each referenced opened archetype from Ty
2176
- // that the instruction contains an opened archetype operand
2177
- // for it.
2182
+ // Check the type and all of its contained types.
2178
2183
Ty.visit ([&](Type t) {
2179
2184
if (!t->isOpenedExistential ())
2180
2185
return ;
0 commit comments