Skip to content

Commit eff91b0

Browse files
authored
Merge pull request #59291 from jckarter/type-expansion-wmo-private-type-5.7
[5.7] SILGen: Carry WMO of type lowering context to closure captures.
2 parents 02a14d6 + 120b4c9 commit eff91b0

File tree

9 files changed

+93
-9
lines changed

9 files changed

+93
-9
lines changed

include/swift/SIL/TypeLowering.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,8 @@ class TypeConverter {
752752

753753
llvm::DenseMap<AbstractClosureExpr *, Optional<AbstractionPattern>>
754754
ClosureAbstractionPatterns;
755+
llvm::DenseMap<SILDeclRef, TypeExpansionContext>
756+
CaptureTypeExpansionContexts;
755757

756758
CanAnyFunctionType makeConstantInterfaceType(SILDeclRef constant);
757759

@@ -1156,6 +1158,7 @@ class TypeConverter {
11561158
/// the abstraction pattern is queried using this function. Once the
11571159
/// abstraction pattern has been asked for, it may not be changed.
11581160
Optional<AbstractionPattern> getConstantAbstractionPattern(SILDeclRef constant);
1161+
TypeExpansionContext getCaptureTypeExpansionContext(SILDeclRef constant);
11591162

11601163
/// Set the preferred abstraction pattern for a closure.
11611164
///
@@ -1165,6 +1168,8 @@ class TypeConverter {
11651168
void setAbstractionPattern(AbstractClosureExpr *closure,
11661169
AbstractionPattern pattern);
11671170

1171+
void setCaptureTypeExpansionContext(SILDeclRef constant,
1172+
SILModule &M);
11681173
private:
11691174
CanType computeLoweredRValueType(TypeExpansionContext context,
11701175
AbstractionPattern origType,

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2078,13 +2078,9 @@ static CanSILFunctionType getSILFunctionType(
20782078
// Lower in the context of the closure. Since the set of captures is a
20792079
// private contract between the closure and its enclosing context, we
20802080
// don't need to keep its capture types opaque.
2081-
auto expansion = TypeExpansionContext::maximal(
2082-
constant->getAnyFunctionRef()->getAsDeclContext(), false);
2083-
// ...unless it's inlinable, in which case it might get inlined into
2084-
// some place we need to keep opaque types opaque.
2085-
if (constant->isSerialized())
2086-
expansion = TypeExpansionContext::minimal();
2087-
lowerCaptureContextParameters(TC, *constant, genericSig, expansion, inputs);
2081+
lowerCaptureContextParameters(TC, *constant, genericSig,
2082+
TC.getCaptureTypeExpansionContext(*constant),
2083+
inputs);
20882084
}
20892085

20902086
auto calleeConvention = ParameterConvention::Direct_Unowned;

lib/SIL/IR/TypeLowering.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3623,6 +3623,19 @@ TypeConverter::getConstantAbstractionPattern(SILDeclRef constant) {
36233623
return None;
36243624
}
36253625

3626+
TypeExpansionContext
3627+
TypeConverter::getCaptureTypeExpansionContext(SILDeclRef constant) {
3628+
auto found = CaptureTypeExpansionContexts.find(constant);
3629+
if (found != CaptureTypeExpansionContexts.end()) {
3630+
return found->second;
3631+
}
3632+
// Insert a minimal type expansion context into the cache, so that further
3633+
// attempts to change it raise an error.
3634+
auto minimal = TypeExpansionContext::minimal();
3635+
CaptureTypeExpansionContexts.insert({constant, minimal});
3636+
return minimal;
3637+
}
3638+
36263639
void TypeConverter::setAbstractionPattern(AbstractClosureExpr *closure,
36273640
AbstractionPattern pattern) {
36283641
auto existing = ClosureAbstractionPatterns.find(closure);
@@ -3634,6 +3647,31 @@ void TypeConverter::setAbstractionPattern(AbstractClosureExpr *closure,
36343647
}
36353648
}
36363649

3650+
void TypeConverter::setCaptureTypeExpansionContext(SILDeclRef constant,
3651+
SILModule &M) {
3652+
if (!hasLoweredLocalCaptures(constant)) {
3653+
return;
3654+
}
3655+
3656+
TypeExpansionContext context = constant.isSerialized()
3657+
? TypeExpansionContext::minimal()
3658+
: TypeExpansionContext::maximal(constant.getAnyFunctionRef()->getAsDeclContext(),
3659+
M.isWholeModule());
3660+
3661+
auto existing = CaptureTypeExpansionContexts.find(constant);
3662+
if (existing != CaptureTypeExpansionContexts.end()) {
3663+
assert(existing->second == context
3664+
&& "closure shouldn't be emitted with different capture type expansion contexts");
3665+
} else {
3666+
// Lower in the context of the closure. Since the set of captures is a
3667+
// private contract between the closure and its enclosing context, we
3668+
// don't need to keep its capture types opaque.
3669+
// The exception is if it's inlinable, in which case it might get inlined into
3670+
// some place we need to keep opaque types opaque.
3671+
CaptureTypeExpansionContexts.insert({constant, context});
3672+
}
3673+
}
3674+
36373675
static void countNumberOfInnerFields(unsigned &fieldsCount, TypeConverter &TC,
36383676
SILType Ty,
36393677
TypeExpansionContext expansion) {

lib/SILGen/SILGen.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,6 +1421,8 @@ void SILGenModule::emitAbstractFuncDecl(AbstractFunctionDecl *AFD) {
14211421
}
14221422

14231423
void SILGenModule::emitFunction(FuncDecl *fd) {
1424+
Types.setCaptureTypeExpansionContext(SILDeclRef(fd), M);
1425+
14241426
SILDeclRef::Loc decl = fd;
14251427

14261428
emitAbstractFuncDecl(fd);

lib/SILGen/SILGenApply.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1139,6 +1139,8 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
11391139
}
11401140

11411141
auto captureInfo = SGF.SGM.Types.getLoweredLocalCaptures(constant);
1142+
SGF.SGM.Types.setCaptureTypeExpansionContext(constant, SGF.SGM.M);
1143+
11421144
if (afd->getDeclContext()->isLocalContext() &&
11431145
!captureInfo.hasGenericParamCaptures())
11441146
subs = SubstitutionMap();
@@ -1204,6 +1206,9 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
12041206
}
12051207

12061208
void visitAbstractClosureExpr(AbstractClosureExpr *e) {
1209+
SILDeclRef constant(e);
1210+
1211+
SGF.SGM.Types.setCaptureTypeExpansionContext(constant, SGF.SGM.M);
12071212
// Emit the closure body.
12081213
SGF.SGM.emitClosure(e);
12091214

@@ -1216,7 +1221,6 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
12161221

12171222
// A directly-called closure can be emitted as a direct call instead of
12181223
// really producing a closure object.
1219-
SILDeclRef constant(e);
12201224

12211225
auto captureInfo = SGF.SGM.M.Types.getLoweredLocalCaptures(constant);
12221226

lib/SILGen/SILGenExpr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2542,6 +2542,7 @@ RValue RValueEmitter::visitAbstractClosureExpr(AbstractClosureExpr *e,
25422542
if (auto contextOrigType = C.getAbstractionPattern()) {
25432543
SGF.SGM.Types.setAbstractionPattern(e, *contextOrigType);
25442544
}
2545+
SGF.SGM.Types.setCaptureTypeExpansionContext(SILDeclRef(e), SGF.SGM.M);
25452546

25462547
// Emit the closure body.
25472548
SGF.SGM.emitClosure(e);

lib/SILGen/SILGenFunction.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,8 @@ SILGenFunction::emitClosureValue(SILLocation loc, SILDeclRef constant,
441441
SubstitutionMap subs,
442442
bool alreadyConverted) {
443443
auto loweredCaptureInfo = SGM.Types.getLoweredLocalCaptures(constant);
444-
444+
SGM.Types.setCaptureTypeExpansionContext(constant, SGM.M);
445+
445446
auto constantInfo = getConstantInfo(getTypeExpansionContext(), constant);
446447
SILValue functionRef = emitGlobalFunctionRef(loc, constant, constantInfo);
447448
SILType functionTy = functionRef->getType();
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
public protocol P {}
3+
4+
struct PImpl: P {}
5+
6+
public struct Wrapper<T: P, U>: P {
7+
public init(value: T, extra: U) {}
8+
}
9+
10+
private struct Burrito {}
11+
12+
extension P {
13+
@inlinable
14+
public func wrapped<U>(extra: U) -> Wrapper<Self, U> {
15+
return Wrapper(value: self, extra: extra)
16+
}
17+
18+
public func burritoed() -> some P {
19+
return wrapped(extra: Burrito())
20+
}
21+
}
22+
23+
public class Butz<T: P> {
24+
init(_: T) {}
25+
}
26+
27+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %target-swift-emit-silgen -disable-availability-checking -verify -wmo %s %S/Inputs/opaque_result_type_captured_wmo_2.swift
2+
func foo(s: String?) {
3+
let x = PImpl()
4+
.burritoed()
5+
.wrapped(extra: 1)
6+
7+
let butz = Butz(x)
8+
9+
s.map { print("\($0) \(butz)") }
10+
}

0 commit comments

Comments
 (0)