Skip to content

Commit fd2a8e7

Browse files
authored
Merge pull request #59290 from jckarter/type-expansion-wmo-private-type
SILGen: Carry WMO of type lowering context to closure captures.
2 parents 1c76e22 + 6b6a557 commit fd2a8e7

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
@@ -821,6 +821,8 @@ class TypeConverter {
821821

822822
llvm::DenseMap<AbstractClosureExpr *, Optional<AbstractionPattern>>
823823
ClosureAbstractionPatterns;
824+
llvm::DenseMap<SILDeclRef, TypeExpansionContext>
825+
CaptureTypeExpansionContexts;
824826

825827
CanAnyFunctionType makeConstantInterfaceType(SILDeclRef constant);
826828

@@ -1225,6 +1227,7 @@ class TypeConverter {
12251227
/// the abstraction pattern is queried using this function. Once the
12261228
/// abstraction pattern has been asked for, it may not be changed.
12271229
Optional<AbstractionPattern> getConstantAbstractionPattern(SILDeclRef constant);
1230+
TypeExpansionContext getCaptureTypeExpansionContext(SILDeclRef constant);
12281231

12291232
/// Set the preferred abstraction pattern for a closure.
12301233
///
@@ -1234,6 +1237,8 @@ class TypeConverter {
12341237
void setAbstractionPattern(AbstractClosureExpr *closure,
12351238
AbstractionPattern pattern);
12361239

1240+
void setCaptureTypeExpansionContext(SILDeclRef constant,
1241+
SILModule &M);
12371242
private:
12381243
CanType computeLoweredRValueType(TypeExpansionContext context,
12391244
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
@@ -3862,6 +3862,19 @@ TypeConverter::getConstantAbstractionPattern(SILDeclRef constant) {
38623862
return None;
38633863
}
38643864

3865+
TypeExpansionContext
3866+
TypeConverter::getCaptureTypeExpansionContext(SILDeclRef constant) {
3867+
auto found = CaptureTypeExpansionContexts.find(constant);
3868+
if (found != CaptureTypeExpansionContexts.end()) {
3869+
return found->second;
3870+
}
3871+
// Insert a minimal type expansion context into the cache, so that further
3872+
// attempts to change it raise an error.
3873+
auto minimal = TypeExpansionContext::minimal();
3874+
CaptureTypeExpansionContexts.insert({constant, minimal});
3875+
return minimal;
3876+
}
3877+
38653878
void TypeConverter::setAbstractionPattern(AbstractClosureExpr *closure,
38663879
AbstractionPattern pattern) {
38673880
auto existing = ClosureAbstractionPatterns.find(closure);
@@ -3873,6 +3886,31 @@ void TypeConverter::setAbstractionPattern(AbstractClosureExpr *closure,
38733886
}
38743887
}
38753888

3889+
void TypeConverter::setCaptureTypeExpansionContext(SILDeclRef constant,
3890+
SILModule &M) {
3891+
if (!hasLoweredLocalCaptures(constant)) {
3892+
return;
3893+
}
3894+
3895+
TypeExpansionContext context = constant.isSerialized()
3896+
? TypeExpansionContext::minimal()
3897+
: TypeExpansionContext::maximal(constant.getAnyFunctionRef()->getAsDeclContext(),
3898+
M.isWholeModule());
3899+
3900+
auto existing = CaptureTypeExpansionContexts.find(constant);
3901+
if (existing != CaptureTypeExpansionContexts.end()) {
3902+
assert(existing->second == context
3903+
&& "closure shouldn't be emitted with different capture type expansion contexts");
3904+
} else {
3905+
// Lower in the context of the closure. Since the set of captures is a
3906+
// private contract between the closure and its enclosing context, we
3907+
// don't need to keep its capture types opaque.
3908+
// The exception is if it's inlinable, in which case it might get inlined into
3909+
// some place we need to keep opaque types opaque.
3910+
CaptureTypeExpansionContexts.insert({constant, context});
3911+
}
3912+
}
3913+
38763914
static void countNumberOfInnerFields(unsigned &fieldsCount, TypeConverter &TC,
38773915
SILType Ty,
38783916
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
@@ -1142,6 +1142,8 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
11421142
}
11431143

11441144
auto captureInfo = SGF.SGM.Types.getLoweredLocalCaptures(constant);
1145+
SGF.SGM.Types.setCaptureTypeExpansionContext(constant, SGF.SGM.M);
1146+
11451147
if (afd->getDeclContext()->isLocalContext() &&
11461148
!captureInfo.hasGenericParamCaptures())
11471149
subs = SubstitutionMap();
@@ -1207,6 +1209,9 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
12071209
}
12081210

12091211
void visitAbstractClosureExpr(AbstractClosureExpr *e) {
1212+
SILDeclRef constant(e);
1213+
1214+
SGF.SGM.Types.setCaptureTypeExpansionContext(constant, SGF.SGM.M);
12101215
// Emit the closure body.
12111216
SGF.SGM.emitClosure(e);
12121217

@@ -1219,7 +1224,6 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
12191224

12201225
// A directly-called closure can be emitted as a direct call instead of
12211226
// really producing a closure object.
1222-
SILDeclRef constant(e);
12231227

12241228
auto captureInfo = SGF.SGM.M.Types.getLoweredLocalCaptures(constant);
12251229

lib/SILGen/SILGenExpr.cpp

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

25492550
// Emit the closure body.
25502551
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)