Skip to content

Commit dd95a63

Browse files
authored
Merge pull request #23724 from brentdax/static-start
[NFC] Correct assumptions about static AbstractStorageDecls
2 parents 8437ee5 + 67af97c commit dd95a63

File tree

14 files changed

+101
-86
lines changed

14 files changed

+101
-86
lines changed

include/swift/AST/Decl.h

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ class alignas(1 << DeclAlignInBits) Decl {
334334
IsUserAccessible : 1
335335
);
336336

337-
SWIFT_INLINE_BITFIELD(AbstractStorageDecl, ValueDecl, 1+1+1+1+2+1+1,
337+
SWIFT_INLINE_BITFIELD(AbstractStorageDecl, ValueDecl, 1+1+1+1+2+1+1+1,
338338
/// Whether the getter is mutating.
339339
IsGetterMutating : 1,
340340

@@ -353,14 +353,14 @@ class alignas(1 << DeclAlignInBits) Decl {
353353
/// Whether a keypath component can directly reference this storage,
354354
/// or if it must use the overridden declaration instead.
355355
HasComputedValidKeyPathComponent : 1,
356-
ValidKeyPathComponent : 1
357-
);
358-
359-
SWIFT_INLINE_BITFIELD(VarDecl, AbstractStorageDecl, 1+4+1+1+1+1,
356+
ValidKeyPathComponent : 1,
357+
360358
/// Whether this property is a type property (currently unfortunately
361359
/// called 'static').
362-
IsStatic : 1,
360+
IsStatic : 1
361+
);
363362

363+
SWIFT_INLINE_BITFIELD(VarDecl, AbstractStorageDecl, 4+1+1+1+1,
364364
/// The specifier associated with this variable or parameter. This
365365
/// determines the storage semantics of the value e.g. mutability.
366366
Specifier : 4,
@@ -393,6 +393,10 @@ class alignas(1 << DeclAlignInBits) Decl {
393393
/// Information about a symbolic default argument, like #file.
394394
defaultArgumentKind : NumDefaultArgumentKindBits
395395
);
396+
397+
SWIFT_INLINE_BITFIELD(SubscriptDecl, VarDecl, 2,
398+
StaticSpelling : 2
399+
);
396400

397401
SWIFT_INLINE_BITFIELD(EnumElementDecl, ValueDecl, 1,
398402
/// The ResilienceExpansion to use for default arguments.
@@ -4283,15 +4287,17 @@ class AbstractStorageDecl : public ValueDecl {
42834287
}
42844288

42854289
protected:
4286-
AbstractStorageDecl(DeclKind Kind, DeclContext *DC, DeclName Name,
4287-
SourceLoc NameLoc, StorageIsMutable_t supportsMutation)
4290+
AbstractStorageDecl(DeclKind Kind, bool IsStatic, DeclContext *DC,
4291+
DeclName Name, SourceLoc NameLoc,
4292+
StorageIsMutable_t supportsMutation)
42884293
: ValueDecl(Kind, DC, Name, NameLoc) {
42894294
Bits.AbstractStorageDecl.HasStorage = true;
42904295
Bits.AbstractStorageDecl.SupportsMutation = supportsMutation;
42914296
Bits.AbstractStorageDecl.IsGetterMutating = false;
42924297
Bits.AbstractStorageDecl.IsSetterMutating = true;
42934298
Bits.AbstractStorageDecl.OpaqueReadOwnership =
42944299
unsigned(OpaqueReadOwnership::Owned);
4300+
Bits.AbstractStorageDecl.IsStatic = IsStatic;
42954301
}
42964302

42974303
void setSupportsMutationIfStillStored(StorageIsMutable_t supportsMutation) {
@@ -4312,9 +4318,16 @@ class AbstractStorageDecl : public ValueDecl {
43124318
/// attribute.
43134319
bool isTransparent() const;
43144320

4315-
/// Determine whether this storage is a static member, if it
4316-
/// is a member. Currently only variables can be static.
4317-
inline bool isStatic() const; // defined in this header
4321+
/// Is this a type ('static') variable?
4322+
bool isStatic() const {
4323+
return Bits.AbstractStorageDecl.IsStatic;
4324+
}
4325+
void setStatic(bool IsStatic) {
4326+
Bits.AbstractStorageDecl.IsStatic = IsStatic;
4327+
}
4328+
4329+
/// \returns the way 'static'/'class' should be spelled for this declaration.
4330+
StaticSpellingKind getCorrectStaticSpelling() const;
43184331

43194332
/// Return the interface type of the stored value.
43204333
Type getValueInterfaceType() const;
@@ -4612,10 +4625,9 @@ class VarDecl : public AbstractStorageDecl {
46124625

46134626
VarDecl(DeclKind Kind, bool IsStatic, Specifier Sp, bool IsCaptureList,
46144627
SourceLoc NameLoc, Identifier Name, DeclContext *DC)
4615-
: AbstractStorageDecl(Kind, DC, Name, NameLoc,
4628+
: AbstractStorageDecl(Kind, IsStatic, DC, Name, NameLoc,
46164629
StorageIsMutable_t(!isImmutableSpecifier(Sp)))
46174630
{
4618-
Bits.VarDecl.IsStatic = IsStatic;
46194631
Bits.VarDecl.Specifier = static_cast<unsigned>(Sp);
46204632
Bits.VarDecl.IsCaptureList = IsCaptureList;
46214633
Bits.VarDecl.IsDebuggerVar = false;
@@ -4794,14 +4806,6 @@ class VarDecl : public AbstractStorageDecl {
47944806
return getSpecifier() == Specifier::InOut;
47954807
}
47964808

4797-
4798-
/// Is this a type ('static') variable?
4799-
bool isStatic() const { return Bits.VarDecl.IsStatic; }
4800-
void setStatic(bool IsStatic) { Bits.VarDecl.IsStatic = IsStatic; }
4801-
4802-
/// \returns the way 'static'/'class' should be spelled for this declaration.
4803-
StaticSpellingKind getCorrectStaticSpelling() const;
4804-
48054809
bool isImmutable() const {
48064810
return isImmutableSpecifier(getSpecifier());
48074811
}
@@ -5110,24 +5114,40 @@ enum class ObjCSubscriptKind {
51105114
/// signatures (indices and element type) are distinct.
51115115
///
51125116
class SubscriptDecl : public GenericContext, public AbstractStorageDecl {
5117+
SourceLoc StaticLoc;
51135118
SourceLoc ArrowLoc;
51145119
ParameterList *Indices;
51155120
TypeLoc ElementTy;
51165121

51175122
public:
5118-
SubscriptDecl(DeclName Name, SourceLoc SubscriptLoc, ParameterList *Indices,
5123+
SubscriptDecl(DeclName Name,
5124+
SourceLoc StaticLoc, StaticSpellingKind StaticSpelling,
5125+
SourceLoc SubscriptLoc, ParameterList *Indices,
51195126
SourceLoc ArrowLoc, TypeLoc ElementTy, DeclContext *Parent,
51205127
GenericParamList *GenericParams)
51215128
: GenericContext(DeclContextKind::SubscriptDecl, Parent),
5122-
AbstractStorageDecl(DeclKind::Subscript, Parent, Name, SubscriptLoc,
5129+
AbstractStorageDecl(DeclKind::Subscript,
5130+
StaticSpelling != StaticSpellingKind::None,
5131+
Parent, Name, SubscriptLoc,
51235132
/*will be overwritten*/ StorageIsNotMutable),
5124-
ArrowLoc(ArrowLoc), Indices(nullptr), ElementTy(ElementTy) {
5133+
StaticLoc(StaticLoc), ArrowLoc(ArrowLoc),
5134+
Indices(nullptr), ElementTy(ElementTy) {
5135+
Bits.SubscriptDecl.StaticSpelling = static_cast<unsigned>(StaticSpelling);
51255136
setIndices(Indices);
51265137
setGenericParams(GenericParams);
51275138
}
51285139

5140+
/// \returns the way 'static'/'class' was spelled in the source.
5141+
StaticSpellingKind getStaticSpelling() const {
5142+
return static_cast<StaticSpellingKind>(Bits.SubscriptDecl.StaticSpelling);
5143+
}
5144+
5145+
SourceLoc getStaticLoc() const { return StaticLoc; }
51295146
SourceLoc getSubscriptLoc() const { return getNameLoc(); }
5130-
SourceLoc getStartLoc() const { return getSubscriptLoc(); }
5147+
5148+
SourceLoc getStartLoc() const {
5149+
return getStaticLoc().isValid() ? getStaticLoc() : getSubscriptLoc();
5150+
}
51315151
SourceRange getSourceRange() const;
51325152
SourceRange getSignatureSourceRange() const;
51335153

@@ -6825,15 +6845,6 @@ AbstractStorageDecl::overwriteSetterAccess(AccessLevel accessLevel) {
68256845
mutableAddressor->overwriteAccess(accessLevel);
68266846
}
68276847

6828-
inline bool AbstractStorageDecl::isStatic() const {
6829-
if (auto var = dyn_cast<VarDecl>(this)) {
6830-
return var->isStatic();
6831-
}
6832-
6833-
// Currently, subscripts are never static.
6834-
return false;
6835-
}
6836-
68376848
/// Constructors and destructors always have a 'self' parameter,
68386849
/// which is stored in an instance member. Functions only have a
68396850
/// 'self' if they are declared inside of a nominal type or extension,

include/swift/Serialization/ModuleFormat.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5252
/// describe what change you made. The content of this comment isn't important;
5353
/// it just ensures a conflict if two people change the module format.
5454
/// Don't worry about adhering to the 80-column limit for this line.
55-
const uint16_t SWIFTMODULE_VERSION_MINOR = 481; // Last change: custom attrs
55+
const uint16_t SWIFTMODULE_VERSION_MINOR = 482; // static subscripts
5656

5757
using DeclIDField = BCFixed<31>;
5858

@@ -1183,6 +1183,7 @@ namespace decls_block {
11831183
DeclIDField, // overridden decl
11841184
AccessLevelField, // access level
11851185
AccessLevelField, // setter access, if applicable
1186+
StaticSpellingKindField, // is subscript static?
11861187
BCVBR<5>, // number of parameter name components
11871188
BCArray<IdentifierIDField> // name components,
11881189
// followed by DeclID accessors,

lib/AST/ASTDumper.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -797,8 +797,6 @@ namespace {
797797

798798
void visitVarDecl(VarDecl *VD) {
799799
printCommon(VD, "var_decl");
800-
if (VD->isStatic())
801-
PrintWithColorRAII(OS, DeclModifierColor) << " type";
802800
if (VD->isLet())
803801
PrintWithColorRAII(OS, DeclModifierColor) << " let";
804802
if (VD->hasNonPatternBindingInit())
@@ -811,6 +809,9 @@ namespace {
811809
}
812810

813811
void printStorageImpl(AbstractStorageDecl *D) {
812+
if (D->isStatic())
813+
PrintWithColorRAII(OS, DeclModifierColor) << " type";
814+
814815
auto impl = D->getImplInfo();
815816
PrintWithColorRAII(OS, DeclModifierColor)
816817
<< " readImpl="

lib/AST/ASTPrinter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -893,8 +893,8 @@ class PrintAST : public ASTVisitor<PrintAST> {
893893
} // unnamed namespace
894894

895895
static StaticSpellingKind getCorrectStaticSpelling(const Decl *D) {
896-
if (auto *VD = dyn_cast<VarDecl>(D)) {
897-
return VD->getCorrectStaticSpelling();
896+
if (auto *ASD = dyn_cast<AbstractStorageDecl>(D)) {
897+
return ASD->getCorrectStaticSpelling();
898898
} else if (auto *PBD = dyn_cast<PatternBindingDecl>(D)) {
899899
return PBD->getCorrectStaticSpelling();
900900
} else if (auto *FD = dyn_cast<FuncDecl>(D)) {

lib/AST/Decl.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2019,12 +2019,9 @@ bool ValueDecl::isInstanceMember() const {
20192019
return false;
20202020

20212021
case DeclKind::Subscript:
2022-
// Subscripts are always instance members.
2023-
return true;
2024-
20252022
case DeclKind::Var:
2026-
// Non-static variables are instance members.
2027-
return !cast<VarDecl>(this)->isStatic();
2023+
// Non-static variables and subscripts are instance members.
2024+
return !cast<AbstractStorageDecl>(this)->isStatic();
20282025

20292026
case DeclKind::Module:
20302027
// Modules are never instance members.
@@ -5098,12 +5095,16 @@ bool VarDecl::isAnonClosureParam() const {
50985095
return nameStr[0] == '$';
50995096
}
51005097

5101-
StaticSpellingKind VarDecl::getCorrectStaticSpelling() const {
5098+
StaticSpellingKind AbstractStorageDecl::getCorrectStaticSpelling() const {
51025099
if (!isStatic())
51035100
return StaticSpellingKind::None;
5104-
if (auto *PBD = getParentPatternBinding()) {
5105-
if (PBD->getStaticSpelling() != StaticSpellingKind::None)
5106-
return PBD->getStaticSpelling();
5101+
if (auto *VD = dyn_cast<VarDecl>(this)) {
5102+
if (auto *PBD = VD->getParentPatternBinding()) {
5103+
if (PBD->getStaticSpelling() != StaticSpellingKind::None)
5104+
return PBD->getStaticSpelling();
5105+
}
5106+
} else if (auto *SD = dyn_cast<SubscriptDecl>(this)) {
5107+
return SD->getStaticSpelling();
51075108
}
51085109

51095110
return getCorrectStaticSpellingForDecl(this);

lib/ClangImporter/ImportDecl.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1565,7 +1565,7 @@ buildSubscriptGetterDecl(ClangImporter::Implementation &Impl,
15651565
AccessorKind::Get,
15661566
subscript,
15671567
/*StaticLoc=*/SourceLoc(),
1568-
StaticSpellingKind::None,
1568+
subscript->getStaticSpelling(),
15691569
/*Throws=*/false,
15701570
/*ThrowsLoc=*/SourceLoc(),
15711571
/*GenericParams=*/nullptr,
@@ -1621,7 +1621,7 @@ buildSubscriptSetterDecl(ClangImporter::Implementation &Impl,
16211621
AccessorKind::Set,
16221622
subscript,
16231623
/*StaticLoc=*/SourceLoc(),
1624-
StaticSpellingKind::None,
1624+
subscript->getStaticSpelling(),
16251625
/*Throws=*/false,
16261626
/*ThrowsLoc=*/SourceLoc(),
16271627
/*GenericParams=*/nullptr,
@@ -6570,6 +6570,7 @@ SwiftDeclConverter::importSubscript(Decl *decl,
65706570
DeclName name(C, DeclBaseName::createSubscript(), {Identifier()});
65716571
auto subscript = Impl.createDeclWithClangNode<SubscriptDecl>(
65726572
getter->getClangNode(), getOverridableAccessLevel(dc), name,
6573+
/*StaticLoc=*/SourceLoc(), StaticSpellingKind::None,
65736574
decl->getLoc(), bodyParams, decl->getLoc(),
65746575
TypeLoc::withoutLoc(elementTy), dc,
65756576
/*GenericParams=*/nullptr);

lib/Index/Index.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -927,8 +927,7 @@ bool IndexSwiftASTWalker::reportPseudoAccessor(AbstractStorageDecl *D,
927927
Info.symInfo.Kind = SymbolKind::Function;
928928
if (D->getDeclContext()->isTypeContext()) {
929929
if (D->isStatic()) {
930-
if (isa<VarDecl>(D) &&
931-
cast<VarDecl>(D)->getCorrectStaticSpelling() == StaticSpellingKind::KeywordClass)
930+
if (D->getCorrectStaticSpelling() == StaticSpellingKind::KeywordClass)
932931
Info.symInfo.Kind = SymbolKind::ClassMethod;
933932
else
934933
Info.symInfo.Kind = SymbolKind::StaticMethod;

lib/Parse/ParseDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6412,6 +6412,7 @@ Parser::parseDeclSubscript(ParseDeclOptions Flags,
64126412
DeclName name = DeclName(Context, DeclBaseName::createSubscript(),
64136413
argumentNames);
64146414
auto *Subscript = new (Context) SubscriptDecl(name,
6415+
SourceLoc(), StaticSpellingKind::None,
64156416
SubscriptLoc, Indices.get(),
64166417
ArrowLoc, ElementTy.get(),
64176418
CurDeclContext,

lib/Sema/CodeSynthesis.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,8 @@ static AccessorDecl *createGetterPrototype(AbstractStorageDecl *storage,
184184
auto *getterParams = buildIndexForwardingParamList(storage, {}, ctx);
185185

186186
SourceLoc staticLoc;
187-
if (auto var = dyn_cast<VarDecl>(storage)) {
188-
if (var->isStatic())
189-
staticLoc = var->getLoc();
190-
}
187+
if (storage->isStatic())
188+
staticLoc = storage->getLoc();
191189

192190
auto storageInterfaceType = storage->getValueInterfaceType();
193191

lib/Sema/ConstraintSystem.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1287,7 +1287,8 @@ ConstraintSystem::getTypeOfMemberReference(
12871287
// If self is a value type and the base type is an lvalue, wrap it in an
12881288
// inout type.
12891289
auto selfFlags = ParameterTypeFlags();
1290-
if (!outerDC->getDeclaredInterfaceType()->hasReferenceSemantics() &&
1290+
if (isInstance &&
1291+
!outerDC->getDeclaredInterfaceType()->hasReferenceSemantics() &&
12911292
baseTy->is<LValueType>() &&
12921293
!selfTy->hasError())
12931294
selfFlags = selfFlags.withInOut(true);

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -234,30 +234,21 @@ static bool areOverrideCompatibleSimple(ValueDecl *decl,
234234
if (parentDecl->isInvalid())
235235
return false;
236236

237-
if (auto func = dyn_cast<FuncDecl>(decl)) {
238-
// Specific checking for methods.
239-
auto parentFunc = cast<FuncDecl>(parentDecl);
240-
if (func->isStatic() != parentFunc->isStatic())
241-
return false;
242-
if (func->isGeneric() != parentFunc->isGeneric())
243-
return false;
244-
} else if (auto ctor = dyn_cast<ConstructorDecl>(decl)) {
245-
auto parentCtor = cast<ConstructorDecl>(parentDecl);
246-
if (ctor->isGeneric() != parentCtor->isGeneric())
237+
// If their staticness is different, they aren't compatible.
238+
if (decl->isStatic() != parentDecl->isStatic())
239+
return false;
240+
241+
// If their genericity is different, they aren't compatible.
242+
if (auto genDecl = decl->getAsGenericContext()) {
243+
auto genParentDecl = parentDecl->getAsGenericContext();
244+
if (genDecl->isGeneric() != genParentDecl->isGeneric())
247245
return false;
246+
}
248247

249-
// Factory initializers cannot be overridden.
248+
// Factory initializers cannot be overridden.
249+
if (auto parentCtor = dyn_cast<ConstructorDecl>(parentDecl))
250250
if (parentCtor->isFactoryInit())
251251
return false;
252-
} else if (auto var = dyn_cast<VarDecl>(decl)) {
253-
auto parentVar = cast<VarDecl>(parentDecl);
254-
if (var->isStatic() != parentVar->isStatic())
255-
return false;
256-
} else if (auto subscript = dyn_cast<SubscriptDecl>(decl)) {
257-
auto parentSubscript = cast<SubscriptDecl>(parentDecl);
258-
if (subscript->isGeneric() != parentSubscript->isGeneric())
259-
return false;
260-
}
261252

262253
return true;
263254
}

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -490,12 +490,10 @@ swift::matchWitness(
490490
} else if (auto *witnessASD = dyn_cast<AbstractStorageDecl>(witness)) {
491491
auto *reqASD = cast<AbstractStorageDecl>(req);
492492

493-
// If this is a property requirement, check that the static-ness matches.
494-
if (auto *vdWitness = dyn_cast<VarDecl>(witness)) {
495-
if (cast<VarDecl>(req)->isStatic() != vdWitness->isStatic())
496-
return RequirementMatch(witness, MatchKind::StaticNonStaticConflict);
497-
}
498-
493+
// Check that the static-ness matches.
494+
if (reqASD->isStatic() != witnessASD->isStatic())
495+
return RequirementMatch(witness, MatchKind::StaticNonStaticConflict);
496+
499497
// If the requirement is settable and the witness is not, reject it.
500498
if (req->isSettable(req->getDeclContext()) &&
501499
!witness->isSettable(witness->getDeclContext()))

0 commit comments

Comments
 (0)