Skip to content
Merged
8 changes: 0 additions & 8 deletions SwiftCompilerSources/Sources/AST/Type.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,6 @@ public struct Type: TypeProperties, CustomStringConvertible, NoReflectionChildre
public func subst(with substitutionMap: SubstitutionMap) -> Type {
return Type(bridged: bridged.subst(substitutionMap.bridged))
}

public func subst(type: Type, with targetType: Type) -> Type {
return Type(bridged: bridged.subst(type.bridged, targetType.bridged))
}
}

/// A Type that is statically known to be canonical.
Expand All @@ -88,10 +84,6 @@ public struct CanonicalType: TypeProperties, CustomStringConvertible, NoReflecti
public func subst(with substitutionMap: SubstitutionMap) -> CanonicalType {
return rawType.subst(with: substitutionMap).canonical
}

public func subst(type: CanonicalType, with targetType: CanonicalType) -> CanonicalType {
return self.rawType.subst(type: type.rawType, with: targetType.rawType).canonical
}
}

/// Implements the common members of `AST.Type`, `AST.CanonicalType` and `SIL.Type`.
Expand Down
1 change: 0 additions & 1 deletion include/swift/AST/ASTBridging.h
Original file line number Diff line number Diff line change
Expand Up @@ -3115,7 +3115,6 @@ struct BridgedASTType {
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedSubstitutionMap getContextSubstitutionMap() const;
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedGenericSignature getInvocationGenericSignatureOfFunctionType() const;
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedASTType subst(BridgedSubstitutionMap substMap) const;
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedASTType subst(BridgedASTType fromType, BridgedASTType toType) const;
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedConformance checkConformance(BridgedDeclObj proto) const;
};

Expand Down
11 changes: 0 additions & 11 deletions include/swift/AST/ASTBridgingImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -596,17 +596,6 @@ BridgedASTType BridgedASTType::subst(BridgedSubstitutionMap substMap) const {
return {unbridged().subst(substMap.unbridged()).getPointer()};
}


BridgedASTType BridgedASTType::subst(BridgedASTType fromType, BridgedASTType toType) const {
auto *fromTy = fromType.unbridged()->castTo<swift::SubstitutableType>();
swift::Type toTy = toType.unbridged();
return {unbridged().subst([fromTy, toTy](swift::SubstitutableType *t) -> swift::Type {
if (t == fromTy)
return toTy;
return t;
}, swift::LookUpConformanceInModule(), swift::SubstFlags::SubstituteLocalArchetypes).getPointer()};
}

BridgedConformance BridgedASTType::checkConformance(BridgedDeclObj proto) const {
return swift::checkConformance(unbridged(), proto.getAs<swift::ProtocolDecl>(), /*allowMissing=*/ false);
}
Expand Down
3 changes: 3 additions & 0 deletions include/swift/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -1051,6 +1051,9 @@ class ASTContext final {
const CanType TheUnconstrainedAnyType; /// This is 'any ~Copyable & ~Escapable',
/// the empty protocol composition
/// without any implicit constraints.
const CanGenericTypeParamType TheSelfType; /// The protocol 'Self' type;
/// a generic parameter with
/// depth 0 index 0
#define SINGLETON_TYPE(SHORT_ID, ID) \
const CanType The##SHORT_ID##Type;
#include "swift/AST/TypeNodes.def"
Expand Down
3 changes: 1 addition & 2 deletions include/swift/AST/InFlightSubstitution.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ class InFlightSubstitution {
Type substType(SubstitutableType *origType, unsigned level);

/// Perform primitive conformance lookup on the given type.
ProtocolConformanceRef lookupConformance(CanType dependentType,
Type conformingReplacementType,
ProtocolConformanceRef lookupConformance(Type dependentType,
ProtocolDecl *conformedProtocol,
unsigned level);

Expand Down
6 changes: 0 additions & 6 deletions include/swift/AST/SubstitutionMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,6 @@ class SubstitutionMap {
/// subsystem.
SubstitutionMap subst(InFlightSubstitution &subs) const;

/// Apply type expansion lowering to all types in the substitution map. Opaque
/// archetypes will be lowered to their underlying types if the type expansion
/// context allows.
SubstitutionMap mapIntoTypeExpansionContext(
TypeExpansionContext context) const;

/// Create a substitution map for a protocol conformance.
static SubstitutionMap
getProtocolSubstitutions(ProtocolConformanceRef conformance);
Expand Down
32 changes: 32 additions & 0 deletions include/swift/AST/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -5032,9 +5032,15 @@ Type substOpaqueTypesWithUnderlyingTypes(Type type,

CanType substOpaqueTypesWithUnderlyingTypes(CanType type,
TypeExpansionContext context);

ProtocolConformanceRef
substOpaqueTypesWithUnderlyingTypes(ProtocolConformanceRef ref,
TypeExpansionContext context);

SubstitutionMap
substOpaqueTypesWithUnderlyingTypes(SubstitutionMap subs,
TypeExpansionContext context);

namespace Lowering {
class TypeConverter;
}
Expand Down Expand Up @@ -7082,6 +7088,32 @@ class ReplaceOpaqueTypesWithUnderlyingTypes {
bool isWholeModule() const { return inContextAndIsWholeModule.getInt(); }
};

/// A function object that can be used as a \c TypeSubstitutionFn and
/// \c LookupConformanceFn for \c Type::subst style APIs to map existential
/// archetypes in the given generic environment to known concrete types from
/// the given substitution map.
class ReplaceExistentialArchetypesWithConcreteTypes {
private:
GenericEnvironment *env;
SubstitutionMap subs;

Type getInterfaceType(ExistentialArchetypeType *type) const;

public:
ReplaceExistentialArchetypesWithConcreteTypes(GenericEnvironment *env,
SubstitutionMap subs)
: env(env), subs(subs) {}

/// TypeSubstitutionFn
Type operator()(SubstitutableType *type) const;

/// LookupConformanceFn
ProtocolConformanceRef operator()(CanType origType,
Type substType,
ProtocolDecl *protocol) const;

};

/// An archetype that's only valid in a portion of a local context.
class LocalArchetypeType : public ArchetypeType {
protected:
Expand Down
2 changes: 1 addition & 1 deletion include/swift/SIL/SILCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
!context.shouldLookThroughOpaqueTypeArchetypes())
return Subs;

return Subs.mapIntoTypeExpansionContext(context);
return substOpaqueTypesWithUnderlyingTypes(Subs, context);
}

return Subs;
Expand Down
5 changes: 3 additions & 2 deletions lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,8 @@ ASTContext::ASTContext(
TheAnyType(ProtocolCompositionType::theAnyType(*this)),
TheUnconstrainedAnyType(
ProtocolCompositionType::theUnconstrainedAnyType(*this)),
TheSelfType(CanGenericTypeParamType(
GenericTypeParamType::getType(0, 0, *this))),
#define SINGLETON_TYPE(SHORT_ID, ID) \
The##SHORT_ID##Type(new (*this, AllocationArena::Permanent) \
ID##Type(*this)),
Expand Down Expand Up @@ -6639,8 +6641,7 @@ CanGenericSignature ASTContext::getSingleGenericParameterSignature() const {
if (auto theSig = getImpl().SingleGenericParameterSignature)
return theSig;

auto param = GenericTypeParamType::getType(/*depth*/ 0, /*index*/ 0, *this);
auto sig = GenericSignature::get(param, { });
auto sig = GenericSignature::get({TheSelfType}, { });
auto canonicalSig = CanGenericSignature(sig);
getImpl().SingleGenericParameterSignature = canonicalSig;
return canonicalSig;
Expand Down
10 changes: 3 additions & 7 deletions lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ std::string ASTMangler::mangleKeyPathGetterThunkHelper(
sub = sub.transformRec([](Type t) -> std::optional<Type> {
if (auto *openedExistential = t->getAs<ExistentialArchetypeType>()) {
auto &ctx = openedExistential->getASTContext();
return GenericTypeParamType::getType(0, 0, ctx);
return ctx.TheSelfType;
}
return std::nullopt;
});
Expand Down Expand Up @@ -431,7 +431,7 @@ std::string ASTMangler::mangleKeyPathSetterThunkHelper(
sub = sub.transformRec([](Type t) -> std::optional<Type> {
if (auto *openedExistential = t->getAs<ExistentialArchetypeType>()) {
auto &ctx = openedExistential->getASTContext();
return GenericTypeParamType::getType(0, 0, ctx);
return ctx.TheSelfType;
}
return std::nullopt;
});
Expand Down Expand Up @@ -5274,15 +5274,11 @@ static void extractExistentialInverseRequirements(

auto &ctx = PCT->getASTContext();

// Form a parameter referring to the existential's Self.
auto existentialSelf =
GenericTypeParamType::getType(/*depth=*/0, /*index=*/0, ctx);

for (auto ip : PCT->getInverses()) {
auto *proto = ctx.getProtocol(getKnownProtocolKind(ip));
assert(proto);
ASSERT(!getABIDecl(proto) && "can't use @abi on inverse protocols");
inverses.push_back({existentialSelf, proto, SourceLoc()});
inverses.push_back({ctx.TheSelfType, proto, SourceLoc()});
}
}

Expand Down
13 changes: 7 additions & 6 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4334,13 +4334,14 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) {
if (proto && Options.TransformContext) {
auto BaseType = Options.TransformContext->getBaseType();
if (BaseType->getClassOrBoundGenericClass()) {
ResultTy = ResultTy.subst(
[&](Type t) -> Type {
if (t->isEqual(proto->getSelfInterfaceType()))
ResultTy = ResultTy.transformRec(
[&](TypeBase *t) -> std::optional<Type> {
if (isa<DependentMemberType>(t))
return t;
else if (t->isEqual(proto->getSelfInterfaceType()))
return DynamicSelfType::get(t, Ctx);
return t;
},
MakeAbstractConformanceForGenericType());
return std::nullopt;
});
ResultTyLoc = TypeLoc::withoutLoc(ResultTy);
}
}
Expand Down
4 changes: 1 addition & 3 deletions lib/AST/ProtocolConformanceRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,7 @@ ProtocolConformanceRef::subst(InFlightSubstitution &IFS) const {

// Local conformance lookup into the substitution map.
// FIXME: Pack element level?
return IFS.lookupConformance(origType->getCanonicalType(),
origType.subst(IFS), proto,
/*level=*/0);
return IFS.lookupConformance(origType, proto, /*level=*/0);
}

ProtocolConformanceRef ProtocolConformanceRef::mapConformanceOutOfContext() const {
Expand Down
8 changes: 3 additions & 5 deletions lib/AST/RequirementEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ RequirementEnvironment::RequirementEnvironment(
// type.
if (type->isEqual(selfType)) {
if (covariantSelf)
return GenericTypeParamType::getType(/*depth=*/0, /*index=*/0, ctx);
return ctx.TheSelfType;
return substConcreteType;
}
// Other requirement generic parameters map 1:1 with their depth
Expand Down Expand Up @@ -173,8 +173,7 @@ RequirementEnvironment::RequirementEnvironment(
// If the conforming type is a class, add a class-constrained 'Self'
// parameter.
if (covariantSelf) {
auto paramTy = GenericTypeParamType::getType(/*depth=*/0, /*index=*/0, ctx);
genericParamTypes.push_back(paramTy);
genericParamTypes.push_back(ctx.TheSelfType);
}

// Now, add all generic parameters from the conforming type.
Expand All @@ -188,8 +187,7 @@ RequirementEnvironment::RequirementEnvironment(
// Next, add requirements.
SmallVector<Requirement, 2> requirements;
if (covariantSelf) {
auto paramTy = GenericTypeParamType::getType(/*depth=*/0, /*index=*/0, ctx);
Requirement reqt(RequirementKind::Superclass, paramTy, substConcreteType);
Requirement reqt(RequirementKind::Superclass, ctx.TheSelfType, substConcreteType);
requirements.push_back(reqt);
}

Expand Down
4 changes: 2 additions & 2 deletions lib/AST/RequirementMachine/InterfaceType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,11 @@ getTypeForSymbolRange(const Symbol *begin, const Symbol *end,
continue;

case Symbol::Kind::Protocol:
handleRoot(GenericTypeParamType::getType(0, 0, ctx.getASTContext()));
handleRoot(ctx.getASTContext().TheSelfType);
continue;

case Symbol::Kind::AssociatedType:
handleRoot(GenericTypeParamType::getType(0, 0, ctx.getASTContext()));
handleRoot(ctx.getASTContext().TheSelfType);

// An associated type symbol at the root means we have a dependent
// member type rooted at Self; handle the associated type below.
Expand Down
24 changes: 11 additions & 13 deletions lib/AST/SubstitutionMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,14 +174,12 @@ SubstitutionMap SubstitutionMap::get(GenericSignature genericSig,
// Form the stored conformances.
SmallVector<ProtocolConformanceRef, 4> conformances;
for (const auto &req : genericSig.getRequirements()) {
if (req.getKind() != RequirementKind::Conformance) continue;

Type depTy = req.getFirstType();
auto replacement = depTy.subst(IFS);
auto *proto = req.getProtocolDecl();
auto conformance = IFS.lookupConformance(
depTy->getCanonicalType(), replacement, proto, /*level=*/0);
conformances.push_back(conformance);
if (req.getKind() != RequirementKind::Conformance)
continue;

conformances.push_back(
IFS.lookupConformance(
req.getFirstType(), req.getProtocolDecl(), /*level=*/0));
}

return SubstitutionMap(genericSig, types, conformances);
Expand Down Expand Up @@ -653,14 +651,14 @@ bool SubstitutionMap::isIdentity() const {
return !hasNonIdentityReplacement;
}

SubstitutionMap SubstitutionMap::mapIntoTypeExpansionContext(
TypeExpansionContext context) const {
SubstitutionMap swift::substOpaqueTypesWithUnderlyingTypes(
SubstitutionMap subs, TypeExpansionContext context) {
ReplaceOpaqueTypesWithUnderlyingTypes replacer(
context.getContext(), context.getResilienceExpansion(),
context.isWholeModuleContext());
return this->subst(replacer, replacer,
SubstFlags::SubstituteOpaqueArchetypes |
SubstFlags::PreservePackExpansionLevel);
return subs.subst(replacer, replacer,
SubstFlags::SubstituteOpaqueArchetypes |
SubstFlags::PreservePackExpansionLevel);
}

bool OuterSubstitutions::isUnsubstitutedTypeParameter(Type type) const {
Expand Down
Loading