Sema: Chain all generic parameter lists

Previously, methods on DeclContext for getting generic parameters
and signatures did not walk up from type contexts to function
contexts, or function contexts to function contexts.

Presumably this is because SIL doesn't completely support nested
generics yet, instead only handling these two special cases:

- non-generic local function inside generic function
- generic method inside generic type

For local functions nested inside generic functions, SIL expects
the closure to not have an interface type or generic signature,
even if the contextual type signature contains archetypes.
This should probably be revisited some day.

Recall that these cases are explicitly rejected by Sema diagnostics
because they lack SIL support:

- generic function inside generic function
- generic type inside generic function

After the previous patches in this series, it becomes possible to
construct types that are the same as before for the supported uses of
nested generics, while introducing a more self-consistent conceptual
model for the unsupported cases.

Some new tests show we generate diagnotics in various cases that
used to crash.

The conceptual model might still not be completely right, and of
course SIL, IRGen and runtime support is still missing.
This commit is contained in:
Slava Pestov
2015-12-15 21:37:27 -08:00
parent ef84c81429
commit d6ea5d8717
14 changed files with 229 additions and 180 deletions

View File

@@ -916,7 +916,7 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
// Adjust the type of the reference.
valueType = openType(valueType, locator,
replacements,
value->getPotentialGenericDeclContext(),
value->getInnermostDeclContext(),
/*skipProtocolSelfConstraint=*/false,
value->getDeclContext()->getGenericTypeContextDepth(),
opener);
@@ -1138,26 +1138,24 @@ ConstraintSystem::getTypeOfMemberReference(Type baseTy, ValueDecl *value,
}
// Figure out the declaration context to use when opening this type.
DeclContext *dc = value->getPotentialGenericDeclContext();
DeclContext *dc = value->getInnermostDeclContext();
unsigned minOpeningDepth =
value->getDeclContext()->getGenericTypeContextDepth();
// Open the type of the generic function or member of a generic type.
Type openedType;
auto isClassBoundExistential = false;
llvm::DenseMap<CanType, TypeVariableType *> replacements;
if (auto genericFn = value->getInterfaceType()->getAs<GenericFunctionType>()){
openedType = openType(genericFn, locator, replacements,
dc,
openedType = openType(genericFn, locator, replacements, dc,
/*skipProtocolSelfConstraint=*/true,
value->getDeclContext()->getGenericTypeContextDepth(),
opener);
minOpeningDepth, opener);
} else {
openedType = TC.getUnopenedTypeOfReference(value, baseTy, DC, base,
/*wantInterfaceType=*/true);
Type selfTy;
if (auto sig = dc->getGenericSignatureOfContext()) {
unsigned minOpeningDepth =
value->getDeclContext()->getGenericTypeContextDepth();
// Open up the generic parameter list for the container.
openGeneric(dc, sig->getGenericParams(), sig->getRequirements(),
@@ -1165,9 +1163,9 @@ ConstraintSystem::getTypeOfMemberReference(Type baseTy, ValueDecl *value,
opener, locator, replacements);
// Open up the type of the member.
openedType = openType(openedType, locator, replacements, nullptr, false,
value->getDeclContext()->getGenericTypeContextDepth(),
opener);
openedType = openType(openedType, locator, replacements, nullptr,
/*skipProtocolSelfConstraint=*/false,
minOpeningDepth, opener);
// Determine the object type of 'self'.
auto nominal = value->getDeclContext()->getDeclaredTypeOfContext()