mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
AST: Remove TypeBase::gatherAllSubstitutions()
This commit is contained in:
@@ -555,106 +555,6 @@ void ModuleDecl::getDisplayDecls(SmallVectorImpl<Decl*> &Results) const {
|
||||
FORWARD(getDisplayDecls, (Results));
|
||||
}
|
||||
|
||||
SubstitutionList
|
||||
TypeBase::gatherAllSubstitutions(ModuleDecl *module,
|
||||
LazyResolver *resolver,
|
||||
DeclContext *gpContext) {
|
||||
// FIXME: If there is no module, infer one. This is a hack for callers that
|
||||
// don't have access to the module. It will have to go away once we're
|
||||
// properly differentiating bound generic types based on the protocol
|
||||
// conformances visible from a given module.
|
||||
if (!module)
|
||||
module = getAnyNominal()->getParentModule();
|
||||
|
||||
// Check the context, introducing the default if needed.
|
||||
if (!gpContext)
|
||||
gpContext = getAnyNominal();
|
||||
|
||||
assert(gpContext->getAsNominalTypeOrNominalTypeExtensionContext()
|
||||
== getAnyNominal() && "not a valid context");
|
||||
|
||||
auto *genericSig = gpContext->getGenericSignatureOfContext();
|
||||
if (genericSig == nullptr)
|
||||
return { };
|
||||
|
||||
// If we already have a cached copy of the substitutions, return them.
|
||||
const ASTContext &ctx = getASTContext();
|
||||
if (auto known = ctx.getSubstitutions(this, gpContext))
|
||||
return *known;
|
||||
|
||||
// Compute the set of substitutions.
|
||||
TypeSubstitutionMap substitutions;
|
||||
|
||||
// The type itself contains substitutions up to the innermost
|
||||
// non-type context.
|
||||
Type parent = this;
|
||||
ArrayRef<GenericTypeParamType *> genericParams =
|
||||
genericSig->getGenericParams();
|
||||
unsigned lastGenericIndex = genericParams.size();
|
||||
while (parent) {
|
||||
if (auto boundGeneric = parent->getAs<BoundGenericType>()) {
|
||||
unsigned index = lastGenericIndex - boundGeneric->getGenericArgs().size();
|
||||
for (Type arg : boundGeneric->getGenericArgs()) {
|
||||
auto paramTy = genericParams[index++];
|
||||
substitutions[
|
||||
paramTy->getCanonicalType()->castTo<GenericTypeParamType>()] = arg;
|
||||
}
|
||||
lastGenericIndex -= boundGeneric->getGenericArgs().size();
|
||||
|
||||
parent = boundGeneric->getParent();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (auto protocol = parent->getAs<ProtocolType>()) {
|
||||
parent = protocol->getParent();
|
||||
lastGenericIndex--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (auto nominal = parent->getAs<NominalType>()) {
|
||||
parent = nominal->getParent();
|
||||
continue;
|
||||
}
|
||||
|
||||
llvm_unreachable("Not a nominal or bound generic type");
|
||||
}
|
||||
|
||||
auto *genericEnv = gpContext->getGenericEnvironmentOfContext();
|
||||
|
||||
// Add forwarding substitutions from the outer context if we have
|
||||
// a type nested inside a generic function.
|
||||
auto *parentDC = gpContext;
|
||||
while (parentDC->isTypeContext())
|
||||
parentDC = parentDC->getParent();
|
||||
if (auto *outerSig = parentDC->getGenericSignatureOfContext()) {
|
||||
for (auto gp : outerSig->getGenericParams()) {
|
||||
auto result = substitutions.insert(
|
||||
{gp->getCanonicalType()->castTo<GenericTypeParamType>(),
|
||||
genericEnv->mapTypeIntoContext(gp)});
|
||||
assert(result.second);
|
||||
(void) result;
|
||||
}
|
||||
}
|
||||
|
||||
SmallVector<Substitution, 4> result;
|
||||
genericSig->getSubstitutions(substitutions,
|
||||
LookUpConformanceInModule(module),
|
||||
result);
|
||||
|
||||
// Before recording substitutions, make sure we didn't end up doing it
|
||||
// recursively.
|
||||
if (auto known = ctx.getSubstitutions(this, gpContext))
|
||||
return *known;
|
||||
|
||||
// Copy and record the substitutions.
|
||||
auto permanentSubs = ctx.AllocateCopy(result,
|
||||
hasTypeVariable()
|
||||
? AllocationArena::ConstraintSolver
|
||||
: AllocationArena::Permanent);
|
||||
ctx.setSubstitutions(this, gpContext, permanentSubs);
|
||||
return permanentSubs;
|
||||
}
|
||||
|
||||
Optional<ProtocolConformanceRef>
|
||||
ModuleDecl::lookupConformance(Type type, ProtocolDecl *protocol,
|
||||
LazyResolver *resolver) {
|
||||
|
||||
Reference in New Issue
Block a user