Skip to content

Commit 3d4503a

Browse files
committed
AST: Add optional GenericEnvironment parameter to TypeBase::getContextSubstitutionMap()
If a generic type appears in a generic function, the old gatherAllSubstitutions() method would map outer generic parameters to archetypes. However, getContextSubstitutionMap() did not map them to anything. I'm trying to unify these methods, so add an optional GenericEnvironment to getContextSubstitutionMap() to support the cases where they're needed. Of course types in generic functions are not supported right now, but not preserving this subtle behavioral difference makes some crashers regress.
1 parent df81e51 commit 3d4503a

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

include/swift/AST/Types.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -869,11 +869,17 @@ class alignas(1 << TypeAlignInBits) TypeBase {
869869
/// the context of the extension above will produce substitutions T
870870
/// -> Int and U -> String suitable for mapping the type of
871871
/// \c SomeArray.
872+
///
873+
/// \param genericEnv If non-null and the type is nested inside of a
874+
/// generic function, generic parameters of the outer context are
875+
/// mapped to context archetypes of this generic environment.
872876
SubstitutionMap getContextSubstitutionMap(ModuleDecl *module,
873-
const DeclContext *dc);
877+
const DeclContext *dc,
878+
GenericEnvironment *genericEnv=nullptr);
874879

875880
/// Deprecated version of the above.
876-
TypeSubstitutionMap getContextSubstitutions(const DeclContext *dc);
881+
TypeSubstitutionMap getContextSubstitutions(const DeclContext *dc,
882+
GenericEnvironment *genericEnv=nullptr);
877883

878884
/// Get the substitutions to apply to the type of the given member as seen
879885
/// from this base type.

lib/AST/Type.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3022,7 +3022,9 @@ Type TypeBase::getSuperclassForDecl(const ClassDecl *baseClass,
30223022
llvm_unreachable("no inheritance relationship between given classes");
30233023
}
30243024

3025-
TypeSubstitutionMap TypeBase::getContextSubstitutions(const DeclContext *dc) {
3025+
TypeSubstitutionMap
3026+
TypeBase::getContextSubstitutions(const DeclContext *dc,
3027+
GenericEnvironment *genericEnv) {
30263028
assert(dc->isTypeContext());
30273029
Type baseTy(this);
30283030

@@ -3101,16 +3103,32 @@ TypeSubstitutionMap TypeBase::getContextSubstitutions(const DeclContext *dc) {
31013103
llvm_unreachable("Bad base type");
31023104
}
31033105

3106+
if (genericEnv) {
3107+
auto *parentDC = dc;
3108+
while (parentDC->isTypeContext())
3109+
parentDC = parentDC->getParent();
3110+
if (auto *outerSig = parentDC->getGenericSignatureOfContext()) {
3111+
for (auto gp : outerSig->getGenericParams()) {
3112+
auto result = substitutions.insert(
3113+
{gp->getCanonicalType()->castTo<GenericTypeParamType>(),
3114+
genericEnv->mapTypeIntoContext(gp)});
3115+
assert(result.second);
3116+
(void) result;
3117+
}
3118+
}
3119+
}
3120+
31043121
return substitutions;
31053122
}
31063123

31073124
SubstitutionMap TypeBase::getContextSubstitutionMap(
3108-
ModuleDecl *module, const DeclContext *dc) {
3125+
ModuleDecl *module, const DeclContext *dc,
3126+
GenericEnvironment *genericEnv) {
31093127
auto *genericSig = dc->getGenericSignatureOfContext();
31103128
if (genericSig == nullptr)
31113129
return SubstitutionMap();
31123130
return genericSig->getSubstitutionMap(
3113-
QueryTypeSubstitutionMap{getContextSubstitutions(dc)},
3131+
QueryTypeSubstitutionMap{getContextSubstitutions(dc, genericEnv)},
31143132
LookUpConformanceInModule(module));
31153133
}
31163134

@@ -3123,7 +3141,7 @@ TypeSubstitutionMap TypeBase::getMemberSubstitutions(
31233141

31243142
// Compute the set of member substitutions to apply.
31253143
if (memberDC->isTypeContext())
3126-
substitutions = getContextSubstitutions(memberDC);
3144+
substitutions = getContextSubstitutions(memberDC, genericEnv);
31273145

31283146
// If the member itself is generic, preserve its generic parameters.
31293147
// We need this since code completion and diagnostics want to be able

0 commit comments

Comments
 (0)