Skip to content

Commit 42d77df

Browse files
committed
[SIL] Fix computation of substituted error type against an abstraction pattern
We were attempting to perform substitution against the original pattern even when it didn't have a substitution map, and then trying to cover for the resulting errors by adjusting to `any Error`... which isn't always correct. Do the substitution only when it makes sense. Fixes rdar://119217570 & rdar://119219214.
1 parent 00d7e41 commit 42d77df

File tree

3 files changed

+36
-16
lines changed

3 files changed

+36
-16
lines changed

lib/SIL/IR/AbstractionPattern.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,33 +1264,32 @@ AbstractionPattern::getFunctionThrownErrorType(
12641264
return llvm::None;
12651265

12661266
auto &ctx = substFnInterfaceType->getASTContext();
1267-
auto optErrorType = substFnInterfaceType->getEffectiveThrownErrorType();
1267+
auto substErrorType = substFnInterfaceType->getEffectiveThrownErrorType();
12681268

12691269
if (isTypeParameterOrOpaqueArchetype()) {
1270-
if (!optErrorType)
1270+
if (!substErrorType)
12711271
return llvm::None;
12721272

1273-
if (!(*optErrorType)->isEqual(ctx.getErrorExistentialType())) {
1273+
if (!(*substErrorType)->isEqual(ctx.getErrorExistentialType())) {
12741274
llvm::errs() << "unsupported reabstraction\n";
12751275
abort();
12761276
}
12771277

1278-
return std::make_pair(AbstractionPattern(*optErrorType),
1279-
(*optErrorType)->getCanonicalType());
1278+
return std::make_pair(AbstractionPattern(*substErrorType),
1279+
(*substErrorType)->getCanonicalType());
12801280
}
12811281

1282-
if (!optErrorType) {
1283-
Type origErrorSubstType =
1284-
optOrigErrorType->getType()
1285-
.subst(optOrigErrorType->getGenericSubstitutions());
1286-
if (origErrorSubstType->isNever())
1287-
optErrorType = ctx.getNeverType();
1288-
else
1289-
optErrorType = ctx.getErrorExistentialType();
1282+
if (!substErrorType) {
1283+
Type origErrorSubstType;
1284+
if (auto errorSubs = optOrigErrorType->getGenericSubstitutions()) {
1285+
substErrorType = optOrigErrorType->getType().subst(errorSubs);
1286+
} else {
1287+
substErrorType = optOrigErrorType->getType();
1288+
}
12901289
}
12911290

12921291
return std::make_pair(*optOrigErrorType,
1293-
(*optErrorType)->getCanonicalType());
1292+
(*substErrorType)->getCanonicalType());
12941293
}
12951294

12961295
AbstractionPattern

test/SILGen/typed_throws.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,27 @@ func forceTryErased() {
177177
try! mightThrowAny(arg: throwsMyBigErrorOrReturnsInt())
178178
}
179179

180+
func takesClosureThrowingConcrete(_ body: () throws(MyError) -> ()) throws(MyError) {
181+
}
182+
183+
// CHECK-LABEL: sil private [ossa] @$s12typed_throws30passesClosureWithReabstraction5countySi_tFyyXEfU_ : $@convention(thin) () -> @error MyError
184+
// CHECK: bb0:
185+
// CHECK-NEXT: debug_value undef : $MyError, var, name "$error", argno 1
186+
func passesClosureWithReabstraction(count: Int) {
187+
try! takesClosureThrowingConcrete { }
188+
}
189+
190+
func takesClosureThrowingConcreteAndRethrows(_ body: () throws(MyError) -> ()) rethrows {
191+
}
192+
193+
// CHECK-LABEL: sil private [ossa] @$s12typed_throws42passesClosureWithReabstractionToRethrowing5countySi_tFyyXEfU_ : $@convention(thin) () -> @error MyError {
194+
// CHECK: bb0:
195+
// CHECK-NEXT: debug_value undef : $MyError, var, name "$error", argno 1
196+
func passesClosureWithReabstractionToRethrowing(count: Int) {
197+
try! takesClosureThrowingConcrete { }
198+
}
199+
200+
180201
// CHECK-LABEL: sil_vtable MySubclass {
181202
// CHECK-NEXT: #MyClass.init!allocator: <E where E : Error> (MyClass.Type) -> (() throws(E) -> ()) throws(E) -> MyClass : @$s12typed_throws10MySubclassC4bodyACyyxYKXE_txYKcs5ErrorRzlufC [override]
182203
// CHECK-NEXT: #MyClass.f: (MyClass) -> () throws -> () : @$s12typed_throws10MySubclassC1fyyAA0C5ErrorOYKFAA0C5ClassCADyyKFTV [override]

test/SILGen/typed_throws_generic.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,8 @@ struct UntypedRes<Success>: P {
310310
}
311311

312312
struct InfallibleRes<Success>: P {
313-
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s20typed_throws_generic13InfallibleResVyxGAA1PA2aEP1fyy1EQzYKFTW : $@convention(witness_method: P) <τ_0_0> (@in_guaranteed InfallibleRes<τ_0_0>) -> @error_indirect any Error
314-
// CHECK: bb0(%0 : $*any Error, %1 : $*InfallibleRes<τ_0_0>):
313+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s20typed_throws_generic13InfallibleResVyxGAA1PA2aEP1fyy1EQzYKFTW : $@convention(witness_method: P) <τ_0_0> (@in_guaranteed InfallibleRes<τ_0_0>) -> @error_indirect τ_0_0.E
314+
// CHECK: bb0(%0 : $*@error_type τ_0_0.E, %1 : $*InfallibleRes<τ_0_0>):
315315
// CHECK: [[SELF:%.*]] = load [trivial] %1 : $*InfallibleRes<τ_0_0>
316316
// CHECK: [[WITNESS:%.*]] = function_ref @$s20typed_throws_generic13InfallibleResV1fyyF : $@convention(method) <τ_0_0> (InfallibleRes<τ_0_0>) -> ()
317317
// CHECK: = apply [[WITNESS]]<τ_0_0>([[SELF]]) : $@convention(method) <τ_0_0> (InfallibleRes<τ_0_0>)

0 commit comments

Comments
 (0)