Skip to content

Commit fd81f81

Browse files
authored
Merge pull request #66294 from slavapestov/pack-element-type-part-2
PackElementType changes, part 2
2 parents 8a6fddf + c441187 commit fd81f81

File tree

13 files changed

+108
-60
lines changed

13 files changed

+108
-60
lines changed

include/swift/AST/Types.h

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6414,7 +6414,7 @@ class PackArchetypeType final
64146414
LayoutConstraint Layout);
64156415

64166416
// Returns the reduced shape type for this pack archetype.
6417-
CanType getReducedShape() const;
6417+
CanType getReducedShape();
64186418

64196419
static bool classof(const TypeBase *T) {
64206420
return T->getKind() == TypeKind::PackArchetype;
@@ -7098,16 +7098,6 @@ inline bool TypeBase::isTypeParameter() {
70987098
return t->is<GenericTypeParamType>();
70997099
}
71007100

7101-
inline bool TypeBase::isParameterPack() {
7102-
Type t(this);
7103-
7104-
while (auto *memberTy = t->getAs<DependentMemberType>())
7105-
t = memberTy->getBase();
7106-
7107-
return t->is<GenericTypeParamType>() &&
7108-
t->castTo<GenericTypeParamType>()->isParameterPack();
7109-
}
7110-
71117101
// TODO: This will become redundant once InOutType is removed.
71127102
inline bool TypeBase::isMaterializable() {
71137103
return !(hasLValueType() || is<InOutType>());

include/swift/SIL/SILType.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -686,12 +686,12 @@ class SILType {
686686
SILType subst(Lowering::TypeConverter &tc, TypeSubstitutionFn subs,
687687
LookupConformanceFn conformances,
688688
CanGenericSignature genericSig = CanGenericSignature(),
689-
bool shouldSubstituteOpaqueArchetypes = false) const;
689+
SubstOptions options = None) const;
690690

691691
SILType subst(SILModule &M, TypeSubstitutionFn subs,
692692
LookupConformanceFn conformances,
693693
CanGenericSignature genericSig = CanGenericSignature(),
694-
bool shouldSubstituteOpaqueArchetypes = false) const;
694+
SubstOptions options = None) const;
695695

696696
SILType subst(Lowering::TypeConverter &tc,
697697
InFlightSubstitution &IFS,

lib/AST/ParameterPack.cpp

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,18 @@ namespace {
3131
/// skipping those captured by nested pack expansion types.
3232
struct PackTypeParameterCollector: TypeWalker {
3333
llvm::SetVector<Type> typeParams;
34+
unsigned expansionLevel;
35+
SmallVector<unsigned, 2> elementLevel;
36+
37+
PackTypeParameterCollector() : expansionLevel(0) {
38+
elementLevel.push_back(0);
39+
}
3440

3541
Action walkToTypePre(Type t) override {
36-
if (t->is<PackExpansionType>())
37-
return Action::SkipChildren;
42+
if (t->is<PackExpansionType>()) {
43+
++expansionLevel;
44+
return Action::Continue;
45+
}
3846

3947
if (auto *boundGenericType = dyn_cast<BoundGenericType>(t.getPointer())) {
4048
if (auto parentType = boundGenericType->getParent())
@@ -58,13 +66,30 @@ struct PackTypeParameterCollector: TypeWalker {
5866
}
5967
}
6068

61-
if (auto *paramTy = t->getAs<GenericTypeParamType>()) {
62-
if (paramTy->isParameterPack())
63-
typeParams.insert(paramTy);
64-
} else if (auto *archetypeTy = t->getAs<PackArchetypeType>()) {
65-
typeParams.insert(archetypeTy->getRoot());
69+
if (auto *eltType = t->getAs<PackElementType>()) {
70+
elementLevel.push_back(eltType->getLevel());
71+
return Action::Continue;
6672
}
6773

74+
if (elementLevel.back() == expansionLevel) {
75+
if (auto *paramTy = t->getAs<GenericTypeParamType>()) {
76+
if (paramTy->isParameterPack())
77+
typeParams.insert(paramTy);
78+
} else if (auto *archetypeTy = t->getAs<PackArchetypeType>()) {
79+
typeParams.insert(archetypeTy->getRoot());
80+
}
81+
}
82+
83+
return Action::Continue;
84+
}
85+
86+
Action walkToTypePost(Type t) override {
87+
if (t->is<PackExpansionType>())
88+
--expansionLevel;
89+
90+
if (t->is<PackElementType>())
91+
elementLevel.pop_back();
92+
6893
return Action::Continue;
6994
}
7095
};
@@ -90,6 +115,16 @@ bool GenericTypeParamType::isParameterPack() const {
90115
GenericTypeParamType::TYPE_SEQUENCE_BIT;
91116
}
92117

118+
bool TypeBase::isParameterPack() {
119+
Type t(this);
120+
121+
while (auto *memberTy = t->getAs<DependentMemberType>())
122+
t = memberTy->getBase();
123+
124+
return t->is<GenericTypeParamType>() &&
125+
t->castTo<GenericTypeParamType>()->isParameterPack();
126+
}
127+
93128
PackType *TypeBase::getPackSubstitutionAsPackType() {
94129
if (auto pack = getAs<PackType>()) {
95130
return pack;

lib/AST/SubstitutionMap.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -192,16 +192,13 @@ SubstitutionMap SubstitutionMap::getCanonical(bool canonicalizeSignature) const
192192

193193
SubstitutionMap SubstitutionMap::get(GenericSignature genericSig,
194194
SubstitutionMap substitutions) {
195-
if (!genericSig) {
196-
assert(!substitutions.hasAnySubstitutableParams() &&
197-
"Shouldn't have substitutions here");
195+
if (!genericSig)
198196
return SubstitutionMap();
199-
}
200197

201198
return SubstitutionMap::get(genericSig,
202199
[&](SubstitutableType *type) -> Type {
203200
return substitutions.lookupSubstitution(
204-
CanSubstitutableType(type));
201+
cast<SubstitutableType>(type->getCanonicalType()));
205202
},
206203
LookUpConformanceInSubstitutionMap(substitutions));
207204
}

lib/AST/Type.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3734,9 +3734,18 @@ PackArchetypeType::get(const ASTContext &Ctx,
37343734
{ShapeType}));
37353735
}
37363736

3737-
CanType PackArchetypeType::getReducedShape() const {
3737+
CanType PackArchetypeType::getReducedShape() {
3738+
// mapTypeIntoContext() also calls getReducedShape() via
3739+
// PackExpansionType::get(), so avoid that by short-circuiting
3740+
// the case where the pack archetype represents its own
3741+
// shape class.
37383742
auto shapeType = getTrailingObjects<PackShape>()->shapeType;
3739-
return getGenericEnvironment()->mapTypeIntoContext(shapeType)->getCanonicalType();
3743+
if (shapeType->isEqual(getInterfaceType()))
3744+
return CanType(this);
3745+
3746+
return getGenericEnvironment()
3747+
->mapTypeIntoContext(shapeType)
3748+
->getCanonicalType();
37403749
}
37413750

37423751
ElementArchetypeType::ElementArchetypeType(

lib/IRGen/MetadataRequest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ SILType IRGenModule::substOpaqueTypesWithUnderlyingTypes(
539539
getSILModule().isWholeModule());
540540
auto underlyingTy =
541541
type.subst(getSILModule(), replacer, replacer, genericSig,
542-
/*substitute opaque*/ true);
542+
SubstFlags::SubstituteOpaqueArchetypes);
543543
return underlyingTy;
544544
}
545545

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4571,13 +4571,15 @@ static bool areABICompatibleParamsOrReturns(SILType a, SILType b,
45714571
inFunction->getModule().isWholeModule());
45724572
if (aa.getASTType()->hasOpaqueArchetype())
45734573
opaqueTypesSubstituted = aa.subst(inFunction->getModule(), replacer,
4574-
replacer, CanGenericSignature(), true);
4574+
replacer, CanGenericSignature(),
4575+
SubstFlags::SubstituteOpaqueArchetypes);
45754576

45764577
auto opaqueTypesSubstituted2 = bb;
45774578
if (bb.getASTType()->hasOpaqueArchetype())
45784579
opaqueTypesSubstituted2 =
45794580
bb.subst(inFunction->getModule(), replacer, replacer,
4580-
CanGenericSignature(), true);
4581+
CanGenericSignature(),
4582+
SubstFlags::SubstituteOpaqueArchetypes);
45814583
if (opaqueTypesSubstituted == opaqueTypesSubstituted2)
45824584
continue;
45834585
}

lib/SIL/IR/SILTypeSubstitution.cpp

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -465,35 +465,29 @@ class SILTypeSubstituter :
465465

466466
} // end anonymous namespace
467467

468-
static bool isSubstitutionInvariant(SILType ty,
469-
bool shouldSubstituteOpaqueArchetypes) {
468+
static bool isSubstitutionInvariant(SILType ty, SubstOptions options) {
470469
return (!ty.hasArchetype() &&
471470
!ty.hasTypeParameter() &&
472-
(!shouldSubstituteOpaqueArchetypes ||
471+
(!options.contains(SubstFlags::SubstituteOpaqueArchetypes) ||
473472
!ty.getRawASTType()->hasOpaqueArchetype()));
474473
}
475474

476475
SILType SILType::subst(TypeConverter &tc, TypeSubstitutionFn subs,
477476
LookupConformanceFn conformances,
478477
CanGenericSignature genericSig,
479-
bool shouldSubstituteOpaqueArchetypes) const {
480-
if (isSubstitutionInvariant(*this, shouldSubstituteOpaqueArchetypes))
478+
SubstOptions options) const {
479+
if (isSubstitutionInvariant(*this, options))
481480
return *this;
482481

483-
auto substOptions =
484-
(shouldSubstituteOpaqueArchetypes
485-
? SubstOptions(SubstFlags::SubstituteOpaqueArchetypes)
486-
: SubstOptions(None));
487-
InFlightSubstitution IFS(subs, conformances, substOptions);
488-
482+
InFlightSubstitution IFS(subs, conformances, options);
489483
SILTypeSubstituter STST(tc, TypeExpansionContext::minimal(), IFS,
490484
genericSig);
491485
return STST.subst(*this);
492486
}
493487

494488
SILType SILType::subst(TypeConverter &tc, InFlightSubstitution &IFS,
495489
CanGenericSignature genericSig) const {
496-
if (isSubstitutionInvariant(*this, IFS.shouldSubstituteOpaqueArchetypes()))
490+
if (isSubstitutionInvariant(*this, IFS.getOptions()))
497491
return *this;
498492

499493
SILTypeSubstituter STST(tc, TypeExpansionContext::minimal(), IFS,
@@ -504,9 +498,8 @@ SILType SILType::subst(TypeConverter &tc, InFlightSubstitution &IFS,
504498
SILType SILType::subst(SILModule &M, TypeSubstitutionFn subs,
505499
LookupConformanceFn conformances,
506500
CanGenericSignature genericSig,
507-
bool shouldSubstituteOpaqueArchetypes) const {
508-
return subst(M.Types, subs, conformances, genericSig,
509-
shouldSubstituteOpaqueArchetypes);
501+
SubstOptions options) const {
502+
return subst(M.Types, subs, conformances, genericSig, options);
510503
}
511504

512505
SILType SILType::subst(TypeConverter &tc, SubstitutionMap subs) const {
@@ -521,7 +514,7 @@ SILType SILType::subst(SILModule &M, SubstitutionMap subs) const{
521514

522515
SILType SILType::subst(SILModule &M, SubstitutionMap subs,
523516
TypeExpansionContext context) const {
524-
if (isSubstitutionInvariant(*this, false))
517+
if (isSubstitutionInvariant(*this, None))
525518
return *this;
526519

527520
InFlightSubstitutionViaSubMap IFS(subs, None);

lib/SILGen/SILGenConstructor.cpp

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -284,17 +284,7 @@ static SubstitutionMap getSubstitutionsForPropertyInitializer(
284284
// replacement types are the archetypes of the initializer itself.
285285
return SubstitutionMap::get(
286286
nominal->getGenericSignatureOfContext(),
287-
[&](SubstitutableType *type) -> Type {
288-
if (auto gp = type->getAs<GenericTypeParamType>()) {
289-
auto archetype = genericEnv->mapTypeIntoContext(gp);
290-
if (!gp->isParameterPack())
291-
return archetype;
292-
293-
return PackType::getSingletonPackExpansion(archetype);
294-
}
295-
296-
return Type(type);
297-
},
287+
QuerySubstitutionMap{genericEnv->getForwardingSubstitutionMap()},
298288
LookUpConformanceInModule(dc->getParentModule()));
299289
}
300290

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,6 +1062,35 @@ CheckGenericArgumentsResult::Kind TypeChecker::checkGenericArguments(
10621062
return CheckGenericArgumentsResult::Success;
10631063
}
10641064

1065+
CheckGenericArgumentsResult::Kind TypeChecker::checkGenericArguments(
1066+
ArrayRef<Requirement> requirements) {
1067+
SmallVector<Requirement, 4> worklist(requirements.begin(), requirements.end());
1068+
1069+
bool hadSubstFailure = false;
1070+
1071+
while (!worklist.empty()) {
1072+
auto req = worklist.pop_back_val();
1073+
switch (req.checkRequirement(worklist, /*allowMissing=*/true)) {
1074+
case CheckRequirementResult::Success:
1075+
case CheckRequirementResult::ConditionalConformance:
1076+
case CheckRequirementResult::PackRequirement:
1077+
break;
1078+
1079+
case CheckRequirementResult::RequirementFailure:
1080+
return CheckGenericArgumentsResult::RequirementFailure;
1081+
1082+
case CheckRequirementResult::SubstitutionFailure:
1083+
hadSubstFailure = true;
1084+
break;
1085+
}
1086+
}
1087+
1088+
if (hadSubstFailure)
1089+
return CheckGenericArgumentsResult::SubstitutionFailure;
1090+
1091+
return CheckGenericArgumentsResult::Success;
1092+
}
1093+
10651094
Requirement
10661095
RequirementRequest::evaluate(Evaluator &evaluator,
10671096
WhereClauseOwner owner,

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5733,9 +5733,7 @@ TypeChecker::conformsToProtocol(Type T, ProtocolDecl *Proto, ModuleDecl *M,
57335733

57345734
// If we have a conditional requirements that we need to check, do so now.
57355735
if (!condReqs->empty()) {
5736-
auto conditionalCheckResult = checkGenericArguments(
5737-
M, *condReqs,
5738-
[](SubstitutableType *dependentType) { return Type(dependentType); });
5736+
auto conditionalCheckResult = checkGenericArguments(*condReqs);
57395737
switch (conditionalCheckResult) {
57405738
case CheckGenericArgumentsResult::Success:
57415739
break;

lib/Sema/TypeChecker.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,10 @@ checkGenericArguments(ModuleDecl *module, ArrayRef<Requirement> requirements,
535535
TypeSubstitutionFn substitutions,
536536
SubstOptions options = None);
537537

538+
/// Check the given requirements without applying substitutions.
539+
CheckGenericArgumentsResult::Kind
540+
checkGenericArguments(ArrayRef<Requirement> requirements);
541+
538542
/// Checks whether the generic requirements imposed on the nested type
539543
/// declaration \p decl (if present) are in agreement with the substitutions
540544
/// that are needed to spell it as a member of the given parent type

lib/Serialization/Serialization.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5652,6 +5652,7 @@ void Serializer::writeAllDeclsAndTypes() {
56525652
registerDeclTypeAbbr<OptionalTypeLayout>();
56535653
registerDeclTypeAbbr<DynamicSelfTypeLayout>();
56545654
registerDeclTypeAbbr<PackExpansionTypeLayout>();
5655+
registerDeclTypeAbbr<PackElementTypeLayout>();
56555656
registerDeclTypeAbbr<PackTypeLayout>();
56565657
registerDeclTypeAbbr<SILPackTypeLayout>();
56575658

0 commit comments

Comments
 (0)