Skip to content

Commit 12231d2

Browse files
authored
Merge pull request #27571 from slavapestov/circular-validation-cleanups-5
Circular validation cleanups, part 5
2 parents 0ea63be + 6701a7e commit 12231d2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+476
-475
lines changed

include/swift/AST/ASTTypeIDZone.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
SWIFT_TYPEID(AncestryFlags)
1919
SWIFT_TYPEID(CtorInitializerKind)
2020
SWIFT_TYPEID(GenericSignature)
21+
SWIFT_TYPEID(ParamSpecifier)
2122
SWIFT_TYPEID(PropertyWrapperBackingPropertyInfo)
2223
SWIFT_TYPEID(PropertyWrapperTypeInfo)
2324
SWIFT_TYPEID(Requirement)

include/swift/AST/ASTTypeIDs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ class ModuleDecl;
3535
class NominalTypeDecl;
3636
class OperatorDecl;
3737
class OpaqueTypeDecl;
38+
class ParamDecl;
39+
enum class ParamSpecifier : uint8_t;
3840
class PrecedenceGroupDecl;
3941
struct PropertyWrapperBackingPropertyInfo;
4042
struct PropertyWrapperTypeInfo;

include/swift/AST/Decl.h

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,10 @@ class alignas(1 << DeclAlignInBits) Decl {
369369
IsPropertyWrapperBackingProperty : 1
370370
);
371371

372-
SWIFT_INLINE_BITFIELD(ParamDecl, VarDecl, 2+1+NumDefaultArgumentKindBits,
372+
SWIFT_INLINE_BITFIELD(ParamDecl, VarDecl, 1+2+1+NumDefaultArgumentKindBits,
373+
/// Whether we've computed the specifier yet.
374+
SpecifierComputed : 1,
375+
373376
/// The specifier associated with this parameter. This determines
374377
/// the storage semantics of the value e.g. mutability.
375378
Specifier : 2,
@@ -5158,6 +5161,13 @@ class VarDecl : public AbstractStorageDecl {
51585161
}
51595162
};
51605163

5164+
enum class ParamSpecifier : uint8_t {
5165+
Default = 0,
5166+
InOut = 1,
5167+
Shared = 2,
5168+
Owned = 3,
5169+
};
5170+
51615171
/// A function parameter declaration.
51625172
class ParamDecl : public VarDecl {
51635173
Identifier ArgumentName;
@@ -5184,16 +5194,10 @@ class ParamDecl : public VarDecl {
51845194
llvm::PointerIntPair<StoredDefaultArgument *, 2, OptionSet<Flags>>
51855195
DefaultValueAndFlags;
51865196

5187-
public:
5188-
enum class Specifier : uint8_t {
5189-
Default = 0,
5190-
InOut = 1,
5191-
Shared = 2,
5192-
Owned = 3,
5193-
};
5197+
friend class ParamSpecifierRequest;
51945198

5195-
ParamDecl(Specifier specifier,
5196-
SourceLoc specifierLoc, SourceLoc argumentNameLoc,
5199+
public:
5200+
ParamDecl(SourceLoc specifierLoc, SourceLoc argumentNameLoc,
51975201
Identifier argumentName, SourceLoc parameterNameLoc,
51985202
Identifier parameterName, DeclContext *dc);
51995203

@@ -5323,10 +5327,17 @@ class ParamDecl : public VarDecl {
53235327
/// Determine whether this declaration is an anonymous closure parameter.
53245328
bool isAnonClosureParam() const;
53255329

5326-
/// Return the raw specifier value for this parameter.
5327-
Specifier getSpecifier() const {
5328-
return static_cast<Specifier>(Bits.ParamDecl.Specifier);
5330+
using Specifier = ParamSpecifier;
5331+
5332+
Optional<Specifier> getCachedSpecifier() const {
5333+
if (Bits.ParamDecl.SpecifierComputed)
5334+
return Specifier(Bits.ParamDecl.Specifier);
5335+
5336+
return None;
53295337
}
5338+
5339+
/// Return the raw specifier value for this parameter.
5340+
Specifier getSpecifier() const;
53305341
void setSpecifier(Specifier Spec);
53315342

53325343
/// Is the type of this parameter 'inout'?
@@ -5818,11 +5829,6 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
58185829
Bits.AbstractFunctionDecl.Synthesized = value;
58195830
}
58205831

5821-
private:
5822-
void computeNeedsNewVTableEntry();
5823-
5824-
void computeSelfDeclType();
5825-
58265832
public:
58275833
/// Compute the interface type of this function declaration from the
58285834
/// parameter types.

include/swift/AST/TypeCheckRequests.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,6 +1231,7 @@ class OperatorPrecedenceGroupRequest
12311231
bool isCached() const { return true; }
12321232
};
12331233

1234+
/// Computes the raw values for an enum type.
12341235
class EnumRawValuesRequest :
12351236
public SimpleRequest<EnumRawValuesRequest,
12361237
bool (EnumDecl *, TypeResolutionStage),
@@ -1256,6 +1257,7 @@ class EnumRawValuesRequest :
12561257
void cacheResult(bool value) const;
12571258
};
12581259

1260+
/// Determines if an override is ABI compatible with its base method.
12591261
class IsABICompatibleOverrideRequest
12601262
: public SimpleRequest<IsABICompatibleOverrideRequest, bool(ValueDecl *),
12611263
CacheKind::Cached> {
@@ -1314,6 +1316,9 @@ class IsStaticRequest :
13141316
void cacheResult(bool value) const;
13151317
};
13161318

1319+
/// Determines if a method override should introduce a new vtable entry,
1320+
/// because the override is not ABI compatible, or the base method is
1321+
/// less visible than the override.
13171322
class NeedsNewVTableEntryRequest
13181323
: public SimpleRequest<NeedsNewVTableEntryRequest,
13191324
bool(AbstractFunctionDecl *),
@@ -1335,6 +1340,28 @@ class NeedsNewVTableEntryRequest
13351340
void cacheResult(bool value) const;
13361341
};
13371342

1343+
/// Determines the specifier for a parameter (inout, __owned, etc).
1344+
class ParamSpecifierRequest
1345+
: public SimpleRequest<ParamSpecifierRequest,
1346+
ParamSpecifier(ParamDecl *),
1347+
CacheKind::SeparatelyCached> {
1348+
public:
1349+
using SimpleRequest::SimpleRequest;
1350+
1351+
private:
1352+
friend SimpleRequest;
1353+
1354+
// Evaluation.
1355+
llvm::Expected<ParamSpecifier>
1356+
evaluate(Evaluator &evaluator, ParamDecl *decl) const;
1357+
1358+
public:
1359+
// Separate caching.
1360+
bool isCached() const { return true; }
1361+
Optional<ParamSpecifier> getCachedResult() const;
1362+
void cacheResult(ParamSpecifier value) const;
1363+
};
1364+
13381365
// Allow AnyValue to compare two Type values, even though Type doesn't
13391366
// support ==.
13401367
template<>

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,5 @@ SWIFT_REQUEST(TypeChecker, IsStaticRequest,
151151
bool(FuncDecl *), SeparatelyCached, NoLocationInfo)
152152
SWIFT_REQUEST(TypeChecker, NeedsNewVTableEntryRequest,
153153
bool(AbstractFunctionDecl *), SeparatelyCached, NoLocationInfo)
154+
SWIFT_REQUEST(TypeChecker, ParamSpecifierRequest,
155+
ParamDecl::Specifier(ParamDecl *), SeparatelyCached, NoLocationInfo)

lib/AST/ASTDumper.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -967,19 +967,21 @@ namespace {
967967
PrintWithColorRAII(OS, InterfaceTypeColor) << "'";
968968
}
969969

970-
switch (P->getSpecifier()) {
971-
case ParamDecl::Specifier::Default:
972-
/* nothing */
973-
break;
974-
case ParamDecl::Specifier::InOut:
975-
OS << " inout";
976-
break;
977-
case ParamDecl::Specifier::Shared:
978-
OS << " shared";
979-
break;
980-
case ParamDecl::Specifier::Owned:
981-
OS << " owned";
982-
break;
970+
if (auto specifier = P->getCachedSpecifier()) {
971+
switch (*specifier) {
972+
case ParamDecl::Specifier::Default:
973+
/* nothing */
974+
break;
975+
case ParamDecl::Specifier::InOut:
976+
OS << " inout";
977+
break;
978+
case ParamDecl::Specifier::Shared:
979+
OS << " shared";
980+
break;
981+
case ParamDecl::Specifier::Owned:
982+
OS << " owned";
983+
break;
984+
}
983985
}
984986

985987
if (P->isVariadic())

lib/AST/Builtins.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,9 @@ getBuiltinFunction(Identifier Id, ArrayRef<Type> argTypes, Type ResType,
158158

159159
SmallVector<ParamDecl*, 4> params;
160160
for (Type argType : argTypes) {
161-
auto PD = new (Context)
162-
ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
163-
Identifier(), SourceLoc(), Identifier(), DC);
161+
auto PD = new (Context) ParamDecl(SourceLoc(), SourceLoc(),
162+
Identifier(), SourceLoc(), Identifier(), DC);
163+
PD->setSpecifier(ParamSpecifier::Default);
164164
PD->setInterfaceType(argType);
165165
PD->setImplicit();
166166
params.push_back(PD);
@@ -202,10 +202,10 @@ getBuiltinGenericFunction(Identifier Id,
202202
auto specifier =
203203
ParamDecl::getParameterSpecifierForValueOwnership(
204204
ArgParamTypes[i].getParameterFlags().getValueOwnership());
205-
auto PD = new (Context) ParamDecl(specifier,
206-
SourceLoc(), SourceLoc(),
205+
auto PD = new (Context) ParamDecl(SourceLoc(), SourceLoc(),
207206
Identifier(), SourceLoc(),
208207
Identifier(), DC);
208+
PD->setSpecifier(specifier);
209209
PD->setInterfaceType(paramIfaceType);
210210
PD->setImplicit();
211211
params.push_back(PD);

lib/AST/Decl.cpp

Lines changed: 21 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,14 +1352,15 @@ ParamDecl *PatternBindingInitializer::getImplicitSelfDecl() {
13521352
auto DC = singleVar->getDeclContext();
13531353
if (DC->isTypeContext()) {
13541354
auto specifier = (DC->getDeclaredInterfaceType()->hasReferenceSemantics()
1355-
? ParamDecl::Specifier::Default
1356-
: ParamDecl::Specifier::InOut);
1355+
? ParamSpecifier::Default
1356+
: ParamSpecifier::InOut);
13571357

13581358
ASTContext &C = DC->getASTContext();
1359-
SelfParam = new (C) ParamDecl(specifier, SourceLoc(), SourceLoc(),
1359+
SelfParam = new (C) ParamDecl(SourceLoc(), SourceLoc(),
13601360
Identifier(), singleVar->getLoc(),
13611361
C.Id_self, this);
13621362
SelfParam->setImplicit();
1363+
SelfParam->setSpecifier(specifier);
13631364
SelfParam->setInterfaceType(DC->getSelfInterfaceType());
13641365
}
13651366
}
@@ -5455,15 +5456,11 @@ bool VarDecl::isMemberwiseInitialized(bool preferDeclaredProperties) const {
54555456
void ParamDecl::setSpecifier(Specifier specifier) {
54565457
// FIXME: Revisit this; in particular shouldn't __owned parameters be
54575458
// ::Let also?
5458-
setIntroducer(specifier == ParamDecl::Specifier::Default
5459+
setIntroducer(specifier == ParamSpecifier::Default
54595460
? VarDecl::Introducer::Let
54605461
: VarDecl::Introducer::Var);
54615462
Bits.ParamDecl.Specifier = static_cast<unsigned>(specifier);
5462-
setImplInfo(
5463-
StorageImplInfo::getSimpleStored(
5464-
isImmutableSpecifier(specifier)
5465-
? StorageIsNotMutable
5466-
: StorageIsMutable));
5463+
Bits.ParamDecl.SpecifierComputed = true;
54675464
}
54685465

54695466
bool ParamDecl::isAnonClosureParam() const {
@@ -5478,6 +5475,15 @@ bool ParamDecl::isAnonClosureParam() const {
54785475
return nameStr[0] == '$';
54795476
}
54805477

5478+
ParamDecl::Specifier ParamDecl::getSpecifier() const {
5479+
auto &ctx = getASTContext();
5480+
5481+
auto mutableThis = const_cast<ParamDecl *>(this);
5482+
return evaluateOrDefault(ctx.evaluator,
5483+
ParamSpecifierRequest{mutableThis},
5484+
ParamDecl::Specifier::Default);
5485+
}
5486+
54815487
StaticSpellingKind AbstractStorageDecl::getCorrectStaticSpelling() const {
54825488
if (!isStatic())
54835489
return StaticSpellingKind::None;
@@ -5708,21 +5714,18 @@ void VarDecl::emitLetToVarNoteIfSimple(DeclContext *UseDC) const {
57085714
}
57095715
}
57105716

5711-
ParamDecl::ParamDecl(Specifier specifier, SourceLoc specifierLoc,
5717+
ParamDecl::ParamDecl(SourceLoc specifierLoc,
57125718
SourceLoc argumentNameLoc, Identifier argumentName,
57135719
SourceLoc parameterNameLoc, Identifier parameterName,
57145720
DeclContext *dc)
57155721
: VarDecl(DeclKind::Param,
57165722
/*IsStatic*/ false,
5717-
specifier == ParamDecl::Specifier::Default
5718-
? VarDecl::Introducer::Let
5719-
: VarDecl::Introducer::Var,
5723+
VarDecl::Introducer::Let,
57205724
/*IsCaptureList*/ false, parameterNameLoc, parameterName, dc,
5721-
StorageIsMutable_t(!isImmutableSpecifier(specifier))),
5725+
StorageIsNotMutable),
57225726
ArgumentName(argumentName), ParameterNameLoc(parameterNameLoc),
57235727
ArgumentNameLoc(argumentNameLoc), SpecifierLoc(specifierLoc) {
5724-
5725-
Bits.ParamDecl.Specifier = static_cast<unsigned>(specifier);
5728+
Bits.ParamDecl.SpecifierComputed = false;
57265729
Bits.ParamDecl.IsTypeLocImplicit = false;
57275730
Bits.ParamDecl.defaultArgumentKind =
57285731
static_cast<unsigned>(DefaultArgumentKind::None);
@@ -5739,7 +5742,6 @@ ParamDecl::ParamDecl(ParamDecl *PD, bool withTypes)
57395742
ArgumentNameLoc(PD->getArgumentNameLoc()),
57405743
SpecifierLoc(PD->getSpecifierLoc()),
57415744
DefaultValueAndFlags(nullptr, PD->DefaultValueAndFlags.getInt()) {
5742-
Bits.ParamDecl.Specifier = static_cast<unsigned>(PD->getSpecifier());
57435745
Bits.ParamDecl.IsTypeLocImplicit = PD->Bits.ParamDecl.IsTypeLocImplicit;
57445746
Bits.ParamDecl.defaultArgumentKind = PD->Bits.ParamDecl.defaultArgumentKind;
57455747
typeLoc = PD->getTypeLoc().clone(PD->getASTContext());
@@ -5749,6 +5751,7 @@ ParamDecl::ParamDecl(ParamDecl *PD, bool withTypes)
57495751
if (withTypes && PD->hasInterfaceType())
57505752
setInterfaceType(PD->getInterfaceType());
57515753

5754+
setSpecifier(PD->getSpecifier());
57525755
setImplicitlyUnwrappedOptional(PD->isImplicitlyUnwrappedOptional());
57535756
}
57545757

@@ -6547,41 +6550,13 @@ ParamDecl *AbstractFunctionDecl::getImplicitSelfDecl(bool createIfNeeded) {
65476550

65486551
// Create and save our 'self' parameter.
65496552
auto &ctx = getASTContext();
6550-
*selfDecl = new (ctx) ParamDecl(ParamDecl::Specifier::Default,
6551-
SourceLoc(), SourceLoc(), Identifier(),
6553+
*selfDecl = new (ctx) ParamDecl(SourceLoc(), SourceLoc(), Identifier(),
65526554
getLoc(), ctx.Id_self, this);
65536555
(*selfDecl)->setImplicit();
65546556

6555-
// If we already have an interface type, compute the 'self' parameter type.
6556-
// Otherwise, we'll do it later.
6557-
if (hasInterfaceType())
6558-
computeSelfDeclType();
6559-
65606557
return *selfDecl;
65616558
}
65626559

6563-
void AbstractFunctionDecl::computeSelfDeclType() {
6564-
assert(hasImplicitSelfDecl());
6565-
assert(hasInterfaceType());
6566-
6567-
auto *selfDecl = getImplicitSelfDecl(/*createIfNeeded=*/false);
6568-
6569-
// If we haven't created a 'self' parameter yet, do nothing, we'll compute
6570-
// the type later.
6571-
if (selfDecl == nullptr)
6572-
return;
6573-
6574-
auto selfParam = computeSelfParam(this,
6575-
/*isInitializingCtor*/true,
6576-
/*wantDynamicSelf*/true);
6577-
selfDecl->setInterfaceType(selfParam.getPlainType());
6578-
6579-
auto specifier = selfParam.getParameterFlags().isInOut()
6580-
? ParamDecl::Specifier::InOut
6581-
: ParamDecl::Specifier::Default;
6582-
selfDecl->setSpecifier(specifier);
6583-
}
6584-
65856560
void AbstractFunctionDecl::setParameters(ParameterList *BodyParams) {
65866561
#ifndef NDEBUG
65876562
auto Name = getFullName();
@@ -6703,14 +6678,6 @@ void AbstractFunctionDecl::computeType(AnyFunctionType::ExtInfo info) {
67036678

67046679
// Record the interface type.
67056680
setInterfaceType(funcTy);
6706-
6707-
// Compute the type of the 'self' parameter if we're created one already.
6708-
if (hasSelf)
6709-
computeSelfDeclType();
6710-
6711-
// Make sure that there are no unresolved dependent types in the
6712-
// generic signature.
6713-
assert(!funcTy->findUnresolvedDependentMemberType());
67146681
}
67156682

67166683
bool AbstractFunctionDecl::hasInlinableBodyText() const {

lib/AST/TypeCheckRequests.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -926,3 +926,17 @@ void NeedsNewVTableEntryRequest::cacheResult(bool value) const {
926926
decl->LazySemanticInfo.NeedsNewVTableEntryComputed = true;
927927
decl->LazySemanticInfo.NeedsNewVTableEntry = value;
928928
}
929+
930+
//----------------------------------------------------------------------------//
931+
// ParamSpecifierRequest computation.
932+
//----------------------------------------------------------------------------//
933+
934+
Optional<ParamSpecifier> ParamSpecifierRequest::getCachedResult() const {
935+
auto *decl = std::get<0>(getStorage());
936+
return decl->getCachedSpecifier();
937+
}
938+
939+
void ParamSpecifierRequest::cacheResult(ParamSpecifier specifier) const {
940+
auto *decl = std::get<0>(getStorage());
941+
decl->setSpecifier(specifier);
942+
}

0 commit comments

Comments
 (0)