Skip to content

Commit e520a32

Browse files
committed
AST: Generalize GenericEnvironment::maybeApplyOuterSubstitutions()
1 parent 39d77b8 commit e520a32

File tree

3 files changed

+47
-46
lines changed

3 files changed

+47
-46
lines changed

include/swift/AST/SubstitutionMap.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,19 @@ struct LookUpConformanceInOverrideSubs {
324324
ProtocolDecl *proto) const;
325325
};
326326

327+
// Substitute the outer generic parameters from a substitution map, ignoring
328+
/// inner generic parameters with a given depth.
329+
struct OuterSubstitutions {
330+
SubstitutionMap subs;
331+
unsigned depth;
332+
333+
bool isUnsubstitutedTypeParameter(Type type) const;
334+
Type operator()(SubstitutableType *type) const;
335+
ProtocolConformanceRef operator()(CanType dependentType,
336+
Type conformingReplacementType,
337+
ProtocolDecl *conformedProtocol) const;
338+
};
339+
327340
} // end namespace swift
328341

329342
namespace llvm {

lib/AST/GenericEnvironment.cpp

Lines changed: 2 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -291,48 +291,6 @@ GenericEnvironment::getMappingIfPresent(GenericParamKey key) const {
291291
return std::nullopt;
292292
}
293293

294-
namespace {
295-
296-
/// Substitute the outer generic parameters from a substitution map, ignoring
297-
/// innter generic parameters with a given depth.
298-
struct SubstituteOuterFromSubstitutionMap {
299-
SubstitutionMap subs;
300-
unsigned depth;
301-
302-
/// Whether this is a type parameter that should not be substituted.
303-
bool isUnsubstitutedTypeParameter(Type type) const {
304-
if (!type->isTypeParameter())
305-
return false;
306-
307-
if (auto depMemTy = type->getAs<DependentMemberType>())
308-
return isUnsubstitutedTypeParameter(depMemTy->getBase());
309-
310-
if (auto genericParam = type->getAs<GenericTypeParamType>())
311-
return genericParam->getDepth() >= depth;
312-
313-
return false;
314-
}
315-
316-
Type operator()(SubstitutableType *type) const {
317-
if (isUnsubstitutedTypeParameter(type))
318-
return Type(type);
319-
320-
return QuerySubstitutionMap{subs}(type);
321-
}
322-
323-
ProtocolConformanceRef operator()(CanType dependentType,
324-
Type conformingReplacementType,
325-
ProtocolDecl *conformedProtocol) const {
326-
if (isUnsubstitutedTypeParameter(dependentType))
327-
return ProtocolConformanceRef(conformedProtocol);
328-
329-
return LookUpConformanceInSubstitutionMap(subs)(
330-
dependentType, conformingReplacementType, conformedProtocol);
331-
}
332-
};
333-
334-
}
335-
336294
Type
337295
GenericEnvironment::maybeApplyOuterContextSubstitutions(Type type) const {
338296
switch (getKind()) {
@@ -342,10 +300,8 @@ GenericEnvironment::maybeApplyOuterContextSubstitutions(Type type) const {
342300

343301
case Kind::OpenedElement:
344302
case Kind::Opaque: {
345-
auto packElements = getGenericSignature().getInnermostGenericParams();
346-
auto elementDepth = packElements.front()->getDepth();
347-
SubstituteOuterFromSubstitutionMap replacer{
348-
getOuterSubstitutions(), elementDepth};
303+
OuterSubstitutions replacer{
304+
getOuterSubstitutions(), getGenericSignature()->getMaxDepth()};
349305
return type.subst(replacer, replacer);
350306
}
351307
}

lib/AST/SubstitutionMap.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,3 +666,35 @@ SubstitutionMap SubstitutionMap::mapIntoTypeExpansionContext(
666666
SubstFlags::SubstituteOpaqueArchetypes |
667667
SubstFlags::PreservePackExpansionLevel);
668668
}
669+
670+
bool OuterSubstitutions::isUnsubstitutedTypeParameter(Type type) const {
671+
if (!type->isTypeParameter())
672+
return false;
673+
674+
if (auto depMemTy = type->getAs<DependentMemberType>())
675+
return isUnsubstitutedTypeParameter(depMemTy->getBase());
676+
677+
if (auto genericParam = type->getAs<GenericTypeParamType>())
678+
return genericParam->getDepth() >= depth;
679+
680+
return false;
681+
}
682+
683+
Type OuterSubstitutions::operator()(SubstitutableType *type) const {
684+
if (isUnsubstitutedTypeParameter(type))
685+
return Type(type);
686+
687+
return QuerySubstitutionMap{subs}(type);
688+
}
689+
690+
ProtocolConformanceRef OuterSubstitutions::operator()(
691+
CanType dependentType,
692+
Type conformingReplacementType,
693+
ProtocolDecl *conformedProtocol) const {
694+
if (isUnsubstitutedTypeParameter(dependentType))
695+
return ProtocolConformanceRef(conformedProtocol);
696+
697+
return LookUpConformanceInSubstitutionMap(subs)(
698+
dependentType, conformingReplacementType, conformedProtocol);
699+
}
700+

0 commit comments

Comments
 (0)