@@ -2898,6 +2898,9 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
28982898 // / The for-each statement.
28992899 ForEachStmt *Stmt;
29002900
2901+ // / The declaration context in which this for-each statement resides.
2902+ DeclContext *DC;
2903+
29012904 // / The locator we're using.
29022905 ConstraintLocator *Locator;
29032906
@@ -2926,7 +2929,8 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
29262929 Type IteratorType;
29272930
29282931 public:
2929- explicit BindingListener (ForEachStmt *stmt) : Stmt(stmt) { }
2932+ explicit BindingListener (ForEachStmt *stmt, DeclContext *dc)
2933+ : Stmt(stmt), DC(dc) { }
29302934
29312935 bool builtConstraints (ConstraintSystem &cs, Expr *expr) override {
29322936 // Save the locator we're using for the expression.
@@ -2956,6 +2960,25 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
29562960 auto elementLocator = cs.getConstraintLocator (
29572961 ContextualLocator, ConstraintLocator::SequenceElementType);
29582962
2963+ // Check the element pattern.
2964+ ASTContext &ctx = cs.getASTContext ();
2965+ if (auto *P = TypeChecker::resolvePattern (Stmt->getPattern (), DC,
2966+ /* isStmtCondition*/ false )) {
2967+ Stmt->setPattern (P);
2968+ } else {
2969+ Stmt->getPattern ()->setType (ErrorType::get (ctx));
2970+ return true ;
2971+ }
2972+
2973+ TypeResolutionOptions options (TypeResolverContext::InExpression);
2974+ options |= TypeResolutionFlags::AllowUnspecifiedTypes;
2975+ options |= TypeResolutionFlags::AllowUnboundGenerics;
2976+ if (TypeChecker::typeCheckPattern (Stmt->getPattern (), DC, options)) {
2977+ // FIXME: Handle errors better.
2978+ Stmt->getPattern ()->setType (ErrorType::get (ctx));
2979+ return true ;
2980+ }
2981+
29592982 // Collect constraints from the element pattern.
29602983 auto pattern = Stmt->getPattern ();
29612984 InitType = cs.generateConstraints (pattern, elementLocator);
@@ -2984,13 +3007,12 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
29843007 }
29853008
29863009 // Reference the makeIterator witness.
2987- ASTContext &ctx = cs.getASTContext ();
29883010 FuncDecl *makeIterator = ctx.getSequenceMakeIterator ();
29893011 Type makeIteratorType =
29903012 cs.createTypeVariable (Locator, TVO_CanBindToNoEscape);
29913013 cs.addValueWitnessConstraint (
29923014 LValueType::get (SequenceType), makeIterator,
2993- makeIteratorType, cs. DC , FunctionRefKind::Compound,
3015+ makeIteratorType, DC, FunctionRefKind::Compound,
29943016 ContextualLocator);
29953017
29963018 Stmt->setSequence (expr);
@@ -3019,7 +3041,7 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
30193041 TypeResolutionOptions options (TypeResolverContext::ForEachStmt);
30203042 options |= TypeResolutionFlags::OverrideType;
30213043 if (TypeChecker::coercePatternToType (pattern,
3022- TypeResolution::forContextual (cs. DC ),
3044+ TypeResolution::forContextual (DC),
30233045 InitType, options)) {
30243046 return nullptr ;
30253047 }
@@ -3033,10 +3055,10 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
30333055 " Couldn't find sequence conformance" );
30343056 Stmt->setSequenceConformance (SequenceConformance);
30353057
3036- // Check the
3058+ // Check the filtering condition.
30373059 // FIXME: This should be pulled into the constraint system itself.
30383060 if (auto *Where = Stmt->getWhere ()) {
3039- if (!TypeChecker::typeCheckCondition (Where, cs. DC ))
3061+ if (!TypeChecker::typeCheckCondition (Where, DC))
30403062 Stmt->setWhere (Where);
30413063 }
30423064
@@ -3053,7 +3075,7 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
30533075 iterator = new (ctx) VarDecl (
30543076 /* IsStatic*/ false , VarDecl::Introducer::Var,
30553077 /* IsCaptureList*/ false , Stmt->getInLoc (),
3056- ctx.getIdentifier (name), cs. DC );
3078+ ctx.getIdentifier (name), DC);
30573079 iterator->setInterfaceType (IteratorType->mapTypeOutOfContext ());
30583080 iterator->setImplicit ();
30593081 Stmt->setIteratorVar (iterator);
@@ -3066,12 +3088,12 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
30663088 PatternBindingDecl::createImplicit (
30673089 ctx, StaticSpellingKind::None, genPat,
30683090 new (ctx) OpaqueValueExpr (Stmt->getInLoc (), nextResultType),
3069- cs. DC , /* VarLoc*/ Stmt->getForLoc ());
3091+ DC, /* VarLoc*/ Stmt->getForLoc ());
30703092 }
30713093
30723094 // Create the iterator variable.
30733095 auto *varRef = TypeChecker::buildCheckedRefExpr (
3074- iterator, cs. DC , DeclNameLoc (Stmt->getInLoc ()), /* implicit*/ true );
3096+ iterator, DC, DeclNameLoc (Stmt->getInLoc ()), /* implicit*/ true );
30753097 if (varRef)
30763098 Stmt->setIteratorVarRef (varRef);
30773099
@@ -3083,7 +3105,7 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
30833105 /* isPlaceholder=*/ true );
30843106 Expr *convertElementExpr = elementExpr;
30853107 if (TypeChecker::typeCheckExpression (
3086- convertElementExpr, cs. DC ,
3108+ convertElementExpr, DC,
30873109 TypeLoc::withoutLoc (optPatternType),
30883110 CTP_CoerceOperand).isNull ()) {
30893111 return nullptr ;
@@ -3097,7 +3119,7 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
30973119 }
30983120 };
30993121
3100- BindingListener listener (stmt);
3122+ BindingListener listener (stmt, dc );
31013123 Expr *seq = stmt->getSequence ();
31023124 assert (seq && " type-checking an uninitialized for-each statement?" );
31033125
0 commit comments