mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Sema: Add DeclContext::getGenericTypeContextDepth()
Now that generic signatures of types include generic parameters introduced by outer generic functions, we need to know to skip them when forming bound generic types or substitutions. Add a function that computes the depth of the innermost generic context that is not a generic type context.
This commit is contained in:
@@ -531,6 +531,7 @@ namespace {
|
||||
ConstraintSystem &cs;
|
||||
DeclContext *dc;
|
||||
bool skipProtocolSelfConstraint;
|
||||
unsigned minOpeningDepth;
|
||||
DependentTypeOpener *opener;
|
||||
ConstraintLocatorBuilder &locator;
|
||||
llvm::DenseMap<CanType, TypeVariableType *> &replacements;
|
||||
@@ -541,13 +542,14 @@ namespace {
|
||||
ConstraintSystem &cs,
|
||||
DeclContext *dc,
|
||||
bool skipProtocolSelfConstraint,
|
||||
unsigned minOpeningDepth,
|
||||
DependentTypeOpener *opener,
|
||||
ConstraintLocatorBuilder &locator,
|
||||
llvm::DenseMap<CanType, TypeVariableType *> &replacements,
|
||||
GetTypeVariable &getTypeVariable)
|
||||
: cs(cs), dc(dc), skipProtocolSelfConstraint(skipProtocolSelfConstraint),
|
||||
opener(opener), locator(locator), replacements(replacements),
|
||||
getTypeVariable(getTypeVariable) { }
|
||||
minOpeningDepth(minOpeningDepth), opener(opener), locator(locator),
|
||||
replacements(replacements), getTypeVariable(getTypeVariable) { }
|
||||
|
||||
Type operator()(Type type) {
|
||||
assert(!type->is<PolymorphicFunctionType>() && "Shouldn't get here");
|
||||
@@ -616,6 +618,7 @@ namespace {
|
||||
genericFn->getGenericParams(),
|
||||
genericFn->getRequirements(),
|
||||
skipProtocolSelfConstraint,
|
||||
minOpeningDepth,
|
||||
opener,
|
||||
locator,
|
||||
replacements);
|
||||
@@ -651,6 +654,7 @@ namespace {
|
||||
unboundDecl->getGenericParamTypes(),
|
||||
unboundDecl->getGenericRequirements(),
|
||||
/*skipProtocolSelfConstraint=*/false,
|
||||
minOpeningDepth,
|
||||
opener,
|
||||
locator,
|
||||
replacements);
|
||||
@@ -676,11 +680,13 @@ Type ConstraintSystem::openType(
|
||||
llvm::DenseMap<CanType, TypeVariableType *> &replacements,
|
||||
DeclContext *dc,
|
||||
bool skipProtocolSelfConstraint,
|
||||
unsigned minOpeningDepth,
|
||||
DependentTypeOpener *opener) {
|
||||
GetTypeVariable getTypeVariable{*this, locator, opener};
|
||||
|
||||
ReplaceDependentTypes replaceDependentTypes(*this, dc,
|
||||
skipProtocolSelfConstraint,
|
||||
minOpeningDepth,
|
||||
opener,
|
||||
locator,
|
||||
replacements, getTypeVariable);
|
||||
@@ -831,7 +837,10 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
|
||||
assert(func->isOperator() && "Lookup should only find operators");
|
||||
|
||||
auto openedType = openType(func->getInterfaceType(), locator,
|
||||
replacements, func, false, opener);
|
||||
replacements, func,
|
||||
false,
|
||||
value->getDeclContext()->getGenericTypeContextDepth(),
|
||||
opener);
|
||||
auto openedFnType = openedType->castTo<FunctionType>();
|
||||
|
||||
// If this is a method whose result type is dynamic Self, replace
|
||||
@@ -869,7 +878,10 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
|
||||
|
||||
// Open the type.
|
||||
type = openType(type, locator, replacements,
|
||||
value->getInnermostDeclContext(), false, opener);
|
||||
value->getInnermostDeclContext(),
|
||||
false,
|
||||
value->getDeclContext()->getGenericTypeContextDepth(),
|
||||
opener);
|
||||
|
||||
// If we opened up any type variables, record the replacements.
|
||||
recordOpenedTypes(locator, replacements);
|
||||
@@ -906,6 +918,7 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
|
||||
replacements,
|
||||
value->getPotentialGenericDeclContext(),
|
||||
/*skipProtocolSelfConstraint=*/false,
|
||||
value->getDeclContext()->getGenericTypeContextDepth(),
|
||||
opener);
|
||||
|
||||
// If we opened up any type variables, record the replacements.
|
||||
@@ -919,6 +932,7 @@ void ConstraintSystem::openGeneric(
|
||||
ArrayRef<GenericTypeParamType *> params,
|
||||
ArrayRef<Requirement> requirements,
|
||||
bool skipProtocolSelfConstraint,
|
||||
unsigned minOpeningDepth,
|
||||
DependentTypeOpener *opener,
|
||||
ConstraintLocatorBuilder locator,
|
||||
llvm::DenseMap<CanType, TypeVariableType *> &replacements) {
|
||||
@@ -927,9 +941,8 @@ void ConstraintSystem::openGeneric(
|
||||
// Create the type variables for the generic parameters.
|
||||
for (auto gp : params) {
|
||||
// If we have a mapping for this type parameter, there's nothing else to do.
|
||||
if (opener && opener->mapGenericTypeParamType(gp)) {
|
||||
if (opener && opener->mapGenericTypeParamType(gp))
|
||||
continue;
|
||||
}
|
||||
|
||||
ArchetypeType *archetype = ArchetypeBuilder::mapTypeIntoContext(dc, gp)
|
||||
->castTo<ArchetypeType>();
|
||||
@@ -940,6 +953,9 @@ void ConstraintSystem::openGeneric(
|
||||
TVO_MustBeMaterializable);
|
||||
replacements[gp->getCanonicalType()] = typeVar;
|
||||
|
||||
if (gp->getDepth() < minOpeningDepth)
|
||||
addConstraint(ConstraintKind::Bind, typeVar, archetype, locatorPtr);
|
||||
|
||||
// Note that we opened a generic parameter to a type variable.
|
||||
if (opener) {
|
||||
Type replacementType;
|
||||
@@ -955,6 +971,7 @@ void ConstraintSystem::openGeneric(
|
||||
GetTypeVariable getTypeVariable{*this, locator, opener};
|
||||
ReplaceDependentTypes replaceDependentTypes(*this, dc,
|
||||
skipProtocolSelfConstraint,
|
||||
minOpeningDepth,
|
||||
opener, locator, replacements,
|
||||
getTypeVariable);
|
||||
|
||||
@@ -1128,21 +1145,28 @@ ConstraintSystem::getTypeOfMemberReference(Type baseTy, ValueDecl *value,
|
||||
auto isClassBoundExistential = false;
|
||||
llvm::DenseMap<CanType, TypeVariableType *> replacements;
|
||||
if (auto genericFn = value->getInterfaceType()->getAs<GenericFunctionType>()){
|
||||
openedType = openType(genericFn, locator, replacements, dc,
|
||||
/*skipProtocolSelfConstraint=*/true, opener);
|
||||
openedType = openType(genericFn, locator, replacements,
|
||||
dc,
|
||||
/*skipProtocolSelfConstraint=*/true,
|
||||
value->getDeclContext()->getGenericTypeContextDepth(),
|
||||
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(),
|
||||
/*skipProtocolSelfConstraint=*/true,
|
||||
/*skipProtocolSelfConstraint=*/true, minOpeningDepth,
|
||||
opener, locator, replacements);
|
||||
|
||||
// Open up the type of the member.
|
||||
openedType = openType(openedType, locator, replacements, nullptr, false,
|
||||
openedType = openType(openedType, locator, replacements, nullptr, false,
|
||||
value->getDeclContext()->getGenericTypeContextDepth(),
|
||||
opener);
|
||||
|
||||
// Determine the object type of 'self'.
|
||||
|
||||
Reference in New Issue
Block a user