Skip to content

Begin groundwork for storing conformances inside generic signatures #7319

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions include/swift/AST/GenericEnvironment.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,7 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
}

/// Map an interface type to a contextual type.
static Type mapTypeIntoContext(ModuleDecl *M,
GenericEnvironment *genericEnv,
static Type mapTypeIntoContext(GenericEnvironment *genericEnv,
Type type);

/// Map a contextual type to an interface type.
Expand All @@ -207,7 +206,7 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
Type mapTypeOutOfContext(Type type) const;

/// Map an interface type to a contextual type.
Type mapTypeIntoContext(ModuleDecl *M, Type type) const;
Type mapTypeIntoContext(Type type) const;

/// Map an interface type to a contextual type.
Type mapTypeIntoContext(Type type,
Expand Down
14 changes: 14 additions & 0 deletions include/swift/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,20 @@ class MakeAbstractConformanceForGenericType {
ProtocolType *conformedProtocol) const;
};

/// Functor class suitable for use as a \c LookupConformanceFn that fetches
/// conformances from a generic signature.
class LookUpConformanceInSignature {
const GenericSignature &Sig;
public:
LookUpConformanceInSignature(const GenericSignature &Sig)
: Sig(Sig) {}

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
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2051,7 +2051,7 @@ static Type computeNominalType(NominalTypeDecl *decl, DeclTypeKind kind) {

auto *genericEnv = decl->getGenericEnvironmentOfContext();
return GenericEnvironment::mapTypeIntoContext(
decl->getModuleContext(), genericEnv, interfaceType);
genericEnv, interfaceType);
}

// Get the parent type.
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/DeclContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ GenericEnvironment *DeclContext::getGenericEnvironmentOfContext() const {

Type DeclContext::mapTypeIntoContext(Type type) const {
return GenericEnvironment::mapTypeIntoContext(
getParentModule(), getGenericEnvironmentOfContext(), type);
getGenericEnvironmentOfContext(), type);
}

Type DeclContext::mapTypeOutOfContext(Type type) const {
Expand Down
10 changes: 5 additions & 5 deletions lib/AST/GenericEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,15 +155,14 @@ bool GenericEnvironment::containsPrimaryArchetype(
QueryArchetypeToInterfaceSubstitutions(this)(archetype));
}

Type GenericEnvironment::mapTypeIntoContext(ModuleDecl *M,
GenericEnvironment *env,
Type GenericEnvironment::mapTypeIntoContext(GenericEnvironment *env,
Type type) {
assert(!type->hasArchetype() && "already have a contextual type");

if (!env)
return type.substDependentTypesWithErrorTypes();

return env->mapTypeIntoContext(M, type);
return env->mapTypeIntoContext(type);
}

Type
Expand Down Expand Up @@ -297,8 +296,9 @@ Type GenericEnvironment::mapTypeIntoContext(

}

Type GenericEnvironment::mapTypeIntoContext(ModuleDecl *M, Type type) const {
return mapTypeIntoContext(type, LookUpConformanceInModule(M));
Type GenericEnvironment::mapTypeIntoContext(Type type) const {
auto *sig = getGenericSignature();
return mapTypeIntoContext(type, LookUpConformanceInSignature(*sig));
}

Type GenericEnvironment::mapTypeIntoContext(GenericTypeParamType *type) const {
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/Pattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ Type Pattern::getType() const {

if (auto genericEnv = dc->getGenericEnvironmentOfContext()) {
ctx.DelayedPatternContexts.erase(this);
Ty = genericEnv->mapTypeIntoContext(dc->getParentModule(), Ty);
Ty = genericEnv->mapTypeIntoContext(Ty);
PatternBits.hasInterfaceType = false;
}
}
Expand Down
19 changes: 17 additions & 2 deletions lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2961,8 +2961,8 @@ LookUpConformanceInModule::operator()(CanType dependentType,
return ProtocolConformanceRef(conformedProtocol->getDecl());

return M->lookupConformance(conformingReplacementType,
conformedProtocol->getDecl(),
conformingReplacementType->getASTContext().getLazyResolver());
conformedProtocol->getDecl(),
M->getASTContext().getLazyResolver());
}

Optional<ProtocolConformanceRef>
Expand All @@ -2982,6 +2982,21 @@ MakeAbstractConformanceForGenericType::operator()(CanType dependentType,
return ProtocolConformanceRef(conformedProtocol->getDecl());
}

Optional<ProtocolConformanceRef>
LookUpConformanceInSignature::operator()(CanType dependentType,
Type conformingReplacementType,
ProtocolType *conformedProtocol) const {
// FIXME: Actually implement this properly.
auto *M = conformedProtocol->getDecl()->getParentModule();

if (conformingReplacementType->isTypeParameter())
return ProtocolConformanceRef(conformedProtocol->getDecl());

return M->lookupConformance(conformingReplacementType,
conformedProtocol->getDecl(),
M->getASTContext().getLazyResolver());
}

Type DependentMemberType::substBaseType(ModuleDecl *module,
Type substBase,
LazyResolver *resolver) {
Expand Down
2 changes: 1 addition & 1 deletion lib/IRGen/GenCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1206,7 +1206,7 @@ void CallEmission::emitToMemory(Address addr,

if (origResultType->hasTypeParameter())
origResultType = IGF.IGM.getGenericEnvironment()
->mapTypeIntoContext(IGF.getSwiftModule(), origResultType)
->mapTypeIntoContext(origResultType)
->getCanonicalType();

if (origResultType != substResultType) {
Expand Down
4 changes: 1 addition & 3 deletions lib/IRGen/GenPoly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@ static SILType applyContextArchetypes(IRGenFunction &IGF,

auto substType =
IGF.IGM.getGenericEnvironment()->mapTypeIntoContext(
IGF.getSwiftModule(),
type.getSwiftRValueType())

type.getSwiftRValueType())
->getCanonicalType();
return SILType::getPrimitiveType(substType, type.getCategory());
}
Expand Down
2 changes: 1 addition & 1 deletion lib/IRGen/GenType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -960,7 +960,7 @@ ArchetypeType *TypeConverter::getExemplarArchetype(ArchetypeType *t) {
// Map the archetype out of its own generic environment and into the
// canonical generic environment.
auto interfaceType = genericEnv->mapTypeOutOfContext(t);
auto exemplar = canGenericEnv->mapTypeIntoContext(module, interfaceType)
auto exemplar = canGenericEnv->mapTypeIntoContext(interfaceType)
->castTo<ArchetypeType>();
assert(isExemplarArchetype(exemplar));
return exemplar;
Expand Down
6 changes: 2 additions & 4 deletions lib/SIL/SILFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,7 @@ bool SILFunction::shouldOptimize() const {

Type SILFunction::mapTypeIntoContext(Type type) const {
return GenericEnvironment::mapTypeIntoContext(
getModule().getSwiftModule(),
getGenericEnvironment(),
type);
getGenericEnvironment(), type);
}

namespace {
Expand Down Expand Up @@ -259,7 +257,7 @@ SILType GenericEnvironment::mapTypeIntoContext(SILModule &M,
SILType type) const {
return doSubstDependentSILType(M,
[&](CanType t) {
return mapTypeIntoContext(M.getSwiftModule(), t)->getCanonicalType();
return mapTypeIntoContext(t)->getCanonicalType();
},
type);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/SIL/SILType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ SILBoxType::getFieldLoweredType(SILModule &M, unsigned index) const {
.getGenericEnvironment(*M.getSwiftModule());
auto substMap =
env->getSubstitutionMap(getGenericArgs());
fieldTy = env->mapTypeIntoContext(M.getSwiftModule(), fieldTy)
fieldTy = env->mapTypeIntoContext(fieldTy)
->getCanonicalType();

fieldTy = SILType::getPrimitiveObjectType(fieldTy)
Expand Down
9 changes: 4 additions & 5 deletions lib/SIL/TypeLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ namespace {
if (Sig && type->hasTypeParameter()) {
type = Sig->getCanonicalSignature()
.getGenericEnvironment(*M.getSwiftModule())
->mapTypeIntoContext(M.getSwiftModule(), type)
->mapTypeIntoContext(type)
->getCanonicalType();
}

Expand Down Expand Up @@ -2467,11 +2467,10 @@ TypeConverter::getInterfaceBoxTypeForCapture(ValueDecl *captured,
auto contextBoxTy = boxTy;
if (signature) {
auto env = signature.getGenericEnvironment(*M.getSwiftModule());
loweredContextType = env->mapTypeIntoContext(M.getSwiftModule(),
loweredContextType)
loweredContextType = env->mapTypeIntoContext(loweredContextType)
->getCanonicalType();
contextBoxTy = cast<SILBoxType>(
env->mapTypeIntoContext(M.getSwiftModule(), contextBoxTy)
env->mapTypeIntoContext(contextBoxTy)
->getCanonicalType());
}
assert(contextBoxTy->getLayout()->getFields().size() == 1
Expand Down Expand Up @@ -2502,7 +2501,7 @@ TypeConverter::getContextBoxTypeForCapture(ValueDecl *captured,
isMutable);
if (env)
boxType = cast<SILBoxType>(
env->mapTypeIntoContext(M.getSwiftModule(), boxType)
env->mapTypeIntoContext(boxType)
->getCanonicalType());

return boxType;
Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1922,7 +1922,7 @@ SILGenModule::emitProtocolWitness(ProtocolConformance *conformance,
}

selfType = GenericEnvironment::mapTypeIntoContext(
M.getSwiftModule(), genericEnv, selfInterfaceType);
genericEnv, selfInterfaceType);
}

SILGenFunction gen(*this, *f);
Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGenPoly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2513,7 +2513,7 @@ buildThunkSignature(SILGenFunction &gen,
contextSubs = calleeGenericEnv->getSubstitutionMap(
[&](SubstitutableType *type) -> Type {
auto depTy = calleeGenericEnv->mapTypeOutOfContext(type);
return genericEnv->mapTypeIntoContext(mod, depTy);
return genericEnv->mapTypeIntoContext(depTy);
},
MakeAbstractConformanceForGenericType());
}
Expand Down
3 changes: 1 addition & 2 deletions lib/SILGen/SILGenProlog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,7 @@ static void emitCaptureArguments(SILGenFunction &gen,
// non-canonical types in that context. We need the original generic
// environment from the AST for that.
auto genericEnv = closure.getGenericEnvironment();
return genericEnv->mapTypeIntoContext(gen.F.getModule().getSwiftModule(),
interfaceType);
return genericEnv->mapTypeIntoContext(interfaceType);
};

switch (gen.SGM.Types.getDeclCaptureKind(capture)) {
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/TypeCheckDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7411,7 +7411,7 @@ checkExtensionGenericParams(TypeChecker &tc, ExtensionDecl *ext, Type type,
});

Type extContextType =
env->mapTypeIntoContext(ext->getModuleContext(), extInterfaceType);
env->mapTypeIntoContext(extInterfaceType);
return { env, extContextType };
}

Expand Down
6 changes: 2 additions & 4 deletions lib/Sema/TypeCheckGeneric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,12 @@ Type GenericTypeToArchetypeResolver::resolveSelfAssociatedType(

Type GenericTypeToArchetypeResolver::resolveTypeOfContext(DeclContext *dc) {
return GenericEnvironment::mapTypeIntoContext(
dc->getParentModule(), GenericEnv,
dc->getSelfInterfaceType());
GenericEnv, dc->getSelfInterfaceType());
}

Type GenericTypeToArchetypeResolver::resolveTypeOfDecl(TypeDecl *decl) {
return GenericEnvironment::mapTypeIntoContext(
decl->getDeclContext()->getParentModule(), GenericEnv,
decl->getDeclaredInterfaceType());
GenericEnv, decl->getDeclaredInterfaceType());
}

bool GenericTypeToArchetypeResolver::areSameType(Type type1, Type type2) {
Expand Down
6 changes: 2 additions & 4 deletions lib/Sema/TypeCheckProtocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1191,8 +1191,7 @@ matchWitness(TypeChecker &tc,
auto reqGenericEnv = reqEnvironment.getSyntheticEnvironment();
Type selfTy = proto->getSelfInterfaceType().subst(reqSubs);
if (reqGenericEnv)
selfTy = reqGenericEnv->mapTypeIntoContext(dc->getParentModule(),
selfTy);
selfTy = reqGenericEnv->mapTypeIntoContext(selfTy);

// Open up the type of the requirement.
reqLocator = cs->getConstraintLocator(
Expand Down Expand Up @@ -1220,8 +1219,7 @@ matchWitness(TypeChecker &tc,
continue;

if (reqGenericEnv) {
replacedInReq = reqGenericEnv->mapTypeIntoContext(dc->getParentModule(),
replacedInReq);
replacedInReq = reqGenericEnv->mapTypeIntoContext(replacedInReq);
}

cs->addConstraint(ConstraintKind::Bind, replacement.second, replacedInReq,
Expand Down
9 changes: 3 additions & 6 deletions lib/Serialization/Deserialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -564,8 +564,7 @@ ProtocolConformanceRef ModuleFile::readConformance(
ASTContext &ctx = getContext();
Type conformingType = getType(conformingTypeID);
if (genericEnv) {
conformingType = genericEnv->mapTypeIntoContext(getAssociatedModule(),
conformingType);
conformingType = genericEnv->mapTypeIntoContext(conformingType);
}

PrettyStackTraceType trace(getAssociatedModule()->getASTContext(),
Expand Down Expand Up @@ -599,8 +598,7 @@ ProtocolConformanceRef ModuleFile::readConformance(
ASTContext &ctx = getContext();
Type conformingType = getType(conformingTypeID);
if (genericEnv) {
conformingType = genericEnv->mapTypeIntoContext(getAssociatedModule(),
conformingType);
conformingType = genericEnv->mapTypeIntoContext(conformingType);
}

PrettyStackTraceType trace(getAssociatedModule()->getASTContext(),
Expand Down Expand Up @@ -761,8 +759,7 @@ ModuleFile::maybeReadSubstitution(llvm::BitstreamCursor &cursor,

auto replacementTy = getType(replacementID);
if (genericEnv) {
replacementTy = genericEnv->mapTypeIntoContext(getAssociatedModule(),
replacementTy);
replacementTy = genericEnv->mapTypeIntoContext(replacementTy);
}

SmallVector<ProtocolConformanceRef, 4> conformanceBuf;
Expand Down