Skip to content

Commit 5832181

Browse files
committed
Sema
1 parent 98e65d0 commit 5832181

File tree

8 files changed

+332
-119
lines changed

8 files changed

+332
-119
lines changed

include/swift/AST/Decl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5855,6 +5855,7 @@ enum class PropertyWrapperSynthesizedPropertyKind {
58555855
class VarDecl : public AbstractStorageDecl {
58565856
friend class NamingPatternRequest;
58575857
NamedPattern *NamingPattern = nullptr;
5858+
GenericEnvironment *OpenedElementEnvironment = nullptr;
58585859

58595860
public:
58605861
enum class Introducer : uint8_t {
@@ -5982,6 +5983,13 @@ class VarDecl : public AbstractStorageDecl {
59825983
NamedPattern *getNamingPattern() const;
59835984
void setNamingPattern(NamedPattern *Pat);
59845985

5986+
GenericEnvironment *getOpenedElementEnvironment() const {
5987+
return OpenedElementEnvironment;
5988+
}
5989+
void setOpenedElementEnvironment(GenericEnvironment *Env) {
5990+
OpenedElementEnvironment = Env;
5991+
}
5992+
59855993
/// If this is a VarDecl that does not belong to a CaseLabelItem's pattern,
59865994
/// return this. Otherwise, this VarDecl must belong to a CaseStmt's
59875995
/// CaseLabelItem. In that case, return the first case label item of the first

include/swift/Sema/SyntacticElementTarget.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,16 @@
2222
#include "swift/AST/Pattern.h"
2323
#include "swift/AST/Stmt.h"
2424
#include "swift/AST/TypeLoc.h"
25+
#include "swift/Basic/TaggedUnion.h"
2526
#include "swift/Sema/ConstraintLocator.h"
2627
#include "swift/Sema/ContextualTypeInfo.h"
2728

2829
namespace swift {
2930

3031
namespace constraints {
31-
/// Describes information about a for-each loop that needs to be tracked
32-
/// within the constraint system.
33-
struct ForEachStmtInfo {
32+
/// Describes information specific to a sequence
33+
/// in a for-each loop.
34+
struct SequenceIterationInfo {
3435
/// The type of the sequence.
3536
Type sequenceType;
3637

@@ -47,6 +48,19 @@ struct ForEachStmtInfo {
4748
Expr *nextCall;
4849
};
4950

51+
/// Describes information specific to a pack expansion expression
52+
/// in a for-each loop.
53+
struct PackIterationInfo {
54+
/// The type of the pattern that matches the elements.
55+
Type patternType;
56+
};
57+
58+
/// Describes information about a for-each loop that needs to be tracked
59+
/// within the constraint system.
60+
struct ForEachStmtInfo : TaggedUnion<SequenceIterationInfo, PackIterationInfo> {
61+
using TaggedUnion::TaggedUnion;
62+
};
63+
5064
/// Describes the target to which a constraint system's solution can be
5165
/// applied.
5266
class SyntacticElementTarget {

lib/AST/ASTVerifier.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,13 @@ class Verifier : public ASTWalker {
795795
if (!shouldVerify(cast<Stmt>(S)))
796796
return false;
797797

798+
if (auto *expansion =
799+
dyn_cast<PackExpansionExpr>(S->getParsedSequence())) {
800+
if (!shouldVerify(expansion)) {
801+
return false;
802+
}
803+
}
804+
798805
if (!S->getElementExpr())
799806
return true;
800807

@@ -804,6 +811,11 @@ class Verifier : public ASTWalker {
804811
}
805812

806813
void cleanup(ForEachStmt *S) {
814+
if (auto *expansion =
815+
dyn_cast<PackExpansionExpr>(S->getParsedSequence())) {
816+
cleanup(expansion);
817+
}
818+
807819
if (!S->getElementExpr())
808820
return;
809821

@@ -2605,6 +2617,16 @@ class Verifier : public ASTWalker {
26052617
abort();
26062618
}
26072619

2620+
// If we are performing pack iteration, variables have to carry the
2621+
// generic environment. Catching the missing environment here will prevent
2622+
// the code from being lowered.
2623+
if (var->getTypeInContext()->is<ErrorType>()) {
2624+
Out << "VarDecl is missing a Generic Environment: ";
2625+
var->getInterfaceType().print(Out);
2626+
Out << "\n";
2627+
abort();
2628+
}
2629+
26082630
// The fact that this is *directly* be a reference storage type
26092631
// cuts the code down quite a bit in getTypeOfReference.
26102632
if (var->getAttrs().hasAttribute<ReferenceOwnershipAttr>() !=

lib/AST/Decl.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7135,6 +7135,11 @@ VarDecl::VarDecl(DeclKind kind, bool isStatic, VarDecl::Introducer introducer,
71357135
}
71367136

71377137
Type VarDecl::getTypeInContext() const {
7138+
// If we are performing pack iteration, use the generic environment of the
7139+
// pack expansion expression to get the right context of a local variable.
7140+
if (auto *env = getOpenedElementEnvironment())
7141+
return GenericEnvironment::mapTypeIntoContext(env, getInterfaceType());
7142+
71387143
return getDeclContext()->mapTypeIntoContext(getInterfaceType());
71397144
}
71407145

lib/AST/Stmt.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,9 @@ void ForEachStmt::setPattern(Pattern *p) {
446446
}
447447

448448
Expr *ForEachStmt::getTypeCheckedSequence() const {
449+
if (auto *expansion = dyn_cast<PackExpansionExpr>(getParsedSequence()))
450+
return expansion;
451+
449452
return iteratorVar ? iteratorVar->getInit(/*index=*/0) : nullptr;
450453
}
451454

0 commit comments

Comments
 (0)