Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/swift/AST/SubstitutionMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ class SubstitutionMap {

/// Query whether any replacement types in the map contain an opened
/// existential.
bool hasOpenedExistential() const;
bool hasLocalArchetypes() const;

/// Query whether any replacement types in the map contain dynamic Self.
bool hasDynamicSelf() const;
Expand Down
13 changes: 5 additions & 8 deletions include/swift/SIL/SILCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,15 +192,11 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
// If we have local archetypes to substitute, check whether that's
// relevant to this particular substitution.
if (!LocalArchetypeSubs.empty()) {
for (auto ty : Subs.getReplacementTypes()) {
if (Subs.hasLocalArchetypes()) {
// If we found a type containing a local archetype, substitute
// open existentials throughout the substitution map.
if (ty->hasLocalArchetype()) {
Subs = Subs.subst(QueryTypeSubstitutionMapOrIdentity{
LocalArchetypeSubs},
MakeAbstractConformanceForGenericType());
break;
}
Subs = Subs.subst(QueryTypeSubstitutionMapOrIdentity{LocalArchetypeSubs},
MakeAbstractConformanceForGenericType());
}
}

Expand All @@ -223,7 +219,8 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
return Ty.subst(
Builder.getModule(),
QueryTypeSubstitutionMapOrIdentity{LocalArchetypeSubs},
MakeAbstractConformanceForGenericType());
MakeAbstractConformanceForGenericType(),
CanGenericSignature());
}
SILType getOpType(SILType Ty) {
Ty = getTypeInClonedContext(Ty);
Expand Down
11 changes: 6 additions & 5 deletions lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -653,13 +653,14 @@ std::string ASTMangler::mangleAutoDiffGeneratedDeclaration(
static Type getTypeForDWARFMangling(Type t) {
return t.subst(
[](SubstitutableType *t) -> Type {
if (isa<GenericTypeParamType>(t))
return t->getCanonicalType();
return t;
if (isa<GenericTypeParamType>(t) &&
cast<GenericTypeParamType>(t)->isParameterPack()) {
return PackType::getSingletonPackExpansion(t->getCanonicalType());
}
return t->getCanonicalType();
},
MakeAbstractConformanceForGenericType(),
SubstFlags::AllowLoweredTypes |
SubstFlags::PreservePackExpansionLevel);
SubstFlags::AllowLoweredTypes);
}

std::string ASTMangler::mangleTypeForDebugger(Type Ty, GenericSignature sig) {
Expand Down
29 changes: 15 additions & 14 deletions lib/AST/RequirementEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ RequirementEnvironment::RequirementEnvironment(
auto concreteType = conformanceDC->getSelfInterfaceType();
auto conformanceSig = conformanceDC->getGenericSignatureOfContext();

auto conformanceToWitnessThunkGenericParamFn = [&](GenericTypeParamType *genericParam)
-> GenericTypeParamType * {
return GenericTypeParamType::get(genericParam->isParameterPack(),
genericParam->getDepth() + (covariantSelf ? 1 : 0),
genericParam->getIndex(), ctx);
};

// This is a substitution function from the generic parameters of the
// conforming type to the witness thunk environment.
//
Expand All @@ -53,25 +60,20 @@ RequirementEnvironment::RequirementEnvironment(
// This is a raw function rather than a substitution map because we need to
// keep generic parameters as generic, even if the conformanceSig (the best
// way to create the substitution map) equates them to concrete types.
auto conformanceToWitnessThunkTypeFn = [&](SubstitutableType *type) {
auto conformanceToWitnessThunkTypeFn = [&](SubstitutableType *type) -> Type {
auto *genericParam = cast<GenericTypeParamType>(type);
if (covariantSelf) {
return GenericTypeParamType::get(genericParam->isParameterPack(),
genericParam->getDepth() + 1,
genericParam->getIndex(), ctx);
}
auto t = conformanceToWitnessThunkGenericParamFn(genericParam);
if (t->isParameterPack())
return PackType::getSingletonPackExpansion(t);

return GenericTypeParamType::get(genericParam->isParameterPack(),
genericParam->getDepth(),
genericParam->getIndex(), ctx);
return t;
};
auto conformanceToWitnessThunkConformanceFn =
MakeAbstractConformanceForGenericType();

auto substConcreteType = concreteType.subst(
conformanceToWitnessThunkTypeFn,
conformanceToWitnessThunkConformanceFn,
SubstFlags::PreservePackExpansionLevel);
conformanceToWitnessThunkConformanceFn);

// Calculate the depth at which the requirement's generic parameters
// appear in the witness thunk signature.
Expand Down Expand Up @@ -168,9 +170,8 @@ RequirementEnvironment::RequirementEnvironment(
// Now, add all generic parameters from the conforming type.
if (conformanceSig) {
for (auto param : conformanceSig.getGenericParams()) {
auto substParam = Type(param).subst(conformanceToWitnessThunkTypeFn,
conformanceToWitnessThunkConformanceFn);
genericParamTypes.push_back(substParam->castTo<GenericTypeParamType>());
auto substParam = conformanceToWitnessThunkGenericParamFn(param);
genericParamTypes.push_back(substParam);
}
}

Expand Down
4 changes: 2 additions & 2 deletions lib/AST/SubstitutionMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@ bool SubstitutionMap::hasArchetypes() const {
return false;
}

bool SubstitutionMap::hasOpenedExistential() const {
bool SubstitutionMap::hasLocalArchetypes() const {
for (Type replacementTy : getReplacementTypesBuffer()) {
if (replacementTy && replacementTy->hasOpenedExistential())
if (replacementTy && replacementTy->hasLocalArchetype())
return true;
}
return false;
Expand Down
8 changes: 7 additions & 1 deletion lib/AST/TypeSubstitution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,13 @@ QueryTypeSubstitutionMapOrIdentity::operator()(SubstitutableType *type) const {
auto known = substitutions.find(key);
if (known != substitutions.end() && known->second)
return known->second;


if (isa<PackArchetypeType>(type) ||
(isa<GenericTypeParamType>(type) &&
cast<GenericTypeParamType>(type)->isParameterPack())) {
return PackType::getSingletonPackExpansion(type);
}

return type;
}

Expand Down
18 changes: 18 additions & 0 deletions test/SILOptimizer/variadic_generics_sil_cloner.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// RUN: %target-swift-frontend -emit-sil -O %s | %FileCheck %s

@_optimize(none)
public func callee<T, each X>(_: T, _: repeat each X) {}

@_transparent
public func caller<each X>(_ x: repeat each X) {
repeat callee(each x, repeat each x)
}

public func outerCaller<each X>(_ x: repeat each X) {
caller(repeat each x)
}

// CHECK-LABEL: sil @$s28variadic_generics_sil_cloner11outerCalleryyxxQpRvzlF : $@convention(thin) <each X> (@pack_guaranteed Pack{repeat each X}) -> () {
// CHECK: [[CALLEE:%.*]] = function_ref @$s28variadic_generics_sil_cloner6calleeyyx_q_q_QptRv_r0_lF : $@convention(thin) <τ_0_0, each τ_0_1> (@in_guaranteed τ_0_0, @pack_guaranteed Pack{repeat each τ_0_1}) -> ()
// CHECK: apply [[CALLEE]]<@pack_element("{{.*}}") each X, Pack{repeat each X}>(
// CHECK: // end sil function '$s28variadic_generics_sil_cloner11outerCalleryyxxQpRvzlF'