Remove Module parameter from GenericEnvironment::mapTypeOutOfContext.

The substitution only replaces archetypes with abstract generic parameters, so no conformance lookup is necessary, and we can provide a "lookup" callback now that just vends abstract conformances.

(Ideally, we'd be able to do this for mapTypeIntoContext too, but we run into problems with generic signatures with same-type constraints on associated types with protocol requirements. Mapping `t_0_0.AssocType` into such a context will require conformance lookup for the concrete type replacement, since same-type Requirements don't preserve the conformances that satisfy the protocol requirements for the same-type relationship.)
This commit is contained in:
Joe Groff
2016-12-15 10:55:33 -08:00
parent b482c7ff33
commit 57d9ad0a03
13 changed files with 48 additions and 47 deletions

View File

@@ -315,8 +315,7 @@ public:
static Type mapTypeOutOfContext(const DeclContext *dc, Type type);
/// Map a contextual type to an interface type.
static Type mapTypeOutOfContext(ModuleDecl *M,
GenericEnvironment *genericEnv,
static Type mapTypeOutOfContext(GenericEnvironment *genericEnv,
Type type);
/// \brief Dump all of the requirements, both specified and inferred.

View File

@@ -197,7 +197,7 @@ public:
}
/// Map a contextual type to an interface type.
Type mapTypeOutOfContext(ModuleDecl *M, Type type) const;
Type mapTypeOutOfContext(Type type) const;
/// Map an interface type to a contextual type.
Type mapTypeIntoContext(ModuleDecl *M, Type type) const;

View File

@@ -105,6 +105,17 @@ public:
ProtocolType *conformedProtocol) const;
};
/// Functor class suitable for use as a \c LookupConformanceFn that provides
/// only abstract conformances for generic types. Asserts that the replacement
/// type is an opaque generic type.
class MakeAbstractConformanceForGenericType {
public:
Optional<ProtocolConformanceRef>
operator()(CanType dependentType,
Type conformingReplacementType,
ProtocolType *conformedProtocol) const;
};
/// Flags that can be passed when substituting into a type.
enum class SubstFlags {
/// If a type cannot be produced because some member type is

View File

@@ -423,8 +423,7 @@ auto ArchetypeBuilder::PotentialArchetype::getNestedType(
// Map the type out of its context.
if (auto genericEnv = alias->getGenericEnvironmentOfContext()) {
type = genericEnv->mapTypeOutOfContext(alias->getModuleContext(),
type);
type = genericEnv->mapTypeOutOfContext(type);
}
if (auto existingPA = builder.resolveArchetype(type)) {
@@ -688,8 +687,7 @@ void ArchetypeType::resolveNestedType(
auto &builder = *genericEnv->getArchetypeBuilder();
Type interfaceType =
genericEnv->mapTypeOutOfContext(&builder.getModule(),
const_cast<ArchetypeType *>(this));
genericEnv->mapTypeOutOfContext(const_cast<ArchetypeType *>(this));
auto parentPA = builder.resolveArchetype(interfaceType);
auto memberPA = parentPA->getNestedType(nested.first, builder);
auto result = memberPA->getTypeInContext(builder, genericEnv);
@@ -1975,14 +1973,12 @@ Type ArchetypeBuilder::mapTypeIntoContext(ModuleDecl *M,
Type
ArchetypeBuilder::mapTypeOutOfContext(const DeclContext *dc, Type type) {
return mapTypeOutOfContext(dc->getParentModule(),
dc->getGenericEnvironmentOfContext(),
return mapTypeOutOfContext(dc->getGenericEnvironmentOfContext(),
type);
}
Type
ArchetypeBuilder::mapTypeOutOfContext(ModuleDecl *M,
GenericEnvironment *env,
ArchetypeBuilder::mapTypeOutOfContext(GenericEnvironment *env,
Type type) {
auto canType = type->getCanonicalType();
assert(!canType->hasTypeParameter() && "already have an interface type");
@@ -1991,7 +1987,7 @@ ArchetypeBuilder::mapTypeOutOfContext(ModuleDecl *M,
assert(env && "dependent type in non-generic context");
return env->mapTypeOutOfContext(M, type);
return env->mapTypeOutOfContext(type);
}
void ArchetypeBuilder::addGenericSignature(GenericSignature *sig) {

View File

@@ -303,7 +303,7 @@ Type DeclContext::mapTypeIntoContext(Type type) const {
Type DeclContext::mapTypeOutOfContext(Type type) const {
if (auto genericEnv = getGenericEnvironmentOfContext())
return genericEnv->mapTypeOutOfContext(getParentModule(), type);
return genericEnv->mapTypeOutOfContext(type);
return type;
}

View File

@@ -142,9 +142,9 @@ bool GenericEnvironment::containsPrimaryArchetype(
QueryArchetypeToInterfaceSubstitutions(this)(archetype));
}
Type GenericEnvironment::mapTypeOutOfContext(ModuleDecl *M, Type type) const {
Type GenericEnvironment::mapTypeOutOfContext(Type type) const {
type = type.subst(QueryArchetypeToInterfaceSubstitutions(this),
LookUpConformanceInModule(M),
MakeAbstractConformanceForGenericType(),
SubstFlags::AllowLoweredTypes);
assert(!type->hasArchetype() && "not fully substituted");
return type;

View File

@@ -2892,6 +2892,16 @@ LookUpConformanceInSubstitutionMap::operator()(CanType dependentType,
return Subs.lookupConformance(dependentType, conformedProtocol->getDecl());
}
Optional<ProtocolConformanceRef>
MakeAbstractConformanceForGenericType::operator()(CanType dependentType,
Type conformingReplacementType,
ProtocolType *conformedProtocol) const {
assert((conformingReplacementType->is<SubstitutableType>()
|| conformingReplacementType->is<DependentMemberType>())
&& "replacement requires looking up a concrete conformance");
return ProtocolConformanceRef(conformedProtocol->getDecl());
}
Type DependentMemberType::substBaseType(ModuleDecl *module,
Type substBase,
LazyResolver *resolver) {

View File

@@ -277,8 +277,7 @@ SILType GenericEnvironment::mapTypeIntoContext(SILModule &M,
}
Type SILFunction::mapTypeOutOfContext(Type type) const {
return ArchetypeBuilder::mapTypeOutOfContext(getModule().getSwiftModule(),
getGenericEnvironment(),
return ArchetypeBuilder::mapTypeOutOfContext(getGenericEnvironment(),
type);
}

View File

@@ -1591,7 +1591,6 @@ static CanAnyFunctionType getDefaultArgGeneratorInterfaceType(
if (auto genTy = funcInfo.FormalInterfaceType->getAs<GenericFunctionType>()) {
sig = genTy->getGenericSignature()->getCanonicalSignature();
resultTy = ArchetypeBuilder::mapTypeOutOfContext(
TC.M.getSwiftModule(),
funcInfo.GenericEnv,
resultTy)->getCanonicalType();
}

View File

@@ -1986,12 +1986,10 @@ getOrCreateReabstractionThunk(GenericEnvironment *genericEnv,
// Substitute context parameters out of the "from" and "to" types.
auto fromInterfaceType
= ArchetypeBuilder::mapTypeOutOfContext(
M.getSwiftModule(), genericEnv, fromType)
= ArchetypeBuilder::mapTypeOutOfContext(genericEnv, fromType)
->getCanonicalType();
auto toInterfaceType
= ArchetypeBuilder::mapTypeOutOfContext(
M.getSwiftModule(), genericEnv, toType)
= ArchetypeBuilder::mapTypeOutOfContext(genericEnv, toType)
->getCanonicalType();
mangler.mangleType(fromInterfaceType, /*uncurry*/ 0);

View File

@@ -138,10 +138,8 @@ void GenericTypeToArchetypeResolver::recordParamType(ParamDecl *decl, Type type)
// When type checking functions, the CompleteGenericTypeResolver sets
// the interface type.
if (!decl->hasInterfaceType())
decl->setInterfaceType(ArchetypeBuilder::mapTypeOutOfContext(
decl->getDeclContext()->getParentModule(),
GenericEnv,
type));
decl->setInterfaceType(ArchetypeBuilder::mapTypeOutOfContext(GenericEnv,
type));
}
Type CompleteGenericTypeResolver::resolveGenericTypeParamType(

View File

@@ -2106,9 +2106,6 @@ Type TypeResolver::resolveASTFunctionType(FunctionTypeRepr *repr,
extInfo = extInfo.withThrows(repr->throws());
ModuleDecl *M = DC->getParentModule();
// If this is a function type without parens around the parameter list,
// diagnose this and produce a fixit to add them.
if (!isa<TupleTypeRepr>(repr->getArgsTypeRepr()) &&
@@ -2127,8 +2124,8 @@ Type TypeResolver::resolveASTFunctionType(FunctionTypeRepr *repr,
if (auto genericEnv = repr->getGenericEnvironment()) {
auto *genericSig = repr->getGenericSignature();
assert(genericSig != nullptr && "Did not call handleSILGenericParams()?");
inputTy = ArchetypeBuilder::mapTypeOutOfContext(M, genericEnv, inputTy);
outputTy = ArchetypeBuilder::mapTypeOutOfContext(M, genericEnv, outputTy);
inputTy = ArchetypeBuilder::mapTypeOutOfContext(genericEnv, inputTy);
outputTy = ArchetypeBuilder::mapTypeOutOfContext(genericEnv, outputTy);
return GenericFunctionType::get(genericSig, inputTy, outputTy, extInfo);
}
@@ -2186,8 +2183,7 @@ Type TypeResolver::resolveSILBoxType(SILBoxTypeRepr *repr,
genericSig = repr->getGenericSignature()->getCanonicalSignature();
for (auto &field : fields) {
auto transTy = genericEnv->mapTypeOutOfContext(DC->getParentModule(),
field.getLoweredType());
auto transTy = genericEnv->mapTypeOutOfContext(field.getLoweredType());
field = {transTy->getCanonicalType(), field.isMutable()};
}
}
@@ -2311,8 +2307,6 @@ Type TypeResolver::resolveSILFunctionType(FunctionTypeRepr *repr,
return ErrorType::get(Context);
}
ModuleDecl *M = DC->getParentModule();
// FIXME: Remap the parsed context types to interface types.
CanGenericSignature genericSig;
SmallVector<SILParameterInfo, 4> interfaceParams;
@@ -2323,19 +2317,19 @@ Type TypeResolver::resolveSILFunctionType(FunctionTypeRepr *repr,
for (auto &param : params) {
auto transParamType = ArchetypeBuilder::mapTypeOutOfContext(
M, genericEnv, param.getType())->getCanonicalType();
genericEnv, param.getType())->getCanonicalType();
interfaceParams.push_back(param.getWithType(transParamType));
}
for (auto &result : results) {
auto transResultType =
ArchetypeBuilder::mapTypeOutOfContext(
M, genericEnv, result.getType())->getCanonicalType();
genericEnv, result.getType())->getCanonicalType();
interfaceResults.push_back(result.getWithType(transResultType));
}
if (errorResult) {
auto transErrorResultType = ArchetypeBuilder::mapTypeOutOfContext(
M, genericEnv, errorResult->getType())->getCanonicalType();
genericEnv, errorResult->getType())->getCanonicalType();
interfaceErrorResult =
errorResult->getWithType(transErrorResultType);
}

View File

@@ -863,8 +863,8 @@ void Serializer::writePattern(const Pattern *pattern, DeclContext *owningDC) {
// If we have an owning context and a contextual type, map out to an
// interface type.
if (owningDC && type->hasArchetype()) {
type = owningDC->getGenericEnvironmentOfContext()->mapTypeOutOfContext(
owningDC->getParentModule(), type);
type = owningDC->getGenericEnvironmentOfContext()
->mapTypeOutOfContext(type);
}
return type;
@@ -1260,7 +1260,7 @@ Serializer::writeConformance(ProtocolConformanceRef conformanceRef,
unsigned abbrCode = abbrCodes[SpecializedProtocolConformanceLayout::Code];
auto type = conf->getType();
if (genericEnv)
type = genericEnv->mapTypeOutOfContext(const_cast<ModuleDecl *>(M), type);
type = genericEnv->mapTypeOutOfContext(type);
SpecializedProtocolConformanceLayout::emitRecord(Out, ScratchRecord,
abbrCode,
addTypeRef(type),
@@ -1278,7 +1278,7 @@ Serializer::writeConformance(ProtocolConformanceRef conformanceRef,
auto type = conf->getType();
if (genericEnv)
type = genericEnv->mapTypeOutOfContext(const_cast<ModuleDecl *>(M), type);
type = genericEnv->mapTypeOutOfContext(type);
InheritedProtocolConformanceLayout::emitRecord(
Out, ScratchRecord, abbrCode, addTypeRef(type));
@@ -1318,8 +1318,7 @@ Serializer::writeSubstitutions(ArrayRef<Substitution> substitutions,
auto replacementType = sub.getReplacement();
if (genericEnv) {
replacementType =
genericEnv->mapTypeOutOfContext(const_cast<ModuleDecl *>(M),
replacementType);
genericEnv->mapTypeOutOfContext(replacementType);
}
BoundGenericSubstitutionLayout::emitRecord(
@@ -2359,9 +2358,7 @@ void Serializer::writeDecl(const Decl *D) {
underlying = typeAlias->getUnderlyingType();
if (underlying->hasArchetype()) {
auto genericEnv = typeAlias->getGenericEnvironmentOfContext();
underlying = genericEnv->mapTypeOutOfContext(
typeAlias->getModuleContext(),
underlying);
underlying = genericEnv->mapTypeOutOfContext(underlying);
}
}