@@ -2898,6 +2898,9 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
2898
2898
// / The for-each statement.
2899
2899
ForEachStmt *Stmt;
2900
2900
2901
+ // / The declaration context in which this for-each statement resides.
2902
+ DeclContext *DC;
2903
+
2901
2904
// / The locator we're using.
2902
2905
ConstraintLocator *Locator;
2903
2906
@@ -2926,7 +2929,8 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
2926
2929
Type IteratorType;
2927
2930
2928
2931
public:
2929
- explicit BindingListener (ForEachStmt *stmt) : Stmt(stmt) { }
2932
+ explicit BindingListener (ForEachStmt *stmt, DeclContext *dc)
2933
+ : Stmt(stmt), DC(dc) { }
2930
2934
2931
2935
bool builtConstraints (ConstraintSystem &cs, Expr *expr) override {
2932
2936
// Save the locator we're using for the expression.
@@ -2956,6 +2960,25 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
2956
2960
auto elementLocator = cs.getConstraintLocator (
2957
2961
ContextualLocator, ConstraintLocator::SequenceElementType);
2958
2962
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
+
2959
2982
// Collect constraints from the element pattern.
2960
2983
auto pattern = Stmt->getPattern ();
2961
2984
InitType = cs.generateConstraints (pattern, elementLocator);
@@ -2984,13 +3007,12 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
2984
3007
}
2985
3008
2986
3009
// Reference the makeIterator witness.
2987
- ASTContext &ctx = cs.getASTContext ();
2988
3010
FuncDecl *makeIterator = ctx.getSequenceMakeIterator ();
2989
3011
Type makeIteratorType =
2990
3012
cs.createTypeVariable (Locator, TVO_CanBindToNoEscape);
2991
3013
cs.addValueWitnessConstraint (
2992
3014
LValueType::get (SequenceType), makeIterator,
2993
- makeIteratorType, cs. DC , FunctionRefKind::Compound,
3015
+ makeIteratorType, DC, FunctionRefKind::Compound,
2994
3016
ContextualLocator);
2995
3017
2996
3018
Stmt->setSequence (expr);
@@ -3019,7 +3041,7 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
3019
3041
TypeResolutionOptions options (TypeResolverContext::ForEachStmt);
3020
3042
options |= TypeResolutionFlags::OverrideType;
3021
3043
if (TypeChecker::coercePatternToType (pattern,
3022
- TypeResolution::forContextual (cs. DC ),
3044
+ TypeResolution::forContextual (DC),
3023
3045
InitType, options)) {
3024
3046
return nullptr ;
3025
3047
}
@@ -3033,10 +3055,10 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
3033
3055
" Couldn't find sequence conformance" );
3034
3056
Stmt->setSequenceConformance (SequenceConformance);
3035
3057
3036
- // Check the
3058
+ // Check the filtering condition.
3037
3059
// FIXME: This should be pulled into the constraint system itself.
3038
3060
if (auto *Where = Stmt->getWhere ()) {
3039
- if (!TypeChecker::typeCheckCondition (Where, cs. DC ))
3061
+ if (!TypeChecker::typeCheckCondition (Where, DC))
3040
3062
Stmt->setWhere (Where);
3041
3063
}
3042
3064
@@ -3053,7 +3075,7 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
3053
3075
iterator = new (ctx) VarDecl (
3054
3076
/* IsStatic*/ false , VarDecl::Introducer::Var,
3055
3077
/* IsCaptureList*/ false , Stmt->getInLoc (),
3056
- ctx.getIdentifier (name), cs. DC );
3078
+ ctx.getIdentifier (name), DC);
3057
3079
iterator->setInterfaceType (IteratorType->mapTypeOutOfContext ());
3058
3080
iterator->setImplicit ();
3059
3081
Stmt->setIteratorVar (iterator);
@@ -3066,12 +3088,12 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
3066
3088
PatternBindingDecl::createImplicit (
3067
3089
ctx, StaticSpellingKind::None, genPat,
3068
3090
new (ctx) OpaqueValueExpr (Stmt->getInLoc (), nextResultType),
3069
- cs. DC , /* VarLoc*/ Stmt->getForLoc ());
3091
+ DC, /* VarLoc*/ Stmt->getForLoc ());
3070
3092
}
3071
3093
3072
3094
// Create the iterator variable.
3073
3095
auto *varRef = TypeChecker::buildCheckedRefExpr (
3074
- iterator, cs. DC , DeclNameLoc (Stmt->getInLoc ()), /* implicit*/ true );
3096
+ iterator, DC, DeclNameLoc (Stmt->getInLoc ()), /* implicit*/ true );
3075
3097
if (varRef)
3076
3098
Stmt->setIteratorVarRef (varRef);
3077
3099
@@ -3083,7 +3105,7 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
3083
3105
/* isPlaceholder=*/ true );
3084
3106
Expr *convertElementExpr = elementExpr;
3085
3107
if (TypeChecker::typeCheckExpression (
3086
- convertElementExpr, cs. DC ,
3108
+ convertElementExpr, DC,
3087
3109
TypeLoc::withoutLoc (optPatternType),
3088
3110
CTP_CoerceOperand).isNull ()) {
3089
3111
return nullptr ;
@@ -3097,7 +3119,7 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
3097
3119
}
3098
3120
};
3099
3121
3100
- BindingListener listener (stmt);
3122
+ BindingListener listener (stmt, dc );
3101
3123
Expr *seq = stmt->getSequence ();
3102
3124
assert (seq && " type-checking an uninitialized for-each statement?" );
3103
3125
0 commit comments