diff --git a/lib/SILGen/SILGenLValue.cpp b/lib/SILGen/SILGenLValue.cpp index 217a8c1848c..777a20bb32d 100644 --- a/lib/SILGen/SILGenLValue.cpp +++ b/lib/SILGen/SILGenLValue.cpp @@ -4564,10 +4564,19 @@ LValue SILGenLValue::visitABISafeConversionExpr(ABISafeConversionExpr *e, LValueOptions options) { LValue lval = visitRec(e->getSubExpr(), accessKind, options); auto typeData = getValueTypeData(SGF, accessKind, e); + auto subExprType = e->getSubExpr()->getType()->getRValueType(); + auto loweredSubExprType = SGF.getLoweredType(subExprType); + + // Ensure the lvalue is re-abstracted to the substituted type, since that's + // the type with which we have ABI compatibility. + if (lval.getTypeOfRValue().getASTType() != loweredSubExprType.getASTType()) { + // Logical components always re-abstract back to the substituted + // type. + assert(lval.isLastComponentPhysical()); + lval.addOrigToSubstComponent(loweredSubExprType); + } - auto OrigType = e->getSubExpr()->getType(); - - lval.add(typeData, OrigType); + lval.add(typeData, subExprType); return lval; } diff --git a/test/SILGen/preconcurrency-abi-safe-conversions.swift b/test/SILGen/preconcurrency-abi-safe-conversions.swift new file mode 100644 index 00000000000..a66fde78da8 --- /dev/null +++ b/test/SILGen/preconcurrency-abi-safe-conversions.swift @@ -0,0 +1,25 @@ +// RUN: %target-swift-emit-silgen -swift-version 5 -verify %s +// RUN: %target-swift-emit-silgen -swift-version 6 -verify %s + +struct Text { + init(_: S) where S: StringProtocol {} +} + +// In Swift 5, we introduce an implicit @Sendable on the closures here. +// Make sure that doing so doesn't disrupt SILGen's lvalue emission. +// rdar://130016855 +public struct Header { + @preconcurrency + private let titleContent: @MainActor () -> TitleContent + + init(title: String) where TitleContent == Text { + self.titleContent = { + Text(title) + } + } + + func testGet() -> @MainActor () -> Text + where TitleContent == Text { + return titleContent // expected-warning * {{}} + } +}