[AST] Add a form of Type::subst() that takes an arbitrary substitution function

The "core" data structure used to record the substitutions to be
performed is a TypeSubstitutionMap, which is a DenseMap. This is a
fairly heavyweight, static data structure for something where

* We occasionally want a more dynamic, lazily-populated data structure, and
* We can usually provide more efficient storage than a DenseMap.

So, introduce a Type::subst() variant that takes a TypeSubstitutionFn,
which is just a function that maps a SubstitutableType * to a Type (or
nothing). Use this as the core variant of subst(). with an adapter for
existing TypeSubstitutionMaps. Over time, TypeSubstitutionMap should
go away.
This commit is contained in:
Doug Gregor
2016-11-30 23:12:07 -08:00
parent a3a943a683
commit 9e465fa03d
6 changed files with 98 additions and 11 deletions

View File

@@ -99,8 +99,20 @@ Type GenericEnvironment::mapTypeOutOfContext(ModuleDecl *M, Type type) const {
return type;
}
GenericEnvironment::QueryInterfaceTypeSubstitutions::operator()(
SubstitutableType *type) const {
if (auto gp = type->getCanonicalType()->getAs<GenericTypeParamType>()) {
auto known = self->InterfaceToArchetypeMap.find(gp);
if (known != self->InterfaceToArchetypeMap.end())
return known->second;
}
return Type();
}
Type GenericEnvironment::mapTypeIntoContext(ModuleDecl *M, Type type) const {
type = type.subst(M, InterfaceToArchetypeMap, SubstFlags::AllowLoweredTypes);
type = type.subst(M, QueryInterfaceTypeSubstitutions(this),
SubstFlags::AllowLoweredTypes);
assert((!type->hasTypeParameter() || type->hasError()) &&
"not fully substituted");
return type;
@@ -133,7 +145,8 @@ GenericEnvironment::getForwardingSubstitutions(ModuleDecl *M) const {
};
SmallVector<Substitution, 4> result;
getGenericSignature()->getSubstitutions(*M, InterfaceToArchetypeMap,
getGenericSignature()->getSubstitutions(*M,
QueryInterfaceTypeSubstitutions(this),
lookupConformanceFn, result);
return getGenericSignature()->getASTContext().AllocateCopy(result);
}
@@ -153,7 +166,8 @@ getSubstitutionMap(ModuleDecl *mod,
for (auto depTy : getGenericSignature()->getAllDependentTypes()) {
// Map the interface type to a context type.
auto contextTy = depTy.subst(mod, InterfaceToArchetypeMap, SubstOptions());
auto contextTy = depTy.subst(mod, QueryInterfaceTypeSubstitutions(this),
SubstOptions());
auto *archetype = contextTy->castTo<ArchetypeType>();
auto sub = subs.front();