From ad181b9eb192371d7c87183f6a3b082b204b2b79 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 25 Mar 2025 12:30:22 -0400 Subject: [PATCH] IRGen: Fix assertion failure with typed throws The mapTypeIntoContext() call in visitFullApplySite() was not necessary. The type in question is already fully substituted and should no longer contain type parameters. However, it can contain archetypes, which is what caused mapTypeIntoContext() to assert. Indeed, this case where the return type is generic but still loadable wasn't covered by our test suite. - Fixes https://github.com/swiftlang/swift/issues/80020. - Fixes rdar://147051717. --- lib/IRGen/IRGenSIL.cpp | 5 +++-- test/IRGen/typed_throws_generic.swift | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 test/IRGen/typed_throws_generic.swift diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index 8745f1961dddf..2a1e37df82ada 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -4040,8 +4040,9 @@ void IRGenSILFunction::visitFullApplySite(FullApplySite site) { Builder.emitBlock(typedErrorLoadBB); auto &errorTI = cast(IGM.getTypeInfo(errorType)); - auto silResultTy = CurSILFn->mapTypeIntoContext( - substConv.getSILResultType(IGM.getMaximalTypeExpansionContext())); + auto silResultTy = + substConv.getSILResultType(IGM.getMaximalTypeExpansionContext()); + ASSERT(!silResultTy.hasTypeParameter()); auto &resultTI = cast(IGM.getTypeInfo(silResultTy)); auto &resultSchema = resultTI.nativeReturnValueSchema(IGM); diff --git a/test/IRGen/typed_throws_generic.swift b/test/IRGen/typed_throws_generic.swift new file mode 100644 index 0000000000000..95794512cedc9 --- /dev/null +++ b/test/IRGen/typed_throws_generic.swift @@ -0,0 +1,20 @@ +// RUN: %target-swift-frontend -primary-file %s -emit-irgen + +// https://github.com/swiftlang/swift/issues/80020 +// +// We used to assert if you had a loadable return type that contained +// a generic parameter. + +public enum MyError: Error { + case error +} + +public struct G {} // Note: G is loadable + +public func f(t: T) throws(MyError) -> G { + return G() +} + +public func g(u: U?) throws(MyError) -> G { + return try f(t: u) +} \ No newline at end of file