AST: Don't canonicalize types when caching substitutions

This causes us to lose sugar in some cases; needed for the next patch.
This commit is contained in:
Slava Pestov
2016-11-26 01:00:34 -05:00
parent 84a322fb2e
commit c5b461924a
2 changed files with 10 additions and 15 deletions

View File

@@ -1112,7 +1112,6 @@ Optional<ArrayRef<Substitution>>
ASTContext::createTrivialSubstitutions(BoundGenericType *BGT,
DeclContext *gpContext) const {
assert(gpContext && "No generic parameter context");
assert(BGT->isCanonical() && "Requesting non-canonical substitutions");
assert(gpContext->isValidGenericContext() &&
"Not type-checked yet");
assert(BGT->getGenericArgs().size() == 1);
@@ -1129,7 +1128,6 @@ ASTContext::getSubstitutions(TypeBase *type,
DeclContext *gpContext) const {
assert(gpContext && "Missing generic parameter context");
auto arena = getArena(type->getRecursiveProperties());
assert(type->isCanonical() && "Requesting non-canonical substitutions");
auto &boundGenericSubstitutions
= Impl.getArena(arena).BoundGenericSubstitutions;
auto known = boundGenericSubstitutions.find({type, gpContext});
@@ -1151,7 +1149,6 @@ void ASTContext::setSubstitutions(TypeBase* type,
auto arena = getArena(type->getRecursiveProperties());
auto &boundGenericSubstitutions
= Impl.getArena(arena).BoundGenericSubstitutions;
assert(type->isCanonical() && "Requesting non-canonical substitutions");
assert(boundGenericSubstitutions.count({type, gpContext}) == 0 &&
"Already have substitutions?");
boundGenericSubstitutions[{type, gpContext}] = Subs;

View File

@@ -576,9 +576,8 @@ TypeBase::gatherAllSubstitutions(Module *module,
return { };
// If we already have a cached copy of the substitutions, return them.
auto *canon = getCanonicalType().getPointer();
const ASTContext &ctx = canon->getASTContext();
if (auto known = ctx.getSubstitutions(canon, gpContext))
const ASTContext &ctx = getASTContext();
if (auto known = ctx.getSubstitutions(this, gpContext))
return *known;
// Compute the set of substitutions.
@@ -586,12 +585,12 @@ TypeBase::gatherAllSubstitutions(Module *module,
// The type itself contains substitutions up to the innermost
// non-type context.
CanType parent(canon);
Type parent = this;
ArrayRef<GenericTypeParamType *> genericParams =
genericSig->getGenericParams();
unsigned lastGenericIndex = genericParams.size();
while (parent) {
if (auto boundGeneric = dyn_cast<BoundGenericType>(parent)) {
if (auto boundGeneric = parent->getAs<BoundGenericType>()) {
unsigned index = lastGenericIndex - boundGeneric->getGenericArgs().size();
for (Type arg : boundGeneric->getGenericArgs()) {
auto paramTy = genericParams[index++];
@@ -600,12 +599,12 @@ TypeBase::gatherAllSubstitutions(Module *module,
}
lastGenericIndex -= boundGeneric->getGenericArgs().size();
parent = CanType(boundGeneric->getParent());
parent = boundGeneric->getParent();
continue;
}
if (auto nominal = dyn_cast<NominalType>(parent)) {
parent = CanType(nominal->getParent());
if (auto nominal = parent->getAs<NominalType>()) {
parent = nominal->getParent();
continue;
}
@@ -654,16 +653,15 @@ TypeBase::gatherAllSubstitutions(Module *module,
// Before recording substitutions, make sure we didn't end up doing it
// recursively.
if (auto known = ctx.getSubstitutions(canon, gpContext))
if (auto known = ctx.getSubstitutions(this, gpContext))
return *known;
// Copy and record the substitutions.
bool hasTypeVariables = canon->hasTypeVariable();
auto permanentSubs = ctx.AllocateCopy(result,
hasTypeVariables
hasTypeVariable()
? AllocationArena::ConstraintSolver
: AllocationArena::Permanent);
ctx.setSubstitutions(canon, gpContext, permanentSubs);
ctx.setSubstitutions(this, gpContext, permanentSubs);
return permanentSubs;
}