Skip to content

[5.7][TypeChecker] Rework type-checking of for-in statements #59261

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions include/swift/AST/Stmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -743,8 +743,8 @@ class ForEachStmt : public LabeledStmt {

// Set by Sema:
ProtocolConformanceRef sequenceConformance = ProtocolConformanceRef();
VarDecl *iteratorVar = nullptr;
Expr *iteratorVarRef = nullptr;
PatternBindingDecl *iteratorVar = nullptr;
Expr *nextCall = nullptr;
OpaqueValueExpr *elementExpr = nullptr;
Expr *convertElementExpr = nullptr;

Expand All @@ -759,11 +759,11 @@ class ForEachStmt : public LabeledStmt {
setPattern(Pat);
}

void setIteratorVar(VarDecl *var) { iteratorVar = var; }
VarDecl *getIteratorVar() const { return iteratorVar; }
void setIteratorVar(PatternBindingDecl *var) { iteratorVar = var; }
PatternBindingDecl *getIteratorVar() const { return iteratorVar; }

void setIteratorVarRef(Expr *var) { iteratorVarRef = var; }
Expr *getIteratorVarRef() const { return iteratorVarRef; }
void setNextCall(Expr *next) { nextCall = next; }
Expr *getNextCall() const { return nextCall; }

void setElementExpr(OpaqueValueExpr *expr) { elementExpr = expr; }
OpaqueValueExpr *getElementExpr() const { return elementExpr; }
Expand Down Expand Up @@ -802,8 +802,12 @@ class ForEachStmt : public LabeledStmt {
/// by this foreach loop, as it was written in the source code and
/// subsequently type-checked. To determine the semantic behavior of this
/// expression to extract a range, use \c getRangeInit().
Expr *getSequence() const { return Sequence; }
void setSequence(Expr *S) { Sequence = S; }
Expr *getParsedSequence() const { return Sequence; }
void setParsedSequence(Expr *S) { Sequence = S; }

/// Type-checked version of the sequence or nullptr if this statement
/// yet to be type-checked.
Expr *getTypeCheckedSequence() const;

/// getBody - Retrieve the body of the loop.
BraceStmt *getBody() const { return Body; }
Expand Down
45 changes: 8 additions & 37 deletions include/swift/Sema/Constraint.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,6 @@ enum class ConstraintKind : char {
/// name, and the type of that member, when referenced as a value, is the
/// second type.
UnresolvedValueMember,
/// The first type conforms to the protocol in which the member requirement
/// resides. Once the conformance is resolved, the value witness will be
/// determined, and the type of that witness, when referenced as a value,
/// will be bound to the second type.
ValueWitness,
/// The first type can be defaulted to the second (which currently
/// cannot be dependent). This is more like a type property than a
/// relational constraint.
Expand Down Expand Up @@ -411,18 +406,11 @@ class Constraint final : public llvm::ilist_node<Constraint>,
/// The type of the member.
Type Second;

union {
/// If non-null, the name of a member of the first type is that
/// being related to the second type.
///
/// Used for ValueMember an UnresolvedValueMember constraints.
DeclNameRef Name;

/// If non-null, the member being referenced.
///
/// Used for ValueWitness constraints.
ValueDecl *Ref;
} Member;
/// If non-null, the name of a member of the first type is that
/// being related to the second type.
///
/// Used for ValueMember an UnresolvedValueMember constraints.
DeclNameRef Name;

/// The DC in which the use appears.
DeclContext *UseDC;
Expand Down Expand Up @@ -537,12 +525,6 @@ class Constraint final : public llvm::ilist_node<Constraint>,
FunctionRefKind functionRefKind,
ConstraintLocator *locator);

/// Create a new value witness constraint.
static Constraint *createValueWitness(
ConstraintSystem &cs, ConstraintKind kind, Type first, Type second,
ValueDecl *requirement, DeclContext *useDC,
FunctionRefKind functionRefKind, ConstraintLocator *locator);

/// Create an overload-binding constraint.
static Constraint *createBindOverload(ConstraintSystem &cs, Type type,
OverloadChoice choice,
Expand Down Expand Up @@ -690,7 +672,6 @@ class Constraint final : public llvm::ilist_node<Constraint>,

case ConstraintKind::ValueMember:
case ConstraintKind::UnresolvedValueMember:
case ConstraintKind::ValueWitness:
case ConstraintKind::PropertyWrapper:
return ConstraintClassification::Member;

Expand Down Expand Up @@ -730,7 +711,6 @@ class Constraint final : public llvm::ilist_node<Constraint>,

case ConstraintKind::ValueMember:
case ConstraintKind::UnresolvedValueMember:
case ConstraintKind::ValueWitness:
return Member.First;

case ConstraintKind::SyntacticElement:
Expand All @@ -752,7 +732,6 @@ class Constraint final : public llvm::ilist_node<Constraint>,

case ConstraintKind::ValueMember:
case ConstraintKind::UnresolvedValueMember:
case ConstraintKind::ValueWitness:
return Member.Second;

default:
Expand All @@ -778,20 +757,13 @@ class Constraint final : public llvm::ilist_node<Constraint>,
DeclNameRef getMember() const {
assert(Kind == ConstraintKind::ValueMember ||
Kind == ConstraintKind::UnresolvedValueMember);
return Member.Member.Name;
}

/// Retrieve the requirement being referenced by a value witness constraint.
ValueDecl *getRequirement() const {
assert(Kind == ConstraintKind::ValueWitness);
return Member.Member.Ref;
return Member.Name;
}

/// Determine the kind of function reference we have for a member reference.
FunctionRefKind getFunctionRefKind() const {
if (Kind == ConstraintKind::ValueMember ||
Kind == ConstraintKind::UnresolvedValueMember ||
Kind == ConstraintKind::ValueWitness)
Kind == ConstraintKind::UnresolvedValueMember)
return static_cast<FunctionRefKind>(TheFunctionRefKind);

// Conservative answer: drop all of the labels.
Expand Down Expand Up @@ -851,8 +823,7 @@ class Constraint final : public llvm::ilist_node<Constraint>,
/// Retrieve the DC in which the member was used.
DeclContext *getMemberUseDC() const {
assert(Kind == ConstraintKind::ValueMember ||
Kind == ConstraintKind::UnresolvedValueMember ||
Kind == ConstraintKind::ValueWitness);
Kind == ConstraintKind::UnresolvedValueMember);
return Member.UseDC;
}

Expand Down
Loading