SILGen: Reabstract subexpr lvalue before ABISafeConversion.

Fixes rdar://130016855. When preconcurrency compatibility introduces
implicit `@Sendable` conversions, the `ABISafeConversionExpr` representing
that conversion indicates an ABI-neutral conversion from the substituted
type of the original expression, so we need to reabstract in cases
where the original property is more generic than the type we're working
with.
This commit is contained in:
Joe Groff
2024-07-11 18:49:35 -07:00
parent 42c43e6262
commit b781005c0a
2 changed files with 37 additions and 3 deletions

View File

@@ -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<UncheckedConversionComponent>(typeData, OrigType);
lval.add<UncheckedConversionComponent>(typeData, subExprType);
return lval;
}

View File

@@ -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>(_: 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<TitleContent> {
@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 * {{}}
}
}