Skip to content

Commit cd1ef24

Browse files
Merge pull request #78309 from AnthonyLatsis/nymphaea
Assortment of small fixes and cleanups
2 parents e6b9cb9 + 967f99f commit cd1ef24

File tree

13 files changed

+71
-82
lines changed

13 files changed

+71
-82
lines changed

include/swift/AST/DeclContext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,10 @@ class alignas(1 << DeclContextAlignInBits) DeclContext
586586
/// context.
587587
bool isInSpecializeExtensionContext() const;
588588

589+
/// Returns whether this declaration context is a protocol in an unsupported
590+
/// context.
591+
bool isUnsupportedNestedProtocol() const;
592+
589593
/// Get the most optimal resilience expansion for code in this context.
590594
/// If the body is able to be inlined into functions in other resilience
591595
/// domains, this ensures that only sufficiently-conservative access patterns

include/swift/AST/TypeNodes.def

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,21 +153,21 @@ ABSTRACT_TYPE(ReferenceStorage, Type)
153153
TYPE_RANGE(ReferenceStorage, First##Storage, Last##Storage)
154154
#include "swift/AST/ReferenceStorage.def"
155155
ABSTRACT_TYPE(AnyGeneric, Type)
156-
ABSTRACT_TYPE(NominalOrBoundGenericNominal, Type)
157-
ABSTRACT_TYPE(Nominal, Type)
156+
ABSTRACT_TYPE(NominalOrBoundGenericNominal, AnyGenericType)
157+
ABSTRACT_TYPE(Nominal, NominalOrBoundGenericNominalType)
158158
TYPE(Enum, NominalType)
159159
TYPE(Struct, NominalType)
160160
TYPE(Class, NominalType)
161161
TYPE(Protocol, NominalType)
162162
TYPE(BuiltinTuple, NominalType)
163163
TYPE_RANGE(Nominal, Enum, BuiltinTuple)
164-
ABSTRACT_TYPE(BoundGeneric, Type)
164+
ABSTRACT_TYPE(BoundGeneric, NominalOrBoundGenericNominalType)
165165
TYPE(BoundGenericClass, BoundGenericType)
166166
TYPE(BoundGenericEnum, BoundGenericType)
167167
TYPE(BoundGenericStruct, BoundGenericType)
168168
TYPE_RANGE(BoundGeneric, BoundGenericClass, BoundGenericStruct)
169169
TYPE_RANGE(NominalOrBoundGenericNominal, Enum, BoundGenericStruct)
170-
UNCHECKED_TYPE(UnboundGeneric, Type)
170+
UNCHECKED_TYPE(UnboundGeneric, AnyGenericType)
171171
TYPE_RANGE(AnyGeneric, Enum, UnboundGeneric)
172172
ABSTRACT_TYPE(AnyMetatype, Type)
173173
TYPE(Metatype, AnyMetatypeType)

include/swift/AST/Types.h

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,12 @@ class alignas(1 << TypeAlignInBits) TypeBase
821821
/// type variables referenced by this type.
822822
void getTypeVariables(SmallPtrSetImpl<TypeVariableType *> &typeVariables);
823823

824+
private:
825+
/// If the receiver is a `DependentMemberType`, returns its root. Otherwise,
826+
/// returns the receiver.
827+
Type getDependentMemberRoot();
828+
829+
public:
824830
/// Determine whether this type is a type parameter, which is either a
825831
/// GenericTypeParamType or a DependentMemberType.
826832
///
@@ -6970,8 +6976,6 @@ class OpenedArchetypeType final : public LocalArchetypeType,
69706976
friend ArchetypeType;
69716977
friend GenericEnvironment;
69726978

6973-
UUID ID;
6974-
69756979
/// Create a new opened archetype in the given environment representing
69766980
/// the interface type.
69776981
///
@@ -6987,10 +6991,7 @@ class OpenedArchetypeType final : public LocalArchetypeType,
69876991
/// of an existential value.
69886992
///
69896993
/// \param existential The existential type to open.
6990-
/// \param knownID When non-empty, the known ID of the archetype. When empty,
6991-
/// a fresh archetype with a unique ID will be opened.
6992-
static CanTypeWrapper<OpenedArchetypeType>
6993-
get(CanType existential, std::optional<UUID> knownID = std::nullopt);
6994+
static CanTypeWrapper<OpenedArchetypeType> get(CanType existential);
69946995

69956996
/// Create a new archetype that represents the opened type
69966997
/// of an existential value.
@@ -7065,8 +7066,6 @@ class ElementArchetypeType final : public LocalArchetypeType,
70657066
friend ArchetypeType;
70667067
friend GenericEnvironment;
70677068

7068-
UUID ID;
7069-
70707069
/// Create a new element archetype in the given environment representing
70717070
/// the interface type.
70727071
///
@@ -7862,38 +7861,11 @@ inline ASTContext &TypeBase::getASTContext() const {
78627861
return *const_cast<ASTContext*>(getCanonicalType()->Context);
78637862
}
78647863

7865-
inline bool TypeBase::isTypeVariableOrMember() {
7866-
Type t(this);
7867-
7868-
while (auto *memberTy = t->getAs<DependentMemberType>())
7869-
t = memberTy->getBase();
7870-
7871-
return t->is<TypeVariableType>();
7872-
}
7873-
7874-
inline bool TypeBase::isTypeParameter() {
7875-
Type t(this);
7876-
7877-
while (auto *memberTy = t->getAs<DependentMemberType>())
7878-
t = memberTy->getBase();
7879-
7880-
return t->is<GenericTypeParamType>();
7881-
}
7882-
78837864
// TODO: This will become redundant once InOutType is removed.
78847865
inline bool TypeBase::isMaterializable() {
78857866
return !(hasLValueType() || is<InOutType>());
78867867
}
78877868

7888-
inline GenericTypeParamType *TypeBase::getRootGenericParam() {
7889-
Type t(this);
7890-
7891-
while (auto *memberTy = t->getAs<DependentMemberType>())
7892-
t = memberTy->getBase();
7893-
7894-
return t->castTo<GenericTypeParamType>();
7895-
}
7896-
78977869
inline bool TypeBase::isConstraintType() const {
78987870
return getCanonicalType().isConstraintType();
78997871
}

lib/AST/ASTContext.cpp

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5561,19 +5561,13 @@ CanTypeWrapper<OpenedArchetypeType> OpenedArchetypeType::getNew(
55615561
properties));
55625562
}
55635563

5564-
CanOpenedArchetypeType OpenedArchetypeType::get(CanType existential,
5565-
std::optional<UUID> knownID) {
5564+
CanOpenedArchetypeType OpenedArchetypeType::get(CanType existential) {
55665565
auto &ctx = existential->getASTContext();
55675566
auto existentialSig = ctx.getOpenedExistentialSignature(existential);
55685567

5569-
if (!knownID)
5570-
knownID = UUID::fromTime();
5571-
55725568
auto *genericEnv = GenericEnvironment::forOpenedExistential(
5573-
existentialSig.OpenedSig,
5574-
existentialSig.Shape,
5575-
existentialSig.Generalization,
5576-
*knownID);
5569+
existentialSig.OpenedSig, existentialSig.Shape,
5570+
existentialSig.Generalization, UUID::fromTime());
55775571

55785572
return cast<OpenedArchetypeType>(
55795573
genericEnv->mapTypeIntoContext(existentialSig.SelfType)

lib/AST/Decl.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5162,10 +5162,8 @@ static Type computeNominalType(NominalTypeDecl *decl, DeclTypeKind kind) {
51625162
// If `decl` is a nested type, find the parent type.
51635163
Type ParentTy;
51645164
DeclContext *dc = decl->getDeclContext();
5165-
bool isUnsupportedNestedProtocol =
5166-
isa<ProtocolDecl>(decl) && decl->getParent()->isGenericContext();
51675165

5168-
if (!isUnsupportedNestedProtocol && dc->isTypeContext()) {
5166+
if (!decl->isUnsupportedNestedProtocol() && dc->isTypeContext()) {
51695167
switch (kind) {
51705168
case DeclTypeKind::DeclaredType: {
51715169
if (auto *nominal = dc->getSelfNominalTypeDecl())

lib/AST/DeclContext.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ DeclContext *DeclContext::getParentForLookup() const {
306306
// outer types.
307307
return getModuleScopeContext();
308308
}
309-
if (isa<ProtocolDecl>(this) && getParent()->isGenericContext()) {
309+
if (isUnsupportedNestedProtocol()) {
310310
// Protocols in generic contexts must not look in to their parents,
311311
// as the parents may contain types with inferred implicit
312312
// generic parameters not present in the protocol's generic signature.
@@ -1532,6 +1532,10 @@ bool DeclContext::isInSpecializeExtensionContext() const {
15321532
return isSpecializeExtensionContext(this);
15331533
}
15341534

1535+
bool DeclContext::isUnsupportedNestedProtocol() const {
1536+
return isa<ProtocolDecl>(this) && getParent()->isGenericContext();
1537+
}
1538+
15351539
bool DeclContext::isAlwaysAvailableConformanceContext() const {
15361540
auto *ext = dyn_cast<ExtensionDecl>(this);
15371541
if (ext == nullptr)

lib/AST/ParameterPack.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -177,12 +177,7 @@ void TypeBase::getTypeParameterPacks(
177177
}
178178

179179
bool TypeBase::isParameterPack() {
180-
Type t(this);
181-
182-
while (auto *memberTy = t->getAs<DependentMemberType>())
183-
t = memberTy->getBase();
184-
185-
return t->isRootParameterPack();
180+
return getDependentMemberRoot()->isRootParameterPack();
186181
}
187182

188183
bool TypeBase::isRootParameterPack() {

lib/AST/Type.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,27 @@ void TypeBase::getTypeVariables(
603603
"Did not find type variables!");
604604
}
605605

606+
Type TypeBase::getDependentMemberRoot() {
607+
Type t(this);
608+
609+
while (auto *dmt = t->getAs<DependentMemberType>())
610+
t = dmt->getBase();
611+
612+
return t;
613+
}
614+
615+
bool TypeBase::isTypeVariableOrMember() {
616+
return getDependentMemberRoot()->is<TypeVariableType>();
617+
}
618+
619+
bool TypeBase::isTypeParameter() {
620+
return getDependentMemberRoot()->is<GenericTypeParamType>();
621+
}
622+
623+
GenericTypeParamType *TypeBase::getRootGenericParam() {
624+
return getDependentMemberRoot()->castTo<GenericTypeParamType>();
625+
}
626+
606627
static bool isLegalSILType(CanType type);
607628

608629
static bool isLegalSILTypeOrPackExpansion(CanType type) {

lib/IRGen/GenMeta.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2758,15 +2758,10 @@ ProtocolDecl *irgen::opaqueTypeRequiresWitnessTable(
27582758

27592759
// The type itself must be anchored on one of the generic parameters of
27602760
// the opaque type (not an outer context).
2761-
Type subject = req.getFirstType();
2762-
while (auto depMember = subject->getAs<DependentMemberType>()) {
2763-
subject = depMember->getBase();
2764-
}
2765-
2766-
if (auto genericParam = subject->getAs<GenericTypeParamType>()) {
2767-
unsigned opaqueDepth = opaque->getOpaqueGenericParams().front()->getDepth();
2768-
if (genericParam->getDepth() == opaqueDepth)
2769-
return proto;
2761+
auto *genericParam = req.getFirstType()->getRootGenericParam();
2762+
unsigned opaqueDepth = opaque->getOpaqueGenericParams().front()->getDepth();
2763+
if (genericParam->getDepth() == opaqueDepth) {
2764+
return proto;
27702765
}
27712766

27722767
return nullptr;

lib/Sema/CSSimplify.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,8 +1441,8 @@ class AllowLabelMismatches : public MatchCallArgumentListener {
14411441
}
14421442
};
14431443

1444-
static std::optional<std::tuple<GenericTypeParamType *, TypeVariableType *,
1445-
Type, OpenedExistentialAdjustments>>
1444+
static std::optional<
1445+
std::tuple<TypeVariableType *, Type, OpenedExistentialAdjustments>>
14461446
shouldOpenExistentialCallArgument(ValueDecl *callee, unsigned paramIdx,
14471447
Type paramTy, Type argTy, Expr *argExpr,
14481448
ConstraintSystem &cs) {
@@ -1819,12 +1819,10 @@ static ConstraintSystem::TypeMatchResult matchCallArguments(
18191819
if (auto existentialArg = shouldOpenExistentialCallArgument(
18201820
callee, paramIdx, paramTy, argTy, argExpr, cs)) {
18211821
// My kingdom for a decent "if let" in C++.
1822-
GenericTypeParamType *openedGenericParam;
18231822
TypeVariableType *openedTypeVar;
18241823
Type existentialType;
18251824
OpenedExistentialAdjustments adjustments;
1826-
std::tie(openedGenericParam, openedTypeVar, existentialType,
1827-
adjustments) = *existentialArg;
1825+
std::tie(openedTypeVar, existentialType, adjustments) = *existentialArg;
18281826

18291827
OpenedArchetypeType *opened;
18301828
std::tie(argTy, opened) = cs.openExistentialType(

lib/Sema/OpenedExistentials.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -590,10 +590,10 @@ swift::isMemberAvailableOnExistential(Type baseTy, const ValueDecl *member) {
590590
return result;
591591
}
592592

593-
std::optional<std::tuple<GenericTypeParamType *, TypeVariableType *,
594-
Type, OpenedExistentialAdjustments>>
593+
std::optional<
594+
std::tuple<TypeVariableType *, Type, OpenedExistentialAdjustments>>
595595
swift::canOpenExistentialCallArgument(ValueDecl *callee, unsigned paramIdx,
596-
Type paramTy, Type argTy) {
596+
Type paramTy, Type argTy) {
597597
if (!callee)
598598
return std::nullopt;
599599

@@ -728,7 +728,7 @@ swift::canOpenExistentialCallArgument(ValueDecl *callee, unsigned paramIdx,
728728
if (referenceInfo.hasNonCovariantRef())
729729
return std::nullopt;
730730

731-
return std::make_tuple(genericParam, paramTypeVar, argTy, adjustments);
731+
return std::make_tuple(paramTypeVar, argTy, adjustments);
732732
}
733733

734734
/// For each occurrence of a type **type** in `refTy` that satisfies

lib/Sema/OpenedExistentials.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,12 +154,12 @@ using OpenedExistentialAdjustments =
154154
/// \param argTy The type of the argument.
155155
///
156156
/// \returns If the argument type is existential and opening it can bind a
157-
/// generic parameter in the callee, returns the generic parameter, type
158-
/// variable (from the opened parameter type) the existential type that needs
159-
/// to be opened (from the argument type), and the adjustments that need to be
160-
/// applied to the existential type after it is opened.
161-
std::optional<std::tuple<GenericTypeParamType *, TypeVariableType *,
162-
Type, OpenedExistentialAdjustments>>
157+
/// generic parameter in the callee, returns the type variable (from the opened
158+
/// parameter type) the existential type that needs to be opened (from the
159+
/// argument type), and the adjustments that need to be applied to the
160+
/// existential type after it is opened.
161+
std::optional<
162+
std::tuple<TypeVariableType *, Type, OpenedExistentialAdjustments>>
163163
canOpenExistentialCallArgument(ValueDecl *callee, unsigned paramIdx,
164164
Type paramTy, Type argTy);
165165

lib/Sema/TypeCheckType.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,14 @@ Type TypeResolution::resolveTypeInContext(TypeDecl *typeDecl,
532532

533533
assert(foundDC);
534534

535+
// Protocols cannot be nested in generic contexts. Use the declared interface
536+
// type, which won't have a parent.
537+
if (auto *proto = dyn_cast<ProtocolDecl>(typeDecl)) {
538+
if (proto->isUnsupportedNestedProtocol()) {
539+
return typeDecl->getDeclaredInterfaceType();
540+
}
541+
}
542+
535543
// selfType is the self type of the context, unless the
536544
// context is a protocol type, in which case we might have
537545
// to use the existential type or superclass bound as a

0 commit comments

Comments
 (0)