Skip to content

Commit e544d36

Browse files
authored
Merge pull request swiftlang#28424 from jckarter/subst-function-type-reabstraction
SIL: Plumb abstraction patterns through type lowering.
2 parents 98dcc5e + 0926d23 commit e544d36

25 files changed

+1012
-833
lines changed

include/swift/AST/Types.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,7 +877,19 @@ class alignas(1 << TypeAlignInBits) TypeBase {
877877
/// True if this type contains archetypes that could be substituted with
878878
/// concrete types to form the argument type.
879879
bool isBindableTo(Type ty);
880+
881+
/// Visit this type and the argument type in parallel, invoking the callback
882+
/// function with each archetype-to-substituted-type binding. The callback
883+
/// may return a new type to substitute into the result type, or return
884+
/// CanType() to error out of the operation.
885+
///
886+
/// Returns the substituted type, or a null CanType() if this type
887+
/// is not bindable to the substituted type, or the callback returns
888+
/// CanType().
889+
CanType substituteBindingsTo(Type ty,
890+
llvm::function_ref<CanType(ArchetypeType*, CanType)> substFn);
880891

892+
881893
/// Determines whether this type is similar to \p other as defined by
882894
/// \p matchOptions.
883895
bool matches(Type other, TypeMatchOptions matchOptions);
@@ -4279,6 +4291,10 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
42794291
SILType substInterfaceType(SILModule &M,
42804292
SILType interfaceType) const;
42814293

4294+
/// Return the unsubstituted function type equivalent to this type; that is, the type that has the same
4295+
/// argument and result types as `this` type after substitutions, if any.
4296+
CanSILFunctionType getUnsubstitutedType(SILModule &M) const;
4297+
42824298
void Profile(llvm::FoldingSetNodeID &ID) {
42834299
Profile(ID, getSubstGenericSignature(), getExtInfo(), getCoroutineKind(),
42844300
getCalleeConvention(), getParameters(), getYields(), getResults(),

include/swift/SIL/AbstractionPattern.h

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,13 @@ class AbstractionPattern {
409409
assert(hasGenericSignature());
410410
return CanGenericSignature(GenericSig);
411411
}
412-
412+
413+
CanGenericSignature getGenericSignatureOrNull() const {
414+
if (!hasGenericSignature())
415+
return CanGenericSignature();
416+
return CanGenericSignature(GenericSig);
417+
}
418+
413419
/// Return an open-coded abstraction pattern for a tuple. The
414420
/// caller is responsible for ensuring that the storage for the
415421
/// tuple elements is valid for as long as the abstraction pattern is.
@@ -513,6 +519,15 @@ class AbstractionPattern {
513519
return pattern;
514520
}
515521

522+
/// Return an abstraction pattern for the type of the given struct field or enum case
523+
/// substituted in `this` type.
524+
///
525+
/// Note that, for most purposes, you should lower a field's type against its
526+
/// *unsubstituted* interface type.
527+
AbstractionPattern
528+
unsafeGetSubstFieldType(ValueDecl *member,
529+
CanType origMemberType = CanType()) const;
530+
516531
private:
517532
/// Return an abstraction pattern for the curried type of an
518533
/// Objective-C method.
@@ -648,11 +663,34 @@ class AbstractionPattern {
648663
return getKind() != Kind::Invalid;
649664
}
650665

666+
bool isTypeParameterOrOpaqueArchetype() const {
667+
switch (getKind()) {
668+
case Kind::Opaque:
669+
return true;
670+
case Kind::Type:
671+
case Kind::ClangType:
672+
case Kind::Discard: {
673+
auto type = getType();
674+
if (isa<DependentMemberType>(type) ||
675+
isa<GenericTypeParamType>(type)) {
676+
return true;
677+
}
678+
if (auto archetype = dyn_cast<ArchetypeType>(type)) {
679+
return true;
680+
}
681+
return false;
682+
}
683+
default:
684+
return false;
685+
}
686+
}
687+
651688
bool isTypeParameter() const {
652689
switch (getKind()) {
653690
case Kind::Opaque:
654691
return true;
655692
case Kind::Type:
693+
case Kind::ClangType:
656694
case Kind::Discard: {
657695
auto type = getType();
658696
if (isa<DependentMemberType>(type) ||
@@ -668,12 +706,13 @@ class AbstractionPattern {
668706
return false;
669707
}
670708
}
671-
709+
672710
/// Is this an interface type that is subject to a concrete
673711
/// same-type constraint?
674712
bool isConcreteType() const;
675713

676-
bool requiresClass();
714+
bool requiresClass() const;
715+
LayoutConstraint getLayoutConstraint() const;
677716

678717
/// Return the Swift type which provides structure for this
679718
/// abstraction pattern.

include/swift/SIL/SILType.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,8 @@ class SILType {
242242
///
243243
/// This is equivalent to, but possibly faster than, calling
244244
/// tc.getTypeLowering(type).isAddressOnly().
245-
static bool isAddressOnly(CanType type, Lowering::TypeConverter &tc,
245+
static bool isAddressOnly(CanType type,
246+
Lowering::TypeConverter &tc,
246247
CanGenericSignature sig,
247248
TypeExpansionContext expansion);
248249

include/swift/SIL/TypeLowering.h

Lines changed: 26 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,6 @@ adjustFunctionType(CanSILFunctionType t, SILFunctionType::Representation rep,
9393
witnessMethodConformance);
9494
}
9595

96-
/// Flag used to place context-dependent TypeLowerings in their own arena which
97-
/// can be disposed when a generic context is exited.
98-
enum IsDependent_t : unsigned {
99-
IsNotDependent = false,
100-
IsDependent = true
101-
};
102-
10396
/// Is a lowered SIL type trivial? That is, are copies ultimately just
10497
/// bit-copies, and it takes no work to destroy a value?
10598
enum IsTrivial_t : bool {
@@ -182,6 +175,10 @@ class TypeLowering {
182175
(isFixedABI ? 0U : NonFixedABIFlag) |
183176
(isAddressOnly ? AddressOnlyFlag : 0U) |
184177
(isResilient ? ResilientFlag : 0U)) {}
178+
179+
constexpr bool operator==(RecursiveProperties p) const {
180+
return Flags == p.Flags;
181+
}
185182

186183
static constexpr RecursiveProperties forTrivial() {
187184
return {IsTrivial, IsFixedABI, IsNotAddressOnly, IsNotResilient};
@@ -502,10 +499,8 @@ class TypeLowering {
502499
}
503500

504501
/// Allocate a new TypeLowering using the TypeConverter's allocator.
505-
void *operator new(size_t size, TypeConverter &tc,
506-
IsDependent_t dependent);
507-
void *operator new[](size_t size, TypeConverter &tc,
508-
IsDependent_t dependent);
502+
void *operator new(size_t size, TypeConverter &tc);
503+
void *operator new[](size_t size, TypeConverter &tc);
509504

510505
// Forbid 'new FooTypeLowering' and try to forbid 'delete tl'.
511506
// The latter is made challenging because the existence of the
@@ -573,7 +568,7 @@ enum class CaptureKind {
573568
class TypeConverter {
574569
friend class TypeLowering;
575570

576-
llvm::BumpPtrAllocator IndependentBPA;
571+
llvm::BumpPtrAllocator TypeLoweringBPA;
577572

578573
struct CachingTypeKey {
579574
CanGenericSignature Sig;
@@ -617,11 +612,6 @@ class TypeConverter {
617612
return OrigType.hasCachingKey();
618613
}
619614

620-
IsDependent_t isDependent() const {
621-
if (SubstType->hasTypeParameter())
622-
return IsDependent;
623-
return IsNotDependent;
624-
}
625615
TypeKey getKeyForMinimalExpansion() const {
626616
return {OrigType, SubstType, TypeExpansionContext::minimal()};
627617
}
@@ -662,24 +652,7 @@ class TypeConverter {
662652
#endif
663653

664654
/// Mapping for types independent on contextual generic parameters.
665-
llvm::DenseMap<CachingTypeKey, const TypeLowering *> IndependentTypes;
666-
667-
struct DependentTypeState {
668-
llvm::BumpPtrAllocator BPA;
669-
CanGenericSignature Sig;
670-
llvm::DenseMap<TypeConverter::CachingTypeKey,
671-
const TypeLowering *> Map;
672-
673-
explicit DependentTypeState(CanGenericSignature sig) : Sig(sig) {}
674-
675-
DependentTypeState(DependentTypeState &&) = default;
676-
677-
// No copy constructor or assignment.
678-
DependentTypeState(const DependentTypeState &) = delete;
679-
void operator=(const DependentTypeState &) = delete;
680-
};
681-
682-
llvm::SmallVector<DependentTypeState, 1> DependentTypes;
655+
llvm::DenseMap<CachingTypeKey, const TypeLowering *> LoweredTypes;
683656

684657
llvm::DenseMap<std::pair<TypeExpansionContext, SILDeclRef>, SILConstantInfo *>
685658
ConstantTypes;
@@ -703,7 +676,8 @@ class TypeConverter {
703676
#include "swift/SIL/BridgedTypes.def"
704677

705678
const TypeLowering &
706-
getTypeLoweringForLoweredType(TypeKey key,
679+
getTypeLoweringForLoweredType(AbstractionPattern origType,
680+
CanType loweredType,
707681
TypeExpansionContext forExpansion,
708682
bool origHadOpaqueTypeArchetype);
709683

@@ -772,11 +746,14 @@ class TypeConverter {
772746
return isIndirectPlusZeroSelfParameter(T.getASTType());
773747
}
774748

775-
/// Lowers a Swift type to a SILType, and returns the SIL TypeLowering
749+
/// Lowers a context-independent Swift type to a SILType, and returns the SIL TypeLowering
776750
/// for that type.
751+
///
752+
/// If `t` contains generic parameters, then the overload that also takes an
753+
/// `AbstractionPattern` must be used.
777754
const TypeLowering &
778755
getTypeLowering(Type t, TypeExpansionContext forExpansion) {
779-
AbstractionPattern pattern(getCurGenericContext(), t->getCanonicalType());
756+
AbstractionPattern pattern(t->getCanonicalType());
780757
return getTypeLowering(pattern, t, forExpansion);
781758
}
782759

@@ -789,8 +766,18 @@ class TypeConverter {
789766
/// Returns the SIL TypeLowering for an already lowered SILType. If the
790767
/// SILType is an address, returns the TypeLowering for the pointed-to
791768
/// type.
769+
///
770+
/// If `t` contains type parameters, then the generic signature for its context
771+
/// must be provided.
772+
const TypeLowering &
773+
getTypeLowering(SILType t, TypeExpansionContext forExpansion,
774+
CanGenericSignature signature = nullptr);
775+
776+
/// Returns the SIL TypeLowering for an already lowered SILType. If the
777+
/// SILType is an address, returns the TypeLowering for the pointed-to
778+
/// type in the context of the given SILFunction.
792779
const TypeLowering &
793-
getTypeLowering(SILType t, TypeExpansionContext forExpansion);
780+
getTypeLowering(SILType t, SILFunction &F);
794781

795782
// Returns the lowered SIL type for a Swift type.
796783
SILType getLoweredType(Type t, TypeExpansionContext forExpansion) {
@@ -949,26 +936,6 @@ class TypeConverter {
949936
AbstractStorageDecl *value,
950937
Type lvalueType);
951938

952-
/// Push a generic function context. See GenericContextScope for an RAII
953-
/// interface to this function.
954-
///
955-
/// Types containing generic parameter references must be lowered in a generic
956-
/// context. There can be at most one level of generic context active at any
957-
/// point in time.
958-
void pushGenericContext(CanGenericSignature sig);
959-
960-
/// Return the current generic context. This should only be used in
961-
/// the type-conversion routines.
962-
CanGenericSignature getCurGenericContext() const {
963-
if (DependentTypes.empty())
964-
return CanGenericSignature();
965-
return DependentTypes.back().Sig;
966-
}
967-
968-
/// Pop a generic function context. See GenericContextScope for an RAII
969-
/// interface to this function. There must be an active generic context.
970-
void popGenericContext(CanGenericSignature sig);
971-
972939
/// Known types for bridging.
973940
#define BRIDGING_KNOWN_TYPE(BridgedModule,BridgedType) \
974941
CanType get##BridgedType##Type();
@@ -1079,26 +1046,6 @@ class TypeConverter {
10791046
bool suppressOptional);
10801047
};
10811048

1082-
/// RAII interface to push a generic context.
1083-
class GenericContextScope {
1084-
TypeConverter &TC;
1085-
CanGenericSignature Sig;
1086-
public:
1087-
GenericContextScope(TypeConverter &TC, CanGenericSignature sig)
1088-
: TC(TC), Sig(sig)
1089-
{
1090-
TC.pushGenericContext(sig);
1091-
}
1092-
1093-
~GenericContextScope() {
1094-
TC.popGenericContext(Sig);
1095-
}
1096-
1097-
private:
1098-
GenericContextScope(const GenericContextScope&) = delete;
1099-
GenericContextScope &operator=(const GenericContextScope&) = delete;
1100-
};
1101-
11021049
} // namespace Lowering
11031050
} // namespace swift
11041051

0 commit comments

Comments
 (0)