@@ -1488,8 +1488,34 @@ bool ConstraintSystem::generateConstraints(SingleValueStmtExpr *E) {
14881488 auto &ctx = getASTContext ();
14891489
14901490 auto *loc = getConstraintLocator (E);
1491- Type resultTy = createTypeVariable (loc, /* options*/ 0 );
1492- setType (E, resultTy);
1491+ Type resultType = createTypeVariable (loc, /* options*/ 0 );
1492+ setType (E, resultType);
1493+
1494+ if (E->getStmtKind () == SingleValueStmtExpr::Kind::For) {
1495+ auto *rrcProtocol = ctx.getProtocol (KnownProtocolKind::RangeReplaceableCollection);
1496+ auto *sequenceProtocol = ctx.getProtocol (KnownProtocolKind::Sequence);
1497+
1498+ addConstraint (ConstraintKind::ConformsTo,
1499+ resultType,
1500+ rrcProtocol->getDeclaredInterfaceType (),
1501+ loc);
1502+ Type elementTypeVar = createTypeVariable (loc, /* options*/ 0 );
1503+ Type elementType = DependentMemberType::get (resultType, sequenceProtocol->getAssociatedType (ctx.Id_Element ));
1504+
1505+ addConstraint (ConstraintKind::Bind, elementTypeVar, elementType, loc);
1506+ addConstraint (ConstraintKind::Bind, resultType, ArraySliceType::get (elementTypeVar), loc);
1507+
1508+ auto *binding = E->getForExpressionPreamble ()->ForAccumulatorBinding ;
1509+
1510+ auto *initializer = binding->getInit (0 );
1511+ auto target = SyntacticElementTarget::forInitialization (initializer, Type (), binding, 0 , false );
1512+
1513+ if (generateConstraints (target)) {
1514+ return true ;
1515+ }
1516+
1517+ addConstraint (ConstraintKind::Conversion, getType (initializer), resultType, loc);
1518+ }
14931519
14941520 // Propagate the implied result kind from the if/switch expression itself
14951521 // into the branches.
@@ -1513,21 +1539,24 @@ bool ConstraintSystem::generateConstraints(SingleValueStmtExpr *E) {
15131539 auto *loc = getConstraintLocator (
15141540 E, {LocatorPathElt::SingleValueStmtResult (idx), ctpElt});
15151541
1516- ContextualTypeInfo info (resultTy , CTP_SingleValueStmtBranch, loc);
1542+ ContextualTypeInfo info (resultType , CTP_SingleValueStmtBranch, loc);
15171543 setContextualInfo (result, info);
15181544 }
15191545
15201546 TypeJoinExpr *join = nullptr ;
1521- if (branches.empty ()) {
1522- // If we only have statement branches, the expression is typed as Void. This
1523- // should only be the case for 'if' and 'switch' statements that must be
1524- // expressions that have branches that all end in a throw, and we'll warn
1525- // that we've inferred Void.
1526- addConstraint (ConstraintKind::Bind, resultTy, ctx.getVoidType (), loc);
1527- } else {
1528- // Otherwise, we join the result types for each of the branches.
1529- join = TypeJoinExpr::forBranchesOfSingleValueStmtExpr (
1530- ctx, resultTy, E, AllocationArena::ConstraintSolver);
1547+
1548+ if (E->getStmtKind () != SingleValueStmtExpr::Kind::For) {
1549+ if (branches.empty ()) {
1550+ // If we only have statement branches, the expression is typed as Void. This
1551+ // should only be the case for 'if' and 'switch' statements that must be
1552+ // expressions that have branches that all end in a throw, and we'll warn
1553+ // that we've inferred Void.
1554+ addConstraint (ConstraintKind::Bind, resultType, ctx.getVoidType (), loc);
1555+ } else {
1556+ // Otherwise, we join the result types for each of the branches.
1557+ join = TypeJoinExpr::forBranchesOfSingleValueStmtExpr (
1558+ ctx, resultType, E, AllocationArena::ConstraintSolver);
1559+ }
15311560 }
15321561
15331562 // If this is an implied return in a closure, we need to account for the fact
@@ -1568,11 +1597,11 @@ bool ConstraintSystem::generateConstraints(SingleValueStmtExpr *E) {
15681597 if (auto *closureTy = getClosureTypeIfAvailable (CE)) {
15691598 auto closureResultTy = closureTy->getResult ();
15701599 auto *bindToClosure = Constraint::create (
1571- *this , ConstraintKind::Bind, resultTy , closureResultTy, loc);
1600+ *this , ConstraintKind::Bind, resultType , closureResultTy, loc);
15721601 bindToClosure->setFavored ();
15731602
15741603 auto *bindToVoid = Constraint::create (*this , ConstraintKind::Bind,
1575- resultTy , ctx.getVoidType (), loc);
1604+ resultType , ctx.getVoidType (), loc);
15761605
15771606 addDisjunctionConstraint ({bindToClosure, bindToVoid}, loc);
15781607 }
0 commit comments