Skip to content

Commit 9e7bb3d

Browse files
committed
Merge remote-tracking branch 'origin/main' into rebranch
2 parents fd89e3a + 6400a29 commit 9e7bb3d

34 files changed

+223
-35
lines changed

include/swift/Basic/Features.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ EXPERIMENTAL_FEATURE(CodeItemMacros, false)
231231
EXPERIMENTAL_FEATURE(PreambleMacros, false)
232232
EXPERIMENTAL_FEATURE(TupleConformances, false)
233233
EXPERIMENTAL_FEATURE(FullTypedThrows, false)
234+
EXPERIMENTAL_FEATURE(SameElementRequirements, false)
234235

235236
// Whether to enable @_used and @_section attributes
236237
EXPERIMENTAL_FEATURE(SymbolLinkageMarkers, true)

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/FeatureSet.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ UNINTERESTING_FEATURE(StaticExclusiveOnly)
134134
UNINTERESTING_FEATURE(ExtractConstantsFromMembers)
135135
UNINTERESTING_FEATURE(FixedArrays)
136136
UNINTERESTING_FEATURE(GroupActorErrors)
137+
UNINTERESTING_FEATURE(SameElementRequirements)
137138

138139
static bool usesFeatureSendingArgsAndResults(Decl *decl) {
139140
auto isFunctionTypeWithSending = [](Type type) {

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: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,7 @@ void GenericSignature::verify(ArrayRef<Requirement> reqts) const {
936936
llvm::errs() << "\n";
937937
dumpAndAbort();
938938
}
939+
939940
if (compareDependentTypes(firstType, secondType) >= 0) {
940941
llvm::errs() << "Out-of-order type parameters: ";
941942
reqt.dump(llvm::errs());

lib/AST/RequirementMachine/GenericSignatureQueries.cpp

Lines changed: 3 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
}
@@ -804,6 +805,7 @@ void RequirementMachine::verify(const MutableTerm &term) const {
804805
switch (symbol.getKind()) {
805806
case Symbol::Kind::Protocol:
806807
case Symbol::Kind::GenericParam:
808+
case Symbol::Kind::PackElement:
807809
erased.add(symbol);
808810
continue;
809811

@@ -843,6 +845,7 @@ void RequirementMachine::verify(const MutableTerm &term) const {
843845
case Symbol::Kind::Superclass:
844846
case Symbol::Kind::ConcreteType:
845847
case Symbol::Kind::ConcreteConformance:
848+
case Symbol::Kind::PackElement:
846849
llvm::errs() << "Bad interior symbol " << symbol << " in " << term << "\n";
847850
abort();
848851
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: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,24 +229,49 @@ 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

235236
llvm_unreachable("Invalid symbol kind");
236237
}
237238

239+
MutableTerm constraintTerm = MutableTerm(rule.getLHS());
240+
MutableTerm subjectTerm = MutableTerm(rule.getRHS());
241+
242+
RewriteContext &ctx = this->System.getRewriteContext();
243+
244+
// Drop the [element] symbol from lhs to determine if we need to swap the
245+
// sides.
246+
if (constraintTerm[0].getKind() == Symbol::Kind::PackElement) {
247+
constraintTerm =
248+
MutableTerm(constraintTerm.begin() + 1, constraintTerm.end());
249+
250+
// Make sure that the shorter term is ordered first.
251+
if (constraintTerm.compare(subjectTerm, ctx) == -1) {
252+
MutableTerm tempTerm = subjectTerm;
253+
subjectTerm = constraintTerm;
254+
constraintTerm = tempTerm;
255+
}
256+
}
257+
238258
ASSERT(rule.getLHS().back().getKind() != Symbol::Kind::Protocol);
239259

240-
MutableTerm constraintTerm(rule.getLHS());
241260
if (constraintTerm.back().getKind() == Symbol::Kind::Shape) {
242261
ASSERT(rule.getRHS().back().getKind() == Symbol::Kind::Shape);
243262
// Strip off the shape symbol from the constraint term.
244263
constraintTerm = MutableTerm(constraintTerm.begin(),
245264
constraintTerm.end() - 1);
246265
}
247266

267+
if (constraintTerm.front().getKind() == Symbol::Kind::PackElement) {
268+
// Strip off the element symbol from the constraint term.
269+
constraintTerm = MutableTerm(constraintTerm.begin() + 1,
270+
constraintTerm.end());
271+
}
272+
248273
auto constraintType = Map.getTypeForTerm(constraintTerm, GenericParams);
249-
Components[rule.getRHS()].Members.push_back(constraintType);
274+
Components[Term::get(subjectTerm, ctx)].Members.push_back(constraintType);
250275
};
251276

252277
if (Debug) {
@@ -313,6 +338,10 @@ void RequirementBuilder::processConnectedComponents() {
313338
subjectTerm = MutableTerm(subjectTerm.begin(), subjectTerm.end() - 1);
314339
} else {
315340
kind = RequirementKind::SameType;
341+
if (subjectTerm.front().getKind() == Symbol::Kind::PackElement) {
342+
// Strip off the element symbol from the subject term.
343+
subjectTerm = MutableTerm(subjectTerm.begin() + 1, subjectTerm.end());
344+
}
316345
}
317346

318347
auto subjectType = Map.getTypeForTerm(subjectTerm, GenericParams);

lib/AST/RequirementMachine/RequirementLowering.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,15 @@ 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;
223+
auto &ctx = firstType->getASTContext();
224+
if (!ctx.LangOpts.hasFeature(Feature::SameElementRequirements)) {
225+
// If one side is a parameter pack, this is a same-element requirement, which
226+
// is not yet supported.
227+
if (firstType->isParameterPack() != secondType->isParameterPack()) {
228+
errors.push_back(RequirementError::forSameElement(
229+
{kind, sugaredFirstType, secondType}, loc));
230+
return true;
231+
}
229232
}
230233

231234
if (firstType->isTypeParameter() && secondType->isTypeParameter()) {

lib/AST/RequirementMachine/RequirementMachine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ void RequirementMachine::dump(llvm::raw_ostream &out) const {
551551
for (auto paramTy : Params) {
552552
out << " " << Type(paramTy);
553553
if (paramTy->isParameterPack())
554-
out << "";
554+
out << " " << paramTy;
555555
}
556556
out << " >";
557557
}

lib/AST/RequirementMachine/RequirementMachineRequests.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -986,13 +986,13 @@ InferredGenericSignatureRequest::evaluate(
986986
if (reduced->hasError() || reduced->isEqual(genericParam))
987987
continue;
988988

989-
if (reduced->isTypeParameter()) {
990-
// If one side is a parameter pack and the other is not, this is a
991-
// same-element requirement that cannot be expressed with only one
992-
// type parameter.
993-
if (genericParam->isParameterPack() != reduced->isParameterPack())
994-
continue;
989+
// If one side is a parameter pack and the other is not, this is a
990+
// same-element requirement that cannot be expressed with only one
991+
// type parameter.
992+
if (genericParam->isParameterPack() != reduced->isParameterPack())
993+
continue;
995994

995+
if (reduced->isTypeParameter()) {
996996
ctx.Diags.diagnose(loc, diag::requires_generic_params_made_equal,
997997
genericParam, result->getSugaredType(reduced))
998998
.warnUntilSwiftVersion(6);

lib/AST/RequirementMachine/RewriteContext.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ static DebugOptions parseDebugFlags(StringRef debugFlags) {
200200

201201
RewriteContext::RewriteContext(ASTContext &ctx)
202202
: TheShapeSymbol(nullptr),
203+
ThePackElementSymbol(nullptr),
203204
Context(ctx),
204205
Stats(ctx.Stats),
205206
SymbolHistogram(Symbol::NumKinds),

lib/AST/RequirementMachine/RewriteContext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ class RewriteContext final {
4848
/// The singleton storage for shape symbols.
4949
Symbol::Storage *TheShapeSymbol;
5050

51+
/// The singleton storage for pack element symbols.
52+
Symbol::Storage *ThePackElementSymbol;
53+
5154
/// Folding set for uniquing terms.
5255
llvm::FoldingSet<Term::Storage> Terms;
5356

lib/AST/RequirementMachine/RewriteSystem.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,9 @@ void RewriteSystem::verifyRewriteRules(ValidityPolicy policy) const {
555555
}
556556

557557
if (index != 0) {
558-
ASSERT_RULE(symbol.getKind() != Symbol::Kind::GenericParam);
558+
ASSERT_RULE(symbol.getKind() != Symbol::Kind::GenericParam ||
559+
(index == 1 &&
560+
lhs[index - 1].getKind() == Symbol::Kind::PackElement));
559561
}
560562

561563
if (!rule.isLHSSimplified() &&
@@ -610,7 +612,9 @@ void RewriteSystem::verifyRewriteRules(ValidityPolicy policy) const {
610612
}
611613

612614
if (index != 0) {
613-
ASSERT_RULE(symbol.getKind() != Symbol::Kind::GenericParam);
615+
ASSERT_RULE(symbol.getKind() != Symbol::Kind::GenericParam ||
616+
(index == 1 &&
617+
lhs[index - 1].getKind() == Symbol::Kind::PackElement));
614618
}
615619

616620
if (!rule.isRHSSimplified() &&

lib/AST/RequirementMachine/Rule.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ const ProtocolDecl *Rule::isAnyConformanceRule() const {
7474
case Symbol::Kind::AssociatedType:
7575
case Symbol::Kind::GenericParam:
7676
case Symbol::Kind::Shape:
77+
case Symbol::Kind::PackElement:
7778
break;
7879
}
7980

@@ -145,6 +146,11 @@ bool Rule::isCircularConformanceRule() const {
145146
return true;
146147
}
147148

149+
/// Returns \c true if this rule is prefixed with the \c [element] symbol.
150+
bool Rule::isSameElementRule() const {
151+
return LHS[0].getKind() == Symbol::Kind::PackElement;
152+
}
153+
148154
/// A protocol typealias rule takes one of the following two forms,
149155
/// where T is a name symbol:
150156
///

lib/AST/RequirementMachine/Rule.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ class Rule final {
123123

124124
bool isCircularConformanceRule() const;
125125

126+
bool isSameElementRule() const;
127+
126128
/// See above for an explanation of these predicates.
127129
bool isPermanent() const {
128130
return Permanent;

lib/AST/RequirementMachine/RuleBuilder.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,14 @@ void RuleBuilder::addRequirement(const Requirement &req,
380380
: Context.getSubstitutionSchemaFromType(
381381
otherType, proto, result));
382382

383+
// If 'T' is a parameter pack, this is a same-element
384+
// requirement that becomes the following rewrite rule:
385+
//
386+
// [element].T.[concrete: C<X, Y>] => [element].T
387+
if (subjectType->isParameterPack()) {
388+
subjectTerm.prepend(Symbol::forPackElement(Context));
389+
}
390+
383391
constraintTerm = subjectTerm;
384392
constraintTerm.add(Symbol::forConcreteType(otherType, result, Context));
385393
break;
@@ -390,6 +398,16 @@ void RuleBuilder::addRequirement(const Requirement &req,
390398
otherType, *substitutions)
391399
: Context.getMutableTermForType(
392400
otherType, proto));
401+
402+
if (subjectType->isParameterPack() != otherType->isParameterPack()) {
403+
// This is a same-element requirement.
404+
if (subjectType->isParameterPack()) {
405+
subjectTerm.prepend(Symbol::forPackElement(Context));
406+
} else {
407+
constraintTerm.prepend(Symbol::forPackElement(Context));
408+
}
409+
}
410+
393411
break;
394412
}
395413
}

0 commit comments

Comments
 (0)