Skip to content

Commit 273937a

Browse files
authored
Merge pull request #69824 from DougGregor/typed-throws-fixes
Yet more typed throws fixes
2 parents aa4b0d0 + 84a078b commit 273937a

File tree

5 files changed

+63
-23
lines changed

5 files changed

+63
-23
lines changed

lib/AST/Type.cpp

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5065,6 +5065,28 @@ case TypeKind::Id:
50655065
isUnchanged = false;
50665066
}
50675067

5068+
llvm::Optional<ASTExtInfo> extInfo;
5069+
if (function->hasExtInfo()) {
5070+
extInfo = function->getExtInfo()
5071+
.withGlobalActor(globalActorType)
5072+
.withThrows(function->isThrowing(), thrownError);
5073+
5074+
// If there was a generic thrown error and it substituted with
5075+
// 'any Error' or 'Never', map to 'throws' or non-throwing rather than
5076+
// maintaining the sugar.
5077+
if (auto origThrownError = function->getThrownError()) {
5078+
if (origThrownError->isTypeParameter() ||
5079+
origThrownError->isTypeVariableOrMember()) {
5080+
// 'any Error'
5081+
if (thrownError->isEqual(
5082+
thrownError->getASTContext().getErrorExistentialType()))
5083+
extInfo = extInfo->withThrows(true, Type());
5084+
else if (thrownError->isNever())
5085+
extInfo = extInfo->withThrows(false, Type());
5086+
}
5087+
}
5088+
}
5089+
50685090
if (auto genericFnType = dyn_cast<GenericFunctionType>(base)) {
50695091
#ifndef NDEBUG
50705092
// Check that generic parameters won't be transformed.
@@ -5080,24 +5102,13 @@ case TypeKind::Id:
50805102
if (isUnchanged) return *this;
50815103

50825104
auto genericSig = genericFnType->getGenericSignature();
5083-
if (!function->hasExtInfo())
5084-
return GenericFunctionType::get(genericSig, substParams, resultTy);
50855105
return GenericFunctionType::get(
5086-
genericSig, substParams, resultTy,
5087-
function->getExtInfo()
5088-
.withGlobalActor(globalActorType)
5089-
.withThrows(function->isThrowing(), thrownError));
5106+
genericSig, substParams, resultTy, extInfo);
50905107
}
50915108

50925109
if (isUnchanged) return *this;
50935110

5094-
if (!function->hasExtInfo())
5095-
return FunctionType::get(substParams, resultTy);
5096-
return FunctionType::get(
5097-
substParams, resultTy,
5098-
function->getExtInfo()
5099-
.withGlobalActor(globalActorType)
5100-
.withThrows(function->isThrowing(), thrownError));
5111+
return FunctionType::get(substParams, resultTy, extInfo);
51015112
}
51025113

51035114
case TypeKind::ArraySlice: {

lib/SILOptimizer/LoopTransforms/ForEachLoopUnroll.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -483,10 +483,11 @@ static void unrollForEach(ArrayInfo &arrayInfo, TryApplyInst *forEachCall,
483483
// targets must be taking a phi argument.
484484
SILBasicBlock *normalBB = forEachCall->getNormalBB();
485485
SILBasicBlock *errorBB = forEachCall->getErrorBB();
486-
assert(errorBB->getSILPhiArguments().size() == 1 &&
487-
normalBB->getSILPhiArguments().size() == 1);
486+
assert(normalBB->getSILPhiArguments().size() == 1);
488487
SILPhiArgument *normalArgument = normalBB->getSILPhiArguments()[0];
489-
SILPhiArgument *errorArgument = errorBB->getSILPhiArguments()[0];
488+
SILPhiArgument *errorArgument = nullptr;
489+
if (errorBB->getSILPhiArguments().size() == 1)
490+
errorArgument = errorBB->getSILPhiArguments()[0];
490491

491492
// A generator for creating a basic block for use as the target of the
492493
// "normal" branch of a try_apply.
@@ -503,8 +504,12 @@ static void unrollForEach(ArrayInfo &arrayInfo, TryApplyInst *forEachCall,
503504
auto errorTargetGenerator = [&](SILBasicBlock *insertionBlock,
504505
SILValue borrowedElem, SILValue storeBorrow) {
505506
SILBasicBlock *newErrorBB = fun->createBasicBlockBefore(insertionBlock);
506-
SILValue argument = newErrorBB->createPhiArgument(
507+
SILValue argument;
508+
if (errorArgument) {
509+
argument = newErrorBB->createPhiArgument(
507510
errorArgument->getType(), errorArgument->getOwnershipKind());
511+
}
512+
508513
// Make the errorBB jump to the error target of the original forEach.
509514
SILBuilderWithScope builder(newErrorBB, forEachCall);
510515
if (storeBorrow) {
@@ -513,7 +518,11 @@ static void unrollForEach(ArrayInfo &arrayInfo, TryApplyInst *forEachCall,
513518
if (borrowedElem) {
514519
builder.createEndBorrow(forEachLoc, borrowedElem);
515520
}
516-
builder.createBranch(forEachLoc, errorBB, argument);
521+
522+
if (argument)
523+
builder.createBranch(forEachLoc, errorBB, argument);
524+
else
525+
builder.createBranch(forEachLoc, errorBB);
517526
return newErrorBB;
518527
};
519528

lib/SILOptimizer/Mandatory/TransferNonSendable.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,8 @@ class PartitionOpTranslator {
640640

641641
if (auto tryApplyInst = dyn_cast<TryApplyInst>(inst)) {
642642
foundResults.emplace_back(tryApplyInst->getNormalBB()->getArgument(0));
643-
foundResults.emplace_back(tryApplyInst->getErrorBB()->getArgument(0));
643+
if (tryApplyInst->getErrorBB()->getNumArguments() > 0)
644+
foundResults.emplace_back(tryApplyInst->getErrorBB()->getArgument(0));
644645
return;
645646
}
646647

lib/SILOptimizer/Transforms/SpeculativeDevirtualizer.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,11 +239,19 @@ static FullApplySite speculateMonomorphicTarget(FullApplySite AI,
239239
// Split critical edges resulting from VirtAI.
240240
if (auto *TAI = dyn_cast<TryApplyInst>(VirtAI)) {
241241
auto *ErrorBB = TAI->getFunction()->createBasicBlock();
242-
ErrorBB->createPhiArgument(TAI->getErrorBB()->getArgument(0)->getType(),
243-
OwnershipKind::Owned);
242+
SILArgument *ErrorArg = nullptr;
243+
if (TAI->getErrorBB()->getNumArguments() == 1) {
244+
ErrorArg = TAI->getErrorBB()->getArgument(0);
245+
ErrorBB->createPhiArgument(ErrorArg->getType(), OwnershipKind::Owned);
246+
}
244247
Builder.setInsertionPoint(ErrorBB);
245-
Builder.createBranch(TAI->getLoc(), TAI->getErrorBB(),
246-
{ErrorBB->getArgument(0)});
248+
249+
if (ErrorArg) {
250+
Builder.createBranch(TAI->getLoc(), TAI->getErrorBB(),
251+
{ErrorBB->getArgument(0)});
252+
} else {
253+
Builder.createBranch(TAI->getLoc(), TAI->getErrorBB());
254+
}
247255

248256
auto *NormalBB = TAI->getFunction()->createBasicBlock();
249257
NormalBB->createPhiArgument(TAI->getNormalBB()->getArgument(0)->getType(),

test/decl/func/typed_throws.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,14 @@ func fromRethrows(body: () throws -> Void) rethrows {
179179
try notRethrowsLike2(body) // expected-error{{call can throw, but the error is not handled; a function declared 'rethrows' may only throw if its parameter does}}
180180
try notRethrowsLike3(body) // expected-error{{call can throw, but the error is not handled; a function declared 'rethrows' may only throw if its parameter does}}
181181
}
182+
183+
// Substitution involving 'any Error' or 'Never' thrown error types should
184+
// use untyped throws or be non-throwing.
185+
enum G_E<T> {
186+
case tuple((x: T, y: T))
187+
}
188+
189+
func testArrMap(arr: [String]) {
190+
_ = mapArray(arr, body: G_E<Int>.tuple)
191+
// expected-error@-1{{cannot convert value of type '((x: Int, y: Int)) -> G_E<Int>' to expected argument type '(String) -> G_E<Int>'}}
192+
}

0 commit comments

Comments
 (0)