@@ -2892,8 +2892,7 @@ bool TypeChecker::typeCheckPatternBinding(PatternBindingDecl *PBD,
2892
2892
return hadError;
2893
2893
}
2894
2894
2895
- auto TypeChecker::typeCheckForEachBinding (
2896
- DeclContext *dc, ForEachStmt *stmt) -> Optional<ForEachBinding> {
2895
+ bool TypeChecker::typeCheckForEachBinding (DeclContext *dc, ForEachStmt *stmt) {
2897
2896
// / Type checking listener for for-each binding.
2898
2897
class BindingListener : public ExprTypeCheckListener {
2899
2898
// / The for-each statement.
@@ -3001,6 +3000,7 @@ auto TypeChecker::typeCheckForEachBinding(
3001
3000
Expr *appliedSolution (Solution &solution, Expr *expr) override {
3002
3001
// Figure out what types the constraints decided on.
3003
3002
auto &cs = solution.getConstraintSystem ();
3003
+ ASTContext &ctx = cs.getASTContext ();
3004
3004
InitType = solution.simplifyType (InitType);
3005
3005
SequenceType = solution.simplifyType (SequenceType);
3006
3006
ElementType = solution.simplifyType (ElementType);
@@ -3012,6 +3012,7 @@ auto TypeChecker::typeCheckForEachBinding(
3012
3012
3013
3013
cs.cacheExprTypes (expr);
3014
3014
Stmt->setSequence (expr);
3015
+ solution.setExprTypes (expr);
3015
3016
3016
3017
// Apply the solution to the iteration pattern as well.
3017
3018
Pattern *pattern = Stmt->getPattern ();
@@ -3032,12 +3033,67 @@ auto TypeChecker::typeCheckForEachBinding(
3032
3033
" Couldn't find sequence conformance" );
3033
3034
Stmt->setSequenceConformance (SequenceConformance);
3034
3035
3035
- solution.setExprTypes (expr);
3036
- return expr;
3037
- }
3036
+ // Check the
3037
+ // FIXME: This should be pulled into the constraint system itself.
3038
+ if (auto *Where = Stmt->getWhere ()) {
3039
+ if (!TypeChecker::typeCheckCondition (Where, cs.DC ))
3040
+ Stmt->setWhere (Where);
3041
+ }
3042
+
3043
+ // Invoke iterator() to get an iterator from the sequence.
3044
+ VarDecl *iterator;
3045
+ Type nextResultType = OptionalType::get (ElementType);
3046
+ {
3047
+ // Create a local variable to capture the iterator.
3048
+ std::string name;
3049
+ if (auto np = dyn_cast_or_null<NamedPattern>(Stmt->getPattern ()))
3050
+ name = " $" +np->getBoundName ().str ().str ();
3051
+ name += " $generator" ;
3052
+
3053
+ iterator = new (ctx) VarDecl (
3054
+ /* IsStatic*/ false , VarDecl::Introducer::Var,
3055
+ /* IsCaptureList*/ false , Stmt->getInLoc (),
3056
+ ctx.getIdentifier (name), cs.DC );
3057
+ iterator->setInterfaceType (IteratorType->mapTypeOutOfContext ());
3058
+ iterator->setImplicit ();
3059
+ Stmt->setIteratorVar (iterator);
3060
+
3061
+ auto genPat = new (ctx) NamedPattern (iterator);
3062
+ genPat->setImplicit ();
3063
+
3064
+ // TODO: test/DebugInfo/iteration.swift requires this extra info to
3065
+ // be around.
3066
+ PatternBindingDecl::createImplicit (
3067
+ ctx, StaticSpellingKind::None, genPat,
3068
+ new (ctx) OpaqueValueExpr (Stmt->getInLoc (), nextResultType),
3069
+ cs.DC , /* VarLoc*/ Stmt->getForLoc ());
3070
+ }
3038
3071
3039
- ForEachBinding getBinding () const {
3040
- return { SequenceType, SequenceConformance, IteratorType, ElementType };
3072
+ // Create the iterator variable.
3073
+ auto *varRef = TypeChecker::buildCheckedRefExpr (
3074
+ iterator, cs.DC , DeclNameLoc (Stmt->getInLoc ()), /* implicit*/ true );
3075
+ if (varRef)
3076
+ Stmt->setIteratorVarRef (varRef);
3077
+
3078
+ // Convert that Optional<Element> value to the type of the pattern.
3079
+ auto optPatternType = OptionalType::get (Stmt->getPattern ()->getType ());
3080
+ if (!optPatternType->isEqual (nextResultType)) {
3081
+ OpaqueValueExpr *elementExpr =
3082
+ new (ctx) OpaqueValueExpr (Stmt->getInLoc (), nextResultType,
3083
+ /* isPlaceholder=*/ true );
3084
+ Expr *convertElementExpr = elementExpr;
3085
+ if (TypeChecker::typeCheckExpression (
3086
+ convertElementExpr, cs.DC ,
3087
+ TypeLoc::withoutLoc (optPatternType),
3088
+ CTP_CoerceOperand).isNull ()) {
3089
+ return nullptr ;
3090
+ }
3091
+ elementExpr->setIsPlaceholder (false );
3092
+ Stmt->setElementExpr (elementExpr);
3093
+ Stmt->setConvertElementExpr (convertElementExpr);
3094
+ }
3095
+
3096
+ return expr;
3041
3097
}
3042
3098
};
3043
3099
@@ -3048,8 +3104,8 @@ auto TypeChecker::typeCheckForEachBinding(
3048
3104
// Type-check the for-each loop sequence and element pattern.
3049
3105
auto resultTy = TypeChecker::typeCheckExpression (seq, dc, &listener);
3050
3106
if (!resultTy)
3051
- return None ;
3052
- return listener. getBinding () ;
3107
+ return true ;
3108
+ return false ;
3053
3109
}
3054
3110
3055
3111
bool TypeChecker::typeCheckCondition (Expr *&expr, DeclContext *dc) {
0 commit comments