mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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:
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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 ¶m : 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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user