Skip to content

Commit 81ba9fd

Browse files
authored
Merge pull request swiftlang#30309 from rjmccall/accessor-subst-function-types
Use pattern substitutions to consistently abstract yields
2 parents b12bd4e + 07f03bd commit 81ba9fd

18 files changed

+850
-124
lines changed

include/swift/AST/TypeDifferenceVisitor.h

Lines changed: 391 additions & 0 deletions
Large diffs are not rendered by default.

include/swift/AST/Types.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3838,6 +3838,11 @@ class SILParameterInfo {
38383838
return SILParameterInfo(type, getConvention(), getDifferentiability());
38393839
}
38403840

3841+
/// Return a version of this parameter info with the convention replaced.
3842+
SILParameterInfo getWithConvention(ParameterConvention c) const {
3843+
return SILParameterInfo(getInterfaceType(), c, getDifferentiability());
3844+
}
3845+
38413846
/// Transform this SILParameterInfo by applying the user-provided
38423847
/// function to its type.
38433848
///
@@ -3853,6 +3858,15 @@ class SILParameterInfo {
38533858
->getCanonicalType());
38543859
}
38553860

3861+
/// Treating this parameter info as a component of the given function
3862+
/// type, apply any substitutions from the function type to it to
3863+
/// get a substituted version of it, as you would get from
3864+
/// SILFunctionType::getUnsubstitutedType.
3865+
SILParameterInfo getUnsubstituted(SILModule &M,
3866+
const SILFunctionType *fnType) const {
3867+
return getWithInterfaceType(getArgumentType(M, fnType));
3868+
}
3869+
38563870
void profile(llvm::FoldingSetNodeID &id) {
38573871
id.AddPointer(getInterfaceType().getPointer());
38583872
id.AddInteger((unsigned)getConvention());
@@ -3955,6 +3969,11 @@ class SILResultInfo {
39553969
return SILResultInfo(type, getConvention());
39563970
}
39573971

3972+
/// Return a version of this result info with the convention replaced.
3973+
SILResultInfo getWithConvention(ResultConvention c) const {
3974+
return SILResultInfo(getInterfaceType(), c);
3975+
}
3976+
39583977
// Does this result convention require indirect storage? This reflects a
39593978
// SILFunctionType's formal (immutable) conventions, as opposed to the
39603979
// transient SIL conventions that dictate SILValue types.
@@ -3980,6 +3999,15 @@ class SILResultInfo {
39803999
->getCanonicalType());
39814000
}
39824001

4002+
/// Treating this result info as a component of the given function
4003+
/// type, apply any substitutions from the function type to it to
4004+
/// get a substituted version of it, as you would get from
4005+
/// SILFunctionType::getUnsubstitutedType.
4006+
SILResultInfo getUnsubstituted(SILModule &M,
4007+
const SILFunctionType *fnType) const {
4008+
return getWithInterfaceType(getReturnValueType(M, fnType));
4009+
}
4010+
39834011
void profile(llvm::FoldingSetNodeID &id) {
39844012
id.AddPointer(TypeAndConvention.getOpaqueValue());
39854013
}
@@ -4020,6 +4048,11 @@ class SILYieldInfo : public SILParameterInfo {
40204048
return SILYieldInfo(type, getConvention());
40214049
}
40224050

4051+
/// Return a version of this yield info with the convention replaced.
4052+
SILYieldInfo getWithConvention(YieldConvention c) const {
4053+
return SILYieldInfo(getInterfaceType(), c);
4054+
}
4055+
40234056
template<typename F>
40244057
SILYieldInfo map(const F &fn) const {
40254058
return getWithInterfaceType(fn(getInterfaceType()));
@@ -4029,6 +4062,20 @@ class SILYieldInfo : public SILParameterInfo {
40294062
return getWithInterfaceType(getInterfaceType()->mapTypeOutOfContext()
40304063
->getCanonicalType());
40314064
}
4065+
4066+
CanType getYieldValueType(SILModule &M,
4067+
const SILFunctionType *fnType) const {
4068+
return getArgumentType(M, fnType);
4069+
}
4070+
4071+
/// Treating this yield info as a component of the given function
4072+
/// type, apply any substitutions from the function type to it to
4073+
/// get a substituted version of it, as you would get from
4074+
/// SILFunctionType::getUnsubstitutedType.
4075+
SILYieldInfo getUnsubstituted(SILModule &M,
4076+
const SILFunctionType *fnType) const {
4077+
return getWithInterfaceType(getYieldValueType(M, fnType));
4078+
}
40324079
};
40334080

40344081
/// SILCoroutineKind - What kind of coroutine is this SILFunction?
@@ -4840,6 +4887,17 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
48404887
CanSILFunctionType
48414888
withPatternSubstitutions(SubstitutionMap subs) const;
48424889

4890+
/// Create a SILFunctionType with the same structure as this one,
4891+
/// but replacing the invocation generic signature and pattern
4892+
/// substitutions. This type must either be polymorphic or have
4893+
/// pattern substitutions, and the substitution signature must
4894+
/// match `getSubstGenericSignature()`.
4895+
CanSILFunctionType
4896+
withPatternSpecialization(CanGenericSignature sign,
4897+
SubstitutionMap subs,
4898+
ProtocolConformanceRef witnessConformance =
4899+
ProtocolConformanceRef()) const;
4900+
48434901
class ABICompatibilityCheckResult {
48444902
friend class SILFunctionType;
48454903

include/swift/SIL/SILFunction.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,11 @@ class SILFunction
354354
return SILFunctionConventions(LoweredType, getModule());
355355
}
356356

357+
SILFunctionConventions getConventionsInContext() const {
358+
auto fnType = getLoweredFunctionTypeInContext(getTypeExpansionContext());
359+
return SILFunctionConventions(fnType, getModule());
360+
}
361+
357362
SILProfiler *getProfiler() const { return Profiler; }
358363

359364
SILFunction *getDynamicallyReplacedFunction() const {

include/swift/SIL/SILType.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,11 @@ class SILType {
380380
bool hasArchetype() const {
381381
return getASTType()->hasArchetype();
382382
}
383+
384+
/// True if the type involves any opaque archetypes.
385+
bool hasOpaqueArchetype() const {
386+
return getASTType()->hasOpaqueArchetype();
387+
}
383388

384389
/// Returns the ASTContext for the referenced Swift type.
385390
ASTContext &getASTContext() const {

lib/AST/ASTMangler.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,6 +1515,9 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn) {
15151515
OpArgs.push_back('G');
15161516
break;
15171517
}
1518+
1519+
auto outerGenericSig = CurGenericSignature;
1520+
CurGenericSignature = fn->getSubstGenericSignature();
15181521

15191522
// Mangle the parameters.
15201523
for (auto param : fn->getParameters()) {
@@ -1542,17 +1545,24 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn) {
15421545
OpArgs.push_back(getResultConvention(error.getConvention()));
15431546
appendType(error.getInterfaceType());
15441547
}
1548+
15451549
if (auto sig = fn->getInvocationGenericSignature()) {
15461550
appendGenericSignature(sig);
1551+
CurGenericSignature = outerGenericSig;
15471552
}
15481553
if (auto subs = fn->getInvocationSubstitutions()) {
15491554
appendFlatGenericArgs(subs);
15501555
appendRetroactiveConformances(subs, Mod);
15511556
}
15521557
if (auto subs = fn->getPatternSubstitutions()) {
15531558
appendGenericSignature(subs.getGenericSignature());
1559+
CurGenericSignature =
1560+
fn->getInvocationGenericSignature()
1561+
? fn->getInvocationGenericSignature()
1562+
: outerGenericSig;
15541563
appendFlatGenericArgs(subs);
15551564
appendRetroactiveConformances(subs, Mod);
1565+
CurGenericSignature = outerGenericSig;
15561566
}
15571567

15581568
OpArgs.push_back('_');

lib/AST/ASTPrinter.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4208,10 +4208,8 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
42084208
}
42094209
sub->Printer << ") -> ";
42104210

4211-
unsigned totalResults =
4212-
T->getNumYields() + T->getNumResults() + unsigned(T->hasErrorResult());
4213-
4214-
if (totalResults != 1)
4211+
bool parenthesizeResults = mustParenthesizeResults(T);
4212+
if (parenthesizeResults)
42154213
sub->Printer << "(";
42164214

42174215
first = true;
@@ -4235,7 +4233,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
42354233
T->getErrorResult().getInterfaceType().print(sub->Printer, subOptions);
42364234
}
42374235

4238-
if (totalResults != 1)
4236+
if (parenthesizeResults)
42394237
sub->Printer << ")";
42404238
}();
42414239

@@ -4252,6 +4250,24 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
42524250
}
42534251
}
42544252

4253+
static bool mustParenthesizeResults(SILFunctionType *T) {
4254+
// If we don't have exactly one result, we must parenthesize.
4255+
unsigned totalResults =
4256+
T->getNumYields() + T->getNumResults() + unsigned(T->hasErrorResult());
4257+
if (totalResults != 1)
4258+
return true;
4259+
4260+
// If we have substitutions, we must parenthesize if the single
4261+
// result is a function type.
4262+
if (!T->hasPatternSubstitutions() && !T->hasInvocationSubstitutions())
4263+
return false;
4264+
if (T->getNumResults() == 1)
4265+
return isa<SILFunctionType>(T->getResults()[0].getInterfaceType());
4266+
if (T->getNumYields() == 1)
4267+
return isa<SILFunctionType>(T->getYields()[0].getInterfaceType());
4268+
return isa<SILFunctionType>(T->getErrorResult().getInterfaceType());
4269+
}
4270+
42554271
void visitSILBlockStorageType(SILBlockStorageType *T) {
42564272
Printer << "@block_storage ";
42574273
printWithParensIfNotSimple(T->getCaptureType());

lib/AST/Type.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5267,6 +5267,25 @@ SILFunctionType::withPatternSubstitutions(SubstitutionMap subs) const {
52675267
getWitnessMethodConformanceOrInvalid());
52685268
}
52695269

5270+
CanSILFunctionType
5271+
SILFunctionType::withPatternSpecialization(CanGenericSignature sig,
5272+
SubstitutionMap subs,
5273+
ProtocolConformanceRef
5274+
witnessConformance) const {
5275+
assert(!hasInvocationSubstitutions());
5276+
subs = subs.getCanonical();
5277+
assert(!subs || CanGenericSignature(subs.getGenericSignature())
5278+
== getSubstGenericSignature());
5279+
return SILFunctionType::get(sig,
5280+
getExtInfo(), getCoroutineKind(),
5281+
getCalleeConvention(),
5282+
getParameters(), getYields(), getResults(),
5283+
getOptionalErrorResult(),
5284+
subs, SubstitutionMap(),
5285+
const_cast<SILFunctionType*>(this)->getASTContext(),
5286+
witnessConformance);
5287+
}
5288+
52705289
SourceLoc swift::extractNearestSourceLoc(Type ty) {
52715290
if (auto nominal = ty->getAnyNominal())
52725291
return extractNearestSourceLoc(nominal);

lib/Frontend/ModuleInterfaceBuilder.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,18 @@ bool ModuleInterfaceBuilder::collectDepsForSerialization(
244244
bool ModuleInterfaceBuilder::buildSwiftModuleInternal(
245245
StringRef OutPath, bool ShouldSerializeDeps,
246246
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer) {
247+
248+
auto outerPrettyStackState = llvm::SavePrettyStackState();
249+
247250
bool SubError = false;
248251
bool RunSuccess = llvm::CrashRecoveryContext().RunSafelyOnThread([&] {
252+
// Pretend we're on the original thread for pretty-stack-trace purposes.
253+
auto savedInnerPrettyStackState = llvm::SavePrettyStackState();
254+
llvm::RestorePrettyStackState(outerPrettyStackState);
255+
SWIFT_DEFER {
256+
llvm::RestorePrettyStackState(savedInnerPrettyStackState);
257+
};
258+
249259
// Note that we don't assume cachePath is the same as the Clang
250260
// module cache path at this point.
251261
if (!moduleCachePath.empty())

0 commit comments

Comments
 (0)