Skip to content

Commit 2ea4586

Browse files
hborlasimanerush
authored andcommitted
[Requirement Machine] Implement same-element requirements.
1 parent 57e38dc commit 2ea4586

23 files changed

+184
-31
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2022,6 +2022,9 @@ void PrintAST::printRequirement(const Requirement &req) {
20222022
SmallVector<Type, 2> rootParameterPacks;
20232023
getTransformedType(req.getFirstType())
20242024
->getTypeParameterPacks(rootParameterPacks);
2025+
if (req.getKind() != RequirementKind::Layout)
2026+
getTransformedType(req.getSecondType())
2027+
->getTypeParameterPacks(rootParameterPacks);
20252028
bool isPackRequirement = !rootParameterPacks.empty();
20262029

20272030
switch (req.getKind()) {

lib/AST/GenericEnvironment.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,16 @@ struct FindElementArchetypeForOpenedPackParam {
181181
: findElementParam(env, openedPacks), getElementArchetype(env) {}
182182

183183

184-
ElementArchetypeType *operator()(Type interfaceType) {
184+
Type operator()(Type interfaceType) {
185185
assert(interfaceType->isTypeParameter());
186186
if (auto member = interfaceType->getAs<DependentMemberType>()) {
187-
auto baseArchetype = (*this)(member->getBase());
187+
auto baseArchetype = (*this)(member->getBase())
188+
->castTo<ElementArchetypeType>();
188189
return baseArchetype->getNestedType(member->getAssocType())
189190
->castTo<ElementArchetypeType>();
190191
}
191192
assert(interfaceType->is<GenericTypeParamType>());
192-
return getElementArchetype(findElementParam(interfaceType))
193-
->castTo<ElementArchetypeType>();
193+
return getElementArchetype(findElementParam(interfaceType));
194194
}
195195
};
196196

lib/AST/GenericSignature.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,10 @@ int swift::compareDependentTypes(Type type1, Type type2) {
782782
// Fast-path check for equality.
783783
if (type1->isEqual(type2)) return 0;
784784

785+
// Packs are always ordered after scalar type parameters.
786+
if (type1->isParameterPack() != type2->isParameterPack())
787+
return type2->isParameterPack() ? -1 : +1;
788+
785789
// Ordering is as follows:
786790
// - Generic params
787791
auto gp1 = type1->getAs<GenericTypeParamType>();

lib/AST/RequirementMachine/GenericSignatureQueries.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ RequirementMachine::getLongestValidPrefix(const MutableTerm &term) const {
281281
case Symbol::Kind::ConcreteType:
282282
case Symbol::Kind::ConcreteConformance:
283283
case Symbol::Kind::Shape:
284+
case Symbol::Kind::PackElement:
284285
llvm::errs() <<"Invalid symbol in a type term: " << term << "\n";
285286
abort();
286287
}
@@ -310,6 +311,20 @@ bool RequirementMachine::isReducedType(Type type) const {
310311
if (!component->hasTypeParameter())
311312
return Action::SkipNode;
312313

314+
if (auto *expansion = component->getAs<PackExpansionType>()) {
315+
auto pattern = expansion->getPatternType();
316+
auto shape = expansion->getCountType();
317+
if (!Self.isReducedType(pattern))
318+
return Action::Stop;
319+
320+
auto reducedShape =
321+
Self.getReducedShape(shape, Self.getGenericParams());
322+
if (reducedShape->getCanonicalType() != CanType(shape))
323+
return Action::Stop;
324+
325+
return Action::SkipChildren;
326+
}
327+
313328
if (!component->isTypeParameter())
314329
return Action::Continue;
315330

@@ -804,6 +819,7 @@ void RequirementMachine::verify(const MutableTerm &term) const {
804819
switch (symbol.getKind()) {
805820
case Symbol::Kind::Protocol:
806821
case Symbol::Kind::GenericParam:
822+
case Symbol::Kind::PackElement:
807823
erased.add(symbol);
808824
continue;
809825

@@ -843,6 +859,7 @@ void RequirementMachine::verify(const MutableTerm &term) const {
843859
case Symbol::Kind::Superclass:
844860
case Symbol::Kind::ConcreteType:
845861
case Symbol::Kind::ConcreteConformance:
862+
case Symbol::Kind::PackElement:
846863
llvm::errs() << "Bad interior symbol " << symbol << " in " << term << "\n";
847864
abort();
848865
break;

lib/AST/RequirementMachine/HomotopyReduction.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,8 @@ RewriteSystem::getMinimizedGenericSignatureRules() const {
691691
continue;
692692
}
693693

694-
if (rule.getLHS()[0].getKind() != Symbol::Kind::GenericParam)
694+
if (rule.getLHS()[0].getKind() != Symbol::Kind::PackElement &&
695+
rule.getLHS()[0].getKind() != Symbol::Kind::GenericParam)
695696
continue;
696697

697698
rules.push_back(ruleID);

lib/AST/RequirementMachine/InterfaceType.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,9 @@ getTypeForSymbolRange(const Symbol *begin, const Symbol *end,
298298
// member type rooted at Self; handle the associated type below.
299299
break;
300300

301+
case Symbol::Kind::PackElement:
302+
continue;
303+
301304
case Symbol::Kind::Name:
302305
case Symbol::Kind::Layout:
303306
case Symbol::Kind::Superclass:

lib/AST/RequirementMachine/MinimalConformances.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ static const ProtocolDecl *getParentConformanceForTerm(Term lhs) {
287287
case Symbol::Kind::ConcreteType:
288288
case Symbol::Kind::ConcreteConformance:
289289
case Symbol::Kind::Shape:
290+
case Symbol::Kind::PackElement:
290291
break;
291292
}
292293

@@ -553,6 +554,7 @@ void RewriteSystem::computeCandidateConformancePaths(
553554
//
554555
// where Y is the simplified form of X.W.
555556
} else if (rhs.isAnyConformanceRule() &&
557+
!lhs.isSameElementRule() &&
556558
(unsigned)(lhs.getLHS().end() - from) < rhs.getLHS().size()) {
557559
if (Debug.contains(DebugFlags::MinimalConformancesDetail)) {
558560
llvm::dbgs() << "Case 2: same-type suffix\n";

lib/AST/RequirementMachine/PropertyUnification.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,7 @@ void PropertyMap::addProperty(
669669
case Symbol::Kind::GenericParam:
670670
case Symbol::Kind::AssociatedType:
671671
case Symbol::Kind::Shape:
672+
case Symbol::Kind::PackElement:
672673
break;
673674
}
674675

lib/AST/RequirementMachine/RequirementBuilder.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ void RequirementBuilder::addRequirementRules(ArrayRef<unsigned> rules) {
229229
case Symbol::Kind::AssociatedType:
230230
case Symbol::Kind::GenericParam:
231231
case Symbol::Kind::Shape:
232+
case Symbol::Kind::PackElement:
232233
break;
233234
}
234235

lib/AST/RequirementMachine/RequirementLowering.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -220,14 +220,6 @@ static void desugarSameTypeRequirement(
220220
break;
221221
}
222222

223-
// If one side is a parameter pack, this is a same-element requirement, which
224-
// is not yet supported.
225-
if (firstType->isParameterPack() != secondType->isParameterPack()) {
226-
errors.push_back(RequirementError::forSameElement(
227-
{kind, sugaredFirstType, secondType}, loc));
228-
return true;
229-
}
230-
231223
if (firstType->isTypeParameter() && secondType->isTypeParameter()) {
232224
result.emplace_back(kind, sugaredFirstType, secondType);
233225
return true;

0 commit comments

Comments
 (0)