@@ -1565,6 +1565,9 @@ class ResultPlanner {
15651565 // /
15661566 // / Valid: reabstraction info, InnerResult, OuterResult.
15671567 ReabstractDirectToDirect,
1568+
1569+ // / Ignore the next direct inner result, since the outer is 'Void'.
1570+ IgnoreDirectResult,
15681571 };
15691572
15701573 Operation (Kind kind) : TheKind(kind) {}
@@ -1709,6 +1712,24 @@ class ResultPlanner {
17091712 SILResultInfo outerResult,
17101713 SILValue optOuterResultAddr);
17111714
1715+ void planIgnoredResult (AbstractionPattern innerOrigType,
1716+ CanType innerSubstType, PlanData &planData) {
1717+ if (innerOrigType.isTuple ()) {
1718+ auto innerSubstTuple = cast<TupleType>(innerSubstType);
1719+ for (unsigned i = 0 , n = innerSubstTuple->getNumElements (); i != n; ++i)
1720+ planIgnoredResult (innerOrigType.getTupleElementType (i),
1721+ innerSubstTuple.getElementType (i), planData);
1722+ return ;
1723+ }
1724+
1725+ auto innerResult = claimNextInnerResult (planData);
1726+ if (innerResult.isFormalIndirect () &&
1727+ SGF.silConv .isSILIndirect (innerResult))
1728+ (void )addInnerIndirectResultTemporary (planData, innerResult);
1729+ else
1730+ addIgnoreDirectResult ();
1731+ }
1732+
17121733 // / Claim the next inner result from the plan data.
17131734 SILResultInfo claimNextInnerResult (PlanData &data) {
17141735 return claimNext (data.InnerResults );
@@ -1858,6 +1879,10 @@ class ResultPlanner {
18581879 op.OuterOrigType = outerOrigType;
18591880 op.OuterSubstType = outerSubstType;
18601881 }
1882+
1883+ void addIgnoreDirectResult () {
1884+ (void )addOperation (Operation::IgnoreDirectResult);
1885+ }
18611886};
18621887
18631888} // end anonymous namespace
@@ -1868,6 +1893,13 @@ void ResultPlanner::plan(AbstractionPattern innerOrigType,
18681893 AbstractionPattern outerOrigType,
18691894 CanType outerSubstType,
18701895 PlanData &planData) {
1896+ // Conversion from `() -> T` to `() -> Void` is allowed when
1897+ // the argument is a closure.
1898+ if (!innerSubstType->isVoid () && outerSubstType->isVoid ()) {
1899+ planIgnoredResult (innerOrigType, innerSubstType, planData);
1900+ return ;
1901+ }
1902+
18711903 // The substituted types must match up in tuple-ness and arity.
18721904 assert (isa<TupleType>(innerSubstType) == isa<TupleType>(outerSubstType) ||
18731905 (isa<TupleType>(innerSubstType) &&
@@ -2580,6 +2612,10 @@ void ResultPlanner::execute(ArrayRef<SILValue> innerDirectResults,
25802612 case Operation::InjectOptionalIndirect:
25812613 SGF.B .createInjectEnumAddr (Loc, op.OuterResultAddr , op.SomeDecl );
25822614 continue ;
2615+
2616+ case Operation::IgnoreDirectResult:
2617+ (void )claimNext (innerDirectResults);
2618+ continue ;
25832619 }
25842620 llvm_unreachable (" bad operation kind" );
25852621 }
0 commit comments