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);
|
static Type mapTypeOutOfContext(const DeclContext *dc, Type type);
|
||||||
|
|
||||||
/// Map a contextual type to an interface type.
|
/// Map a contextual type to an interface type.
|
||||||
static Type mapTypeOutOfContext(ModuleDecl *M,
|
static Type mapTypeOutOfContext(GenericEnvironment *genericEnv,
|
||||||
GenericEnvironment *genericEnv,
|
|
||||||
Type type);
|
Type type);
|
||||||
|
|
||||||
/// \brief Dump all of the requirements, both specified and inferred.
|
/// \brief Dump all of the requirements, both specified and inferred.
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Map a contextual type to an interface type.
|
/// 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.
|
/// Map an interface type to a contextual type.
|
||||||
Type mapTypeIntoContext(ModuleDecl *M, Type type) const;
|
Type mapTypeIntoContext(ModuleDecl *M, Type type) const;
|
||||||
|
|||||||
@@ -105,6 +105,17 @@ public:
|
|||||||
ProtocolType *conformedProtocol) const;
|
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.
|
/// Flags that can be passed when substituting into a type.
|
||||||
enum class SubstFlags {
|
enum class SubstFlags {
|
||||||
/// If a type cannot be produced because some member type is
|
/// 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.
|
// Map the type out of its context.
|
||||||
if (auto genericEnv = alias->getGenericEnvironmentOfContext()) {
|
if (auto genericEnv = alias->getGenericEnvironmentOfContext()) {
|
||||||
type = genericEnv->mapTypeOutOfContext(alias->getModuleContext(),
|
type = genericEnv->mapTypeOutOfContext(type);
|
||||||
type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto existingPA = builder.resolveArchetype(type)) {
|
if (auto existingPA = builder.resolveArchetype(type)) {
|
||||||
@@ -688,8 +687,7 @@ void ArchetypeType::resolveNestedType(
|
|||||||
auto &builder = *genericEnv->getArchetypeBuilder();
|
auto &builder = *genericEnv->getArchetypeBuilder();
|
||||||
|
|
||||||
Type interfaceType =
|
Type interfaceType =
|
||||||
genericEnv->mapTypeOutOfContext(&builder.getModule(),
|
genericEnv->mapTypeOutOfContext(const_cast<ArchetypeType *>(this));
|
||||||
const_cast<ArchetypeType *>(this));
|
|
||||||
auto parentPA = builder.resolveArchetype(interfaceType);
|
auto parentPA = builder.resolveArchetype(interfaceType);
|
||||||
auto memberPA = parentPA->getNestedType(nested.first, builder);
|
auto memberPA = parentPA->getNestedType(nested.first, builder);
|
||||||
auto result = memberPA->getTypeInContext(builder, genericEnv);
|
auto result = memberPA->getTypeInContext(builder, genericEnv);
|
||||||
@@ -1975,14 +1973,12 @@ Type ArchetypeBuilder::mapTypeIntoContext(ModuleDecl *M,
|
|||||||
|
|
||||||
Type
|
Type
|
||||||
ArchetypeBuilder::mapTypeOutOfContext(const DeclContext *dc, Type type) {
|
ArchetypeBuilder::mapTypeOutOfContext(const DeclContext *dc, Type type) {
|
||||||
return mapTypeOutOfContext(dc->getParentModule(),
|
return mapTypeOutOfContext(dc->getGenericEnvironmentOfContext(),
|
||||||
dc->getGenericEnvironmentOfContext(),
|
|
||||||
type);
|
type);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type
|
Type
|
||||||
ArchetypeBuilder::mapTypeOutOfContext(ModuleDecl *M,
|
ArchetypeBuilder::mapTypeOutOfContext(GenericEnvironment *env,
|
||||||
GenericEnvironment *env,
|
|
||||||
Type type) {
|
Type type) {
|
||||||
auto canType = type->getCanonicalType();
|
auto canType = type->getCanonicalType();
|
||||||
assert(!canType->hasTypeParameter() && "already have an interface type");
|
assert(!canType->hasTypeParameter() && "already have an interface type");
|
||||||
@@ -1991,7 +1987,7 @@ ArchetypeBuilder::mapTypeOutOfContext(ModuleDecl *M,
|
|||||||
|
|
||||||
assert(env && "dependent type in non-generic context");
|
assert(env && "dependent type in non-generic context");
|
||||||
|
|
||||||
return env->mapTypeOutOfContext(M, type);
|
return env->mapTypeOutOfContext(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArchetypeBuilder::addGenericSignature(GenericSignature *sig) {
|
void ArchetypeBuilder::addGenericSignature(GenericSignature *sig) {
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ Type DeclContext::mapTypeIntoContext(Type type) const {
|
|||||||
|
|
||||||
Type DeclContext::mapTypeOutOfContext(Type type) const {
|
Type DeclContext::mapTypeOutOfContext(Type type) const {
|
||||||
if (auto genericEnv = getGenericEnvironmentOfContext())
|
if (auto genericEnv = getGenericEnvironmentOfContext())
|
||||||
return genericEnv->mapTypeOutOfContext(getParentModule(), type);
|
return genericEnv->mapTypeOutOfContext(type);
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,9 +142,9 @@ bool GenericEnvironment::containsPrimaryArchetype(
|
|||||||
QueryArchetypeToInterfaceSubstitutions(this)(archetype));
|
QueryArchetypeToInterfaceSubstitutions(this)(archetype));
|
||||||
}
|
}
|
||||||
|
|
||||||
Type GenericEnvironment::mapTypeOutOfContext(ModuleDecl *M, Type type) const {
|
Type GenericEnvironment::mapTypeOutOfContext(Type type) const {
|
||||||
type = type.subst(QueryArchetypeToInterfaceSubstitutions(this),
|
type = type.subst(QueryArchetypeToInterfaceSubstitutions(this),
|
||||||
LookUpConformanceInModule(M),
|
MakeAbstractConformanceForGenericType(),
|
||||||
SubstFlags::AllowLoweredTypes);
|
SubstFlags::AllowLoweredTypes);
|
||||||
assert(!type->hasArchetype() && "not fully substituted");
|
assert(!type->hasArchetype() && "not fully substituted");
|
||||||
return type;
|
return type;
|
||||||
|
|||||||
@@ -2892,6 +2892,16 @@ LookUpConformanceInSubstitutionMap::operator()(CanType dependentType,
|
|||||||
return Subs.lookupConformance(dependentType, conformedProtocol->getDecl());
|
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 DependentMemberType::substBaseType(ModuleDecl *module,
|
||||||
Type substBase,
|
Type substBase,
|
||||||
LazyResolver *resolver) {
|
LazyResolver *resolver) {
|
||||||
|
|||||||
@@ -277,8 +277,7 @@ SILType GenericEnvironment::mapTypeIntoContext(SILModule &M,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Type SILFunction::mapTypeOutOfContext(Type type) const {
|
Type SILFunction::mapTypeOutOfContext(Type type) const {
|
||||||
return ArchetypeBuilder::mapTypeOutOfContext(getModule().getSwiftModule(),
|
return ArchetypeBuilder::mapTypeOutOfContext(getGenericEnvironment(),
|
||||||
getGenericEnvironment(),
|
|
||||||
type);
|
type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1591,7 +1591,6 @@ static CanAnyFunctionType getDefaultArgGeneratorInterfaceType(
|
|||||||
if (auto genTy = funcInfo.FormalInterfaceType->getAs<GenericFunctionType>()) {
|
if (auto genTy = funcInfo.FormalInterfaceType->getAs<GenericFunctionType>()) {
|
||||||
sig = genTy->getGenericSignature()->getCanonicalSignature();
|
sig = genTy->getGenericSignature()->getCanonicalSignature();
|
||||||
resultTy = ArchetypeBuilder::mapTypeOutOfContext(
|
resultTy = ArchetypeBuilder::mapTypeOutOfContext(
|
||||||
TC.M.getSwiftModule(),
|
|
||||||
funcInfo.GenericEnv,
|
funcInfo.GenericEnv,
|
||||||
resultTy)->getCanonicalType();
|
resultTy)->getCanonicalType();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1986,12 +1986,10 @@ getOrCreateReabstractionThunk(GenericEnvironment *genericEnv,
|
|||||||
|
|
||||||
// Substitute context parameters out of the "from" and "to" types.
|
// Substitute context parameters out of the "from" and "to" types.
|
||||||
auto fromInterfaceType
|
auto fromInterfaceType
|
||||||
= ArchetypeBuilder::mapTypeOutOfContext(
|
= ArchetypeBuilder::mapTypeOutOfContext(genericEnv, fromType)
|
||||||
M.getSwiftModule(), genericEnv, fromType)
|
|
||||||
->getCanonicalType();
|
->getCanonicalType();
|
||||||
auto toInterfaceType
|
auto toInterfaceType
|
||||||
= ArchetypeBuilder::mapTypeOutOfContext(
|
= ArchetypeBuilder::mapTypeOutOfContext(genericEnv, toType)
|
||||||
M.getSwiftModule(), genericEnv, toType)
|
|
||||||
->getCanonicalType();
|
->getCanonicalType();
|
||||||
|
|
||||||
mangler.mangleType(fromInterfaceType, /*uncurry*/ 0);
|
mangler.mangleType(fromInterfaceType, /*uncurry*/ 0);
|
||||||
|
|||||||
@@ -138,9 +138,7 @@ void GenericTypeToArchetypeResolver::recordParamType(ParamDecl *decl, Type type)
|
|||||||
// When type checking functions, the CompleteGenericTypeResolver sets
|
// When type checking functions, the CompleteGenericTypeResolver sets
|
||||||
// the interface type.
|
// the interface type.
|
||||||
if (!decl->hasInterfaceType())
|
if (!decl->hasInterfaceType())
|
||||||
decl->setInterfaceType(ArchetypeBuilder::mapTypeOutOfContext(
|
decl->setInterfaceType(ArchetypeBuilder::mapTypeOutOfContext(GenericEnv,
|
||||||
decl->getDeclContext()->getParentModule(),
|
|
||||||
GenericEnv,
|
|
||||||
type));
|
type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2106,9 +2106,6 @@ Type TypeResolver::resolveASTFunctionType(FunctionTypeRepr *repr,
|
|||||||
|
|
||||||
extInfo = extInfo.withThrows(repr->throws());
|
extInfo = extInfo.withThrows(repr->throws());
|
||||||
|
|
||||||
ModuleDecl *M = DC->getParentModule();
|
|
||||||
|
|
||||||
|
|
||||||
// If this is a function type without parens around the parameter list,
|
// If this is a function type without parens around the parameter list,
|
||||||
// diagnose this and produce a fixit to add them.
|
// diagnose this and produce a fixit to add them.
|
||||||
if (!isa<TupleTypeRepr>(repr->getArgsTypeRepr()) &&
|
if (!isa<TupleTypeRepr>(repr->getArgsTypeRepr()) &&
|
||||||
@@ -2127,8 +2124,8 @@ Type TypeResolver::resolveASTFunctionType(FunctionTypeRepr *repr,
|
|||||||
if (auto genericEnv = repr->getGenericEnvironment()) {
|
if (auto genericEnv = repr->getGenericEnvironment()) {
|
||||||
auto *genericSig = repr->getGenericSignature();
|
auto *genericSig = repr->getGenericSignature();
|
||||||
assert(genericSig != nullptr && "Did not call handleSILGenericParams()?");
|
assert(genericSig != nullptr && "Did not call handleSILGenericParams()?");
|
||||||
inputTy = ArchetypeBuilder::mapTypeOutOfContext(M, genericEnv, inputTy);
|
inputTy = ArchetypeBuilder::mapTypeOutOfContext(genericEnv, inputTy);
|
||||||
outputTy = ArchetypeBuilder::mapTypeOutOfContext(M, genericEnv, outputTy);
|
outputTy = ArchetypeBuilder::mapTypeOutOfContext(genericEnv, outputTy);
|
||||||
return GenericFunctionType::get(genericSig, inputTy, outputTy, extInfo);
|
return GenericFunctionType::get(genericSig, inputTy, outputTy, extInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2186,8 +2183,7 @@ Type TypeResolver::resolveSILBoxType(SILBoxTypeRepr *repr,
|
|||||||
genericSig = repr->getGenericSignature()->getCanonicalSignature();
|
genericSig = repr->getGenericSignature()->getCanonicalSignature();
|
||||||
|
|
||||||
for (auto &field : fields) {
|
for (auto &field : fields) {
|
||||||
auto transTy = genericEnv->mapTypeOutOfContext(DC->getParentModule(),
|
auto transTy = genericEnv->mapTypeOutOfContext(field.getLoweredType());
|
||||||
field.getLoweredType());
|
|
||||||
field = {transTy->getCanonicalType(), field.isMutable()};
|
field = {transTy->getCanonicalType(), field.isMutable()};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2311,8 +2307,6 @@ Type TypeResolver::resolveSILFunctionType(FunctionTypeRepr *repr,
|
|||||||
return ErrorType::get(Context);
|
return ErrorType::get(Context);
|
||||||
}
|
}
|
||||||
|
|
||||||
ModuleDecl *M = DC->getParentModule();
|
|
||||||
|
|
||||||
// FIXME: Remap the parsed context types to interface types.
|
// FIXME: Remap the parsed context types to interface types.
|
||||||
CanGenericSignature genericSig;
|
CanGenericSignature genericSig;
|
||||||
SmallVector<SILParameterInfo, 4> interfaceParams;
|
SmallVector<SILParameterInfo, 4> interfaceParams;
|
||||||
@@ -2323,19 +2317,19 @@ Type TypeResolver::resolveSILFunctionType(FunctionTypeRepr *repr,
|
|||||||
|
|
||||||
for (auto ¶m : params) {
|
for (auto ¶m : params) {
|
||||||
auto transParamType = ArchetypeBuilder::mapTypeOutOfContext(
|
auto transParamType = ArchetypeBuilder::mapTypeOutOfContext(
|
||||||
M, genericEnv, param.getType())->getCanonicalType();
|
genericEnv, param.getType())->getCanonicalType();
|
||||||
interfaceParams.push_back(param.getWithType(transParamType));
|
interfaceParams.push_back(param.getWithType(transParamType));
|
||||||
}
|
}
|
||||||
for (auto &result : results) {
|
for (auto &result : results) {
|
||||||
auto transResultType =
|
auto transResultType =
|
||||||
ArchetypeBuilder::mapTypeOutOfContext(
|
ArchetypeBuilder::mapTypeOutOfContext(
|
||||||
M, genericEnv, result.getType())->getCanonicalType();
|
genericEnv, result.getType())->getCanonicalType();
|
||||||
interfaceResults.push_back(result.getWithType(transResultType));
|
interfaceResults.push_back(result.getWithType(transResultType));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errorResult) {
|
if (errorResult) {
|
||||||
auto transErrorResultType = ArchetypeBuilder::mapTypeOutOfContext(
|
auto transErrorResultType = ArchetypeBuilder::mapTypeOutOfContext(
|
||||||
M, genericEnv, errorResult->getType())->getCanonicalType();
|
genericEnv, errorResult->getType())->getCanonicalType();
|
||||||
interfaceErrorResult =
|
interfaceErrorResult =
|
||||||
errorResult->getWithType(transErrorResultType);
|
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
|
// If we have an owning context and a contextual type, map out to an
|
||||||
// interface type.
|
// interface type.
|
||||||
if (owningDC && type->hasArchetype()) {
|
if (owningDC && type->hasArchetype()) {
|
||||||
type = owningDC->getGenericEnvironmentOfContext()->mapTypeOutOfContext(
|
type = owningDC->getGenericEnvironmentOfContext()
|
||||||
owningDC->getParentModule(), type);
|
->mapTypeOutOfContext(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
@@ -1260,7 +1260,7 @@ Serializer::writeConformance(ProtocolConformanceRef conformanceRef,
|
|||||||
unsigned abbrCode = abbrCodes[SpecializedProtocolConformanceLayout::Code];
|
unsigned abbrCode = abbrCodes[SpecializedProtocolConformanceLayout::Code];
|
||||||
auto type = conf->getType();
|
auto type = conf->getType();
|
||||||
if (genericEnv)
|
if (genericEnv)
|
||||||
type = genericEnv->mapTypeOutOfContext(const_cast<ModuleDecl *>(M), type);
|
type = genericEnv->mapTypeOutOfContext(type);
|
||||||
SpecializedProtocolConformanceLayout::emitRecord(Out, ScratchRecord,
|
SpecializedProtocolConformanceLayout::emitRecord(Out, ScratchRecord,
|
||||||
abbrCode,
|
abbrCode,
|
||||||
addTypeRef(type),
|
addTypeRef(type),
|
||||||
@@ -1278,7 +1278,7 @@ Serializer::writeConformance(ProtocolConformanceRef conformanceRef,
|
|||||||
|
|
||||||
auto type = conf->getType();
|
auto type = conf->getType();
|
||||||
if (genericEnv)
|
if (genericEnv)
|
||||||
type = genericEnv->mapTypeOutOfContext(const_cast<ModuleDecl *>(M), type);
|
type = genericEnv->mapTypeOutOfContext(type);
|
||||||
|
|
||||||
InheritedProtocolConformanceLayout::emitRecord(
|
InheritedProtocolConformanceLayout::emitRecord(
|
||||||
Out, ScratchRecord, abbrCode, addTypeRef(type));
|
Out, ScratchRecord, abbrCode, addTypeRef(type));
|
||||||
@@ -1318,8 +1318,7 @@ Serializer::writeSubstitutions(ArrayRef<Substitution> substitutions,
|
|||||||
auto replacementType = sub.getReplacement();
|
auto replacementType = sub.getReplacement();
|
||||||
if (genericEnv) {
|
if (genericEnv) {
|
||||||
replacementType =
|
replacementType =
|
||||||
genericEnv->mapTypeOutOfContext(const_cast<ModuleDecl *>(M),
|
genericEnv->mapTypeOutOfContext(replacementType);
|
||||||
replacementType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BoundGenericSubstitutionLayout::emitRecord(
|
BoundGenericSubstitutionLayout::emitRecord(
|
||||||
@@ -2359,9 +2358,7 @@ void Serializer::writeDecl(const Decl *D) {
|
|||||||
underlying = typeAlias->getUnderlyingType();
|
underlying = typeAlias->getUnderlyingType();
|
||||||
if (underlying->hasArchetype()) {
|
if (underlying->hasArchetype()) {
|
||||||
auto genericEnv = typeAlias->getGenericEnvironmentOfContext();
|
auto genericEnv = typeAlias->getGenericEnvironmentOfContext();
|
||||||
underlying = genericEnv->mapTypeOutOfContext(
|
underlying = genericEnv->mapTypeOutOfContext(underlying);
|
||||||
typeAlias->getModuleContext(),
|
|
||||||
underlying);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user