@@ -1565,6 +1565,9 @@ class ResultPlanner {
1565
1565
// /
1566
1566
// / Valid: reabstraction info, InnerResult, OuterResult.
1567
1567
ReabstractDirectToDirect,
1568
+
1569
+ // / Ignore the next direct inner result, since the outer is 'Void'.
1570
+ IgnoreDirectResult,
1568
1571
};
1569
1572
1570
1573
Operation (Kind kind) : TheKind(kind) {}
@@ -1709,6 +1712,24 @@ class ResultPlanner {
1709
1712
SILResultInfo outerResult,
1710
1713
SILValue optOuterResultAddr);
1711
1714
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
+
1712
1733
// / Claim the next inner result from the plan data.
1713
1734
SILResultInfo claimNextInnerResult (PlanData &data) {
1714
1735
return claimNext (data.InnerResults );
@@ -1858,6 +1879,10 @@ class ResultPlanner {
1858
1879
op.OuterOrigType = outerOrigType;
1859
1880
op.OuterSubstType = outerSubstType;
1860
1881
}
1882
+
1883
+ void addIgnoreDirectResult () {
1884
+ (void )addOperation (Operation::IgnoreDirectResult);
1885
+ }
1861
1886
};
1862
1887
1863
1888
} // end anonymous namespace
@@ -1868,6 +1893,13 @@ void ResultPlanner::plan(AbstractionPattern innerOrigType,
1868
1893
AbstractionPattern outerOrigType,
1869
1894
CanType outerSubstType,
1870
1895
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
+
1871
1903
// The substituted types must match up in tuple-ness and arity.
1872
1904
assert (isa<TupleType>(innerSubstType) == isa<TupleType>(outerSubstType) ||
1873
1905
(isa<TupleType>(innerSubstType) &&
@@ -2580,6 +2612,10 @@ void ResultPlanner::execute(ArrayRef<SILValue> innerDirectResults,
2580
2612
case Operation::InjectOptionalIndirect:
2581
2613
SGF.B .createInjectEnumAddr (Loc, op.OuterResultAddr , op.SomeDecl );
2582
2614
continue ;
2615
+
2616
+ case Operation::IgnoreDirectResult:
2617
+ (void )claimNext (innerDirectResults);
2618
+ continue ;
2583
2619
}
2584
2620
llvm_unreachable (" bad operation kind" );
2585
2621
}
0 commit comments