Skip to content

Commit 8e8c57c

Browse files
committed
SIL type lowering: Compute IsTypeExpansionSensitive and use it instead of TypeBase's hasOpaqueArchetypePropertiesOrCases
A type is IsTypeExpansionSensitive if it contains an opaque result type that influences how the type is lowered. This could be because the type mentions an opaque archetype and therefore we would look through to the underlying type depending on the type expansion and could get a different SIL type. For example '() -> out some P' could lower to '() -> @out Int'. Or this could be because when we lower an aggregate type some of its fields are opaque types that could be looked through and therefore the aggregate has different lowering (e.g address vs. loadable) in different type expansion contexts. By replacing it this change also fixes an infinite recursion in hasOpaqueArchetypePropertiesOrCases. rdar://68798822
1 parent 0ff5f60 commit 8e8c57c

File tree

5 files changed

+340
-211
lines changed

5 files changed

+340
-211
lines changed

include/swift/AST/Types.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -600,9 +600,6 @@ class alignas(1 << TypeAlignInBits) TypeBase {
600600
bool hasOpaqueArchetype() const {
601601
return getRecursiveProperties().hasOpaqueArchetype();
602602
}
603-
/// Determine whether the type has any stored properties or enum cases that
604-
/// involve an opaque type.
605-
bool hasOpaqueArchetypePropertiesOrCases();
606603

607604
/// Determine whether the type is an opened existential type.
608605
///

include/swift/SIL/TypeLowering.h

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -147,16 +147,23 @@ enum IsResilient_t : bool {
147147
IsResilient = true
148148
};
149149

150+
/// Does this type contain an opaque result type that affects type lowering?
151+
enum IsTypeExpansionSensitive_t : bool {
152+
IsNotTypeExpansionSensitive = false,
153+
IsTypeExpansionSensitive = true
154+
};
155+
150156
/// Extended type information used by SIL.
151157
class TypeLowering {
152158
public:
153159
class RecursiveProperties {
154160
// These are chosen so that bitwise-or merges the flags properly.
155161
enum : unsigned {
156-
NonTrivialFlag = 1 << 0,
157-
NonFixedABIFlag = 1 << 1,
158-
AddressOnlyFlag = 1 << 2,
159-
ResilientFlag = 1 << 3,
162+
NonTrivialFlag = 1 << 0,
163+
NonFixedABIFlag = 1 << 1,
164+
AddressOnlyFlag = 1 << 2,
165+
ResilientFlag = 1 << 3,
166+
TypeExpansionSensitiveFlag = 1 << 4,
160167
};
161168

162169
uint8_t Flags;
@@ -165,15 +172,17 @@ class TypeLowering {
165172
/// a trivial, loadable, fixed-layout type.
166173
constexpr RecursiveProperties() : Flags(0) {}
167174

168-
constexpr RecursiveProperties(IsTrivial_t isTrivial,
169-
IsFixedABI_t isFixedABI,
170-
IsAddressOnly_t isAddressOnly,
171-
IsResilient_t isResilient)
172-
: Flags((isTrivial ? 0U : NonTrivialFlag) |
173-
(isFixedABI ? 0U : NonFixedABIFlag) |
174-
(isAddressOnly ? AddressOnlyFlag : 0U) |
175-
(isResilient ? ResilientFlag : 0U)) {}
176-
175+
constexpr RecursiveProperties(
176+
IsTrivial_t isTrivial, IsFixedABI_t isFixedABI,
177+
IsAddressOnly_t isAddressOnly, IsResilient_t isResilient,
178+
IsTypeExpansionSensitive_t isTypeExpansionSensitive =
179+
IsNotTypeExpansionSensitive)
180+
: Flags((isTrivial ? 0U : NonTrivialFlag) |
181+
(isFixedABI ? 0U : NonFixedABIFlag) |
182+
(isAddressOnly ? AddressOnlyFlag : 0U) |
183+
(isResilient ? ResilientFlag : 0U) |
184+
(isTypeExpansionSensitive ? TypeExpansionSensitiveFlag : 0U)) {}
185+
177186
constexpr bool operator==(RecursiveProperties p) const {
178187
return Flags == p.Flags;
179188
}
@@ -183,7 +192,7 @@ class TypeLowering {
183192
}
184193

185194
static constexpr RecursiveProperties forReference() {
186-
return {IsNotTrivial, IsFixedABI, IsNotAddressOnly, IsNotResilient };
195+
return {IsNotTrivial, IsFixedABI, IsNotAddressOnly, IsNotResilient};
187196
}
188197

189198
static constexpr RecursiveProperties forOpaque() {
@@ -194,6 +203,7 @@ class TypeLowering {
194203
return {IsTrivial, IsFixedABI, IsNotAddressOnly, IsResilient};
195204
}
196205

206+
197207
void addSubobject(RecursiveProperties other) {
198208
Flags |= other.Flags;
199209
}
@@ -210,10 +220,19 @@ class TypeLowering {
210220
IsResilient_t isResilient() const {
211221
return IsResilient_t((Flags & ResilientFlag) != 0);
212222
}
223+
IsTypeExpansionSensitive_t isTypeExpansionSensitive() const {
224+
return IsTypeExpansionSensitive_t(
225+
(Flags & TypeExpansionSensitiveFlag) != 0);
226+
}
213227

214228
void setNonTrivial() { Flags |= NonTrivialFlag; }
215229
void setNonFixedABI() { Flags |= NonFixedABIFlag; }
216230
void setAddressOnly() { Flags |= AddressOnlyFlag; }
231+
void setTypeExpansionSensitive(
232+
IsTypeExpansionSensitive_t isTypeExpansionSensitive) {
233+
Flags = (Flags & ~TypeExpansionSensitiveFlag) |
234+
(isTypeExpansionSensitive ? TypeExpansionSensitiveFlag : 0);
235+
}
217236
};
218237

219238
private:
@@ -305,6 +324,12 @@ class TypeLowering {
305324
return Properties.isResilient();
306325
}
307326

327+
/// Does this type contain an opaque result type that could influence how the
328+
/// type is lowered if we could look through to the underlying type.
329+
bool isTypeExpansionSensitive() const {
330+
return Properties.isTypeExpansionSensitive();
331+
}
332+
308333
ResilienceExpansion getResilienceExpansion() const {
309334
return expansionContext.getResilienceExpansion();
310335
}
@@ -705,8 +730,6 @@ class TypeConverter {
705730

706731
llvm::DenseMap<SILDeclRef, CaptureInfo> LoweredCaptures;
707732

708-
llvm::DenseMap<CanType, bool> opaqueArchetypeFields;
709-
710733
/// Cache of loadable SILType to number of (estimated) fields
711734
///
712735
/// Second element is a ResilienceExpansion.
@@ -719,17 +742,15 @@ class TypeConverter {
719742
Optional<CanType> BridgedType##Ty;
720743
#include "swift/SIL/BridgedTypes.def"
721744

722-
const TypeLowering &
723-
getTypeLoweringForLoweredType(AbstractionPattern origType,
724-
CanType loweredType,
725-
TypeExpansionContext forExpansion,
726-
bool origHadOpaqueTypeArchetype);
745+
const TypeLowering &getTypeLoweringForLoweredType(
746+
AbstractionPattern origType, CanType loweredType,
747+
TypeExpansionContext forExpansion,
748+
IsTypeExpansionSensitive_t isTypeExpansionSensitive);
727749

728-
const TypeLowering *
729-
getTypeLoweringForExpansion(TypeKey key,
730-
TypeExpansionContext forExpansion,
731-
const TypeLowering *lowering,
732-
bool origHadOpaqueTypeArchetype);
750+
const TypeLowering *getTypeLoweringForExpansion(
751+
TypeKey key, TypeExpansionContext forExpansion,
752+
const TypeLowering *minimalExpansionLowering,
753+
IsTypeExpansionSensitive_t isOrigTypeExpansionSensitive);
733754

734755
public:
735756
ModuleDecl &M;
@@ -885,8 +906,6 @@ class TypeConverter {
885906

886907
CanType getLoweredTypeOfGlobal(VarDecl *var);
887908

888-
bool hasOpaqueArchetypeOrPropertiesOrCases(CanType ty);
889-
890909
/// Return the SILFunctionType for a native function value of the
891910
/// given type.
892911
CanSILFunctionType getSILFunctionType(TypeExpansionContext context,

lib/AST/Type.cpp

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5048,27 +5048,6 @@ Type TypeBase::openAnyExistentialType(OpenedArchetypeType *&opened) {
50485048
return opened;
50495049
}
50505050

5051-
bool TypeBase::hasOpaqueArchetypePropertiesOrCases() {
5052-
if (auto *structDecl = getStructOrBoundGenericStruct()) {
5053-
for (auto *field : structDecl->getStoredProperties()) {
5054-
auto fieldTy = field->getInterfaceType()->getCanonicalType();
5055-
if (fieldTy->hasOpaqueArchetype() ||
5056-
fieldTy->hasOpaqueArchetypePropertiesOrCases())
5057-
return true;
5058-
}
5059-
}
5060-
5061-
if (auto *enumDecl = getEnumOrBoundGenericEnum()) {
5062-
for (auto *elt : enumDecl->getAllElements()) {
5063-
auto eltType = elt->getInterfaceType();
5064-
if (eltType->hasOpaqueArchetype() ||
5065-
eltType->getCanonicalType()->hasOpaqueArchetypePropertiesOrCases())
5066-
return true;
5067-
}
5068-
}
5069-
return false;
5070-
}
5071-
50725051
CanType swift::substOpaqueTypesWithUnderlyingTypes(CanType ty,
50735052
TypeExpansionContext context,
50745053
bool allowLoweredTypes) {

0 commit comments

Comments
 (0)