Skip to content

Commit 2fd5843

Browse files
authored
Merge pull request #70355 from simanerush/pack-iteration-fixes
[SE-0408] Pack iteration review feedback!
2 parents d06aeee + 40167fb commit 2fd5843

File tree

8 files changed

+38
-25
lines changed

8 files changed

+38
-25
lines changed

include/swift/AST/Decl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5861,6 +5861,9 @@ enum class PropertyWrapperSynthesizedPropertyKind {
58615861
class VarDecl : public AbstractStorageDecl {
58625862
friend class NamingPatternRequest;
58635863
NamedPattern *NamingPattern = nullptr;
5864+
/// When the variable is declared in context of a for-in loop over the elements of
5865+
/// a parameter pack, this is the opened element environment of the pack expansion
5866+
/// to use as the variable's context generic environment.
58645867
GenericEnvironment *OpenedElementEnvironment = nullptr;
58655868

58665869
public:

include/swift/Sema/ConstraintSystem.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3819,10 +3819,20 @@ class ConstraintSystem {
38193819
RememberChoice_t rememberChoice,
38203820
ConstraintLocatorBuilder locator,
38213821
ConstraintFix *compatFix = nullptr);
3822-
3823-
/// Add a materialize constraint for a pack expansion.
3822+
3823+
/// Given a tuple with a single unlabeled element that represents a pack
3824+
/// expansion (either directly via \c PackExpansionType or through a type
3825+
/// variable constrained to a pack expansion), materialize the pack expansion
3826+
/// and return its pattern type as a result. The result is a type variable
3827+
/// because element of the tuple is not required to be resolved at the time of
3828+
/// the call and operation is delayed until the element is sufficiently
3829+
/// resolved (see \c simplifyMaterializePackExpansionConstraint)
3830+
///
3831+
/// \param tupleType A tuple with a single unlabeled element that represents a
3832+
/// pack expansion.
3833+
/// \param locator The locator.
38243834
TypeVariableType *
3825-
addMaterializePackExpansionConstraint(Type patternType,
3835+
addMaterializePackExpansionConstraint(Type tupleType,
38263836
ConstraintLocatorBuilder locator);
38273837

38283838
/// Add a disjunction constraint.

include/swift/Sema/SyntacticElementTarget.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929
namespace swift {
3030

3131
namespace constraints {
32-
/// Describes information specific to a sequence
33-
/// in a for-each loop.
32+
/// Describes information about a for-in loop over a sequence that needs to be
33+
/// tracked in the constraint system.
3434
struct SequenceIterationInfo {
3535
/// The type of the sequence.
3636
Type sequenceType;
@@ -48,18 +48,16 @@ struct SequenceIterationInfo {
4848
Expr *nextCall;
4949
};
5050

51-
/// Describes information specific to a pack expansion expression
52-
/// in a for-each loop.
51+
/// Describes information about a for-in loop over a pack that needs to be
52+
/// tracked in the constraint system.
5353
struct PackIterationInfo {
5454
/// The type of the pattern that matches the elements.
5555
Type patternType;
5656
};
5757

58-
/// Describes information about a for-each loop that needs to be tracked
58+
/// Describes information about a for-in loop that needs to be tracked
5959
/// within the constraint system.
60-
struct ForEachStmtInfo : TaggedUnion<SequenceIterationInfo, PackIterationInfo> {
61-
using TaggedUnion::TaggedUnion;
62-
};
60+
using ForEachStmtInfo = TaggedUnion<SequenceIterationInfo, PackIterationInfo>;
6361

6462
/// Describes the target to which a constraint system's solution can be
6563
/// applied.

lib/AST/ASTVerifier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2644,7 +2644,7 @@ class Verifier : public ASTWalker {
26442644
}
26452645

26462646
// Catch cases where there's a missing generic environment.
2647-
if (var->getTypeInContext()->is<ErrorType>()) {
2647+
if (var->getTypeInContext()->hasError()) {
26482648
Out << "VarDecl is missing a Generic Environment: ";
26492649
var->getInterfaceType().print(Out);
26502650
Out << "\n";

lib/AST/Decl.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7163,8 +7163,9 @@ VarDecl::VarDecl(DeclKind kind, bool isStatic, VarDecl::Introducer introducer,
71637163
}
71647164

71657165
Type VarDecl::getTypeInContext() const {
7166-
// If we are performing pack iteration, use the generic environment of the
7167-
// pack expansion expression to get the right context of a local variable.
7166+
// If the variable is declared in context of a for-in loop over the elements
7167+
// of a parameter pack, its interface type must be mapped into context using
7168+
// the opened element environment of the pack expansion.
71687169
if (auto *env = getOpenedElementEnvironment())
71697170
return GenericEnvironment::mapTypeIntoContext(env, getInterfaceType());
71707171

lib/SILGen/SILGenStmt.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,8 +1246,6 @@ void StmtEmitter::visitRepeatWhileStmt(RepeatWhileStmt *S) {
12461246
}
12471247

12481248
void StmtEmitter::visitForEachStmt(ForEachStmt *S) {
1249-
// Emit the 'iterator' variable that we'll be using for iteration.
1250-
LexicalScope OuterForScope(SGF, CleanupLocation(S));
12511249

12521250
if (auto *expansion =
12531251
dyn_cast<PackExpansionExpr>(S->getTypeCheckedSequence())) {
@@ -1256,8 +1254,6 @@ void StmtEmitter::visitForEachStmt(ForEachStmt *S) {
12561254
->getCanonicalType());
12571255

12581256
JumpDest loopDest = createJumpDest(S->getBody());
1259-
1260-
// Set the destinations for 'break' and 'continue'.
12611257
JumpDest endDest = createJumpDest(S->getBody());
12621258

12631259
SGF.emitDynamicPackLoop(
@@ -1271,6 +1267,7 @@ void StmtEmitter::visitForEachStmt(ForEachStmt *S) {
12711267

12721268
SGF.emitExprInto(expansion->getPatternExpr(), letValueInit.get());
12731269

1270+
// Set the destinations for 'break' and 'continue'.
12741271
SGF.BreakContinueDestStack.push_back({S, endDest, loopDest});
12751272
visit(S->getBody());
12761273
SGF.BreakContinueDestStack.pop_back();
@@ -1284,6 +1281,8 @@ void StmtEmitter::visitForEachStmt(ForEachStmt *S) {
12841281
return;
12851282
}
12861283

1284+
// Emit the 'iterator' variable that we'll be using for iteration.
1285+
LexicalScope OuterForScope(SGF, CleanupLocation(S));
12871286
SGF.emitPatternBinding(S->getIteratorVar(),
12881287
/*index=*/0, /*debuginfo*/ true);
12891288

lib/Sema/CSGen.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4451,8 +4451,8 @@ static bool generateInitPatternConstraints(ConstraintSystem &cs,
44514451
return false;
44524452
}
44534453

4454-
/// Generate constraints for a for-in statement preamble, expecting a
4455-
/// `PackExpansionExpr`.
4454+
/// Generate constraints for a for-in statement preamble where the expression
4455+
/// is a `PackExpansionExpr`.
44564456
static llvm::Optional<PackIterationInfo>
44574457
generateForEachStmtConstraints(ConstraintSystem &cs, DeclContext *dc,
44584458
PackExpansionExpr *expansion, Type patternType) {
@@ -4528,6 +4528,7 @@ generateForEachStmtConstraints(ConstraintSystem &cs, DeclContext *dc,
45284528

45294529
auto *makeIteratorCall =
45304530
CallExpr::createImplicitEmpty(ctx, makeIteratorRef);
4531+
45314532
Pattern *pattern = NamedPattern::createImplicit(ctx, makeIteratorVar);
45324533
auto *PB = PatternBindingDecl::createImplicit(
45334534
ctx, StaticSpellingKind::None, pattern, makeIteratorCall, dc);
@@ -4544,6 +4545,7 @@ generateForEachStmtConstraints(ConstraintSystem &cs, DeclContext *dc,
45444545
return llvm::None;
45454546

45464547
sequenceIterationInfo.makeIteratorVar = PB;
4548+
45474549
// Type of sequence expression has to conform to Sequence protocol.
45484550
//
45494551
// Note that the following emulates having `$generator` separately
@@ -4610,7 +4612,7 @@ generateForEachStmtConstraints(ConstraintSystem &cs, DeclContext *dc,
46104612
cs.setTargetFor(sequenceIterationInfo.nextCall, nextTarget);
46114613
}
46124614

4613-
// Generate constraints for the pattern
4615+
// Generate constraints for the pattern.
46144616
Type initType =
46154617
cs.generateConstraints(typeCheckedPattern, elementLocator,
46164618
shouldBindPatternVarsOneWay, nullptr, 0);
@@ -4681,7 +4683,7 @@ generateForEachStmtConstraints(ConstraintSystem &cs,
46814683
if (isa<PackExpansionExpr>(forEachExpr)) {
46824684
auto *expansion = cast<PackExpansionExpr>(forEachExpr);
46834685

4684-
// Generate constraints for the pattern
4686+
// Generate constraints for the pattern.
46854687
Type patternType = cs.generateConstraints(
46864688
pattern, elementLocator, target.shouldBindPatternVarsOneWay(), nullptr,
46874689
0);

lib/Sema/CSSimplify.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15648,11 +15648,11 @@ void ConstraintSystem::addExplicitConversionConstraint(
1564815648
}
1564915649

1565015650
TypeVariableType *ConstraintSystem::addMaterializePackExpansionConstraint(
15651-
Type patternType, ConstraintLocatorBuilder locator) {
15652-
assert(isSingleUnlabeledPackExpansionTuple(patternType));
15651+
Type tupleType, ConstraintLocatorBuilder locator) {
15652+
assert(isSingleUnlabeledPackExpansionTuple(tupleType));
1565315653
TypeVariableType *packVar =
1565415654
createTypeVariable(getConstraintLocator(locator), TVO_CanBindToPack);
15655-
addConstraint(ConstraintKind::MaterializePackExpansion, patternType, packVar,
15655+
addConstraint(ConstraintKind::MaterializePackExpansion, tupleType, packVar,
1565615656
getConstraintLocator(locator, {ConstraintLocator::Member}));
1565715657
return packVar;
1565815658
}

0 commit comments

Comments
 (0)