Skip to content

Circular validation cleanups, part 5 #27571

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
1 change: 1 addition & 0 deletions include/swift/AST/ASTTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
SWIFT_TYPEID(AncestryFlags)
SWIFT_TYPEID(CtorInitializerKind)
SWIFT_TYPEID(GenericSignature)
SWIFT_TYPEID(ParamSpecifier)
SWIFT_TYPEID(PropertyWrapperBackingPropertyInfo)
SWIFT_TYPEID(PropertyWrapperTypeInfo)
SWIFT_TYPEID(Requirement)
Expand Down
2 changes: 2 additions & 0 deletions include/swift/AST/ASTTypeIDs.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class ModuleDecl;
class NominalTypeDecl;
class OperatorDecl;
class OpaqueTypeDecl;
class ParamDecl;
enum class ParamSpecifier : uint8_t;
class PrecedenceGroupDecl;
struct PropertyWrapperBackingPropertyInfo;
struct PropertyWrapperTypeInfo;
Expand Down
42 changes: 24 additions & 18 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,10 @@ class alignas(1 << DeclAlignInBits) Decl {
IsPropertyWrapperBackingProperty : 1
);

SWIFT_INLINE_BITFIELD(ParamDecl, VarDecl, 2+1+NumDefaultArgumentKindBits,
SWIFT_INLINE_BITFIELD(ParamDecl, VarDecl, 1+2+1+NumDefaultArgumentKindBits,
/// Whether we've computed the specifier yet.
SpecifierComputed : 1,

/// The specifier associated with this parameter. This determines
/// the storage semantics of the value e.g. mutability.
Specifier : 2,
Expand Down Expand Up @@ -5158,6 +5161,13 @@ class VarDecl : public AbstractStorageDecl {
}
};

enum class ParamSpecifier : uint8_t {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'long as we're here, can we pick a better name than "Specifier"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I'm all ears :) I believe one of your refactorings introduced the name Specifier, but I might be wrong :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did it back then because the it's the name the Swift Book's "grammar" gives it.

Default = 0,
InOut = 1,
Shared = 2,
Owned = 3,
};

/// A function parameter declaration.
class ParamDecl : public VarDecl {
Identifier ArgumentName;
Expand All @@ -5184,16 +5194,10 @@ class ParamDecl : public VarDecl {
llvm::PointerIntPair<StoredDefaultArgument *, 2, OptionSet<Flags>>
DefaultValueAndFlags;

public:
enum class Specifier : uint8_t {
Default = 0,
InOut = 1,
Shared = 2,
Owned = 3,
};
friend class ParamSpecifierRequest;

ParamDecl(Specifier specifier,
SourceLoc specifierLoc, SourceLoc argumentNameLoc,
public:
ParamDecl(SourceLoc specifierLoc, SourceLoc argumentNameLoc,
Identifier argumentName, SourceLoc parameterNameLoc,
Identifier parameterName, DeclContext *dc);

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

/// Return the raw specifier value for this parameter.
Specifier getSpecifier() const {
return static_cast<Specifier>(Bits.ParamDecl.Specifier);
using Specifier = ParamSpecifier;

Optional<Specifier> getCachedSpecifier() const {
if (Bits.ParamDecl.SpecifierComputed)
return Specifier(Bits.ParamDecl.Specifier);

return None;
}

/// Return the raw specifier value for this parameter.
Specifier getSpecifier() const;
void setSpecifier(Specifier Spec);

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

private:
void computeNeedsNewVTableEntry();

void computeSelfDeclType();

public:
/// Compute the interface type of this function declaration from the
/// parameter types.
Expand Down
27 changes: 27 additions & 0 deletions include/swift/AST/TypeCheckRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,7 @@ class OperatorPrecedenceGroupRequest
bool isCached() const { return true; }
};

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

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

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

/// Determines the specifier for a parameter (inout, __owned, etc).
class ParamSpecifierRequest
: public SimpleRequest<ParamSpecifierRequest,
ParamSpecifier(ParamDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

// Evaluation.
llvm::Expected<ParamSpecifier>
evaluate(Evaluator &evaluator, ParamDecl *decl) const;

public:
// Separate caching.
bool isCached() const { return true; }
Optional<ParamSpecifier> getCachedResult() const;
void cacheResult(ParamSpecifier value) const;
};

// Allow AnyValue to compare two Type values, even though Type doesn't
// support ==.
template<>
Expand Down
2 changes: 2 additions & 0 deletions include/swift/AST/TypeCheckerTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,5 @@ SWIFT_REQUEST(TypeChecker, IsStaticRequest,
bool(FuncDecl *), SeparatelyCached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, NeedsNewVTableEntryRequest,
bool(AbstractFunctionDecl *), SeparatelyCached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, ParamSpecifierRequest,
ParamDecl::Specifier(ParamDecl *), SeparatelyCached, NoLocationInfo)
28 changes: 15 additions & 13 deletions lib/AST/ASTDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -967,19 +967,21 @@ namespace {
PrintWithColorRAII(OS, InterfaceTypeColor) << "'";
}

switch (P->getSpecifier()) {
case ParamDecl::Specifier::Default:
/* nothing */
break;
case ParamDecl::Specifier::InOut:
OS << " inout";
break;
case ParamDecl::Specifier::Shared:
OS << " shared";
break;
case ParamDecl::Specifier::Owned:
OS << " owned";
break;
if (auto specifier = P->getCachedSpecifier()) {
switch (*specifier) {
case ParamDecl::Specifier::Default:
/* nothing */
break;
case ParamDecl::Specifier::InOut:
OS << " inout";
break;
case ParamDecl::Specifier::Shared:
OS << " shared";
break;
case ParamDecl::Specifier::Owned:
OS << " owned";
break;
}
}

if (P->isVariadic())
Expand Down
10 changes: 5 additions & 5 deletions lib/AST/Builtins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,9 @@ getBuiltinFunction(Identifier Id, ArrayRef<Type> argTypes, Type ResType,

SmallVector<ParamDecl*, 4> params;
for (Type argType : argTypes) {
auto PD = new (Context)
ParamDecl(ParamDecl::Specifier::Default, SourceLoc(), SourceLoc(),
Identifier(), SourceLoc(), Identifier(), DC);
auto PD = new (Context) ParamDecl(SourceLoc(), SourceLoc(),
Identifier(), SourceLoc(), Identifier(), DC);
PD->setSpecifier(ParamSpecifier::Default);
PD->setInterfaceType(argType);
PD->setImplicit();
params.push_back(PD);
Expand Down Expand Up @@ -202,10 +202,10 @@ getBuiltinGenericFunction(Identifier Id,
auto specifier =
ParamDecl::getParameterSpecifierForValueOwnership(
ArgParamTypes[i].getParameterFlags().getValueOwnership());
auto PD = new (Context) ParamDecl(specifier,
SourceLoc(), SourceLoc(),
auto PD = new (Context) ParamDecl(SourceLoc(), SourceLoc(),
Identifier(), SourceLoc(),
Identifier(), DC);
PD->setSpecifier(specifier);
PD->setInterfaceType(paramIfaceType);
PD->setImplicit();
params.push_back(PD);
Expand Down
75 changes: 21 additions & 54 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1352,14 +1352,15 @@ ParamDecl *PatternBindingInitializer::getImplicitSelfDecl() {
auto DC = singleVar->getDeclContext();
if (DC->isTypeContext()) {
auto specifier = (DC->getDeclaredInterfaceType()->hasReferenceSemantics()
? ParamDecl::Specifier::Default
: ParamDecl::Specifier::InOut);
? ParamSpecifier::Default
: ParamSpecifier::InOut);

ASTContext &C = DC->getASTContext();
SelfParam = new (C) ParamDecl(specifier, SourceLoc(), SourceLoc(),
SelfParam = new (C) ParamDecl(SourceLoc(), SourceLoc(),
Identifier(), singleVar->getLoc(),
C.Id_self, this);
SelfParam->setImplicit();
SelfParam->setSpecifier(specifier);
SelfParam->setInterfaceType(DC->getSelfInterfaceType());
}
}
Expand Down Expand Up @@ -5455,15 +5456,11 @@ bool VarDecl::isMemberwiseInitialized(bool preferDeclaredProperties) const {
void ParamDecl::setSpecifier(Specifier specifier) {
// FIXME: Revisit this; in particular shouldn't __owned parameters be
// ::Let also?
setIntroducer(specifier == ParamDecl::Specifier::Default
setIntroducer(specifier == ParamSpecifier::Default
? VarDecl::Introducer::Let
: VarDecl::Introducer::Var);
Bits.ParamDecl.Specifier = static_cast<unsigned>(specifier);
setImplInfo(
StorageImplInfo::getSimpleStored(
isImmutableSpecifier(specifier)
? StorageIsNotMutable
: StorageIsMutable));
Bits.ParamDecl.SpecifierComputed = true;
}

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

ParamDecl::Specifier ParamDecl::getSpecifier() const {
auto &ctx = getASTContext();

auto mutableThis = const_cast<ParamDecl *>(this);
return evaluateOrDefault(ctx.evaluator,
ParamSpecifierRequest{mutableThis},
ParamDecl::Specifier::Default);
}

StaticSpellingKind AbstractStorageDecl::getCorrectStaticSpelling() const {
if (!isStatic())
return StaticSpellingKind::None;
Expand Down Expand Up @@ -5714,21 +5720,18 @@ void VarDecl::emitLetToVarNoteIfSimple(DeclContext *UseDC) const {
}
}

ParamDecl::ParamDecl(Specifier specifier, SourceLoc specifierLoc,
ParamDecl::ParamDecl(SourceLoc specifierLoc,
SourceLoc argumentNameLoc, Identifier argumentName,
SourceLoc parameterNameLoc, Identifier parameterName,
DeclContext *dc)
: VarDecl(DeclKind::Param,
/*IsStatic*/ false,
specifier == ParamDecl::Specifier::Default
? VarDecl::Introducer::Let
: VarDecl::Introducer::Var,
VarDecl::Introducer::Let,
/*IsCaptureList*/ false, parameterNameLoc, parameterName, dc,
StorageIsMutable_t(!isImmutableSpecifier(specifier))),
StorageIsNotMutable),
ArgumentName(argumentName), ParameterNameLoc(parameterNameLoc),
ArgumentNameLoc(argumentNameLoc), SpecifierLoc(specifierLoc) {

Bits.ParamDecl.Specifier = static_cast<unsigned>(specifier);
Bits.ParamDecl.SpecifierComputed = false;
Bits.ParamDecl.IsTypeLocImplicit = false;
Bits.ParamDecl.defaultArgumentKind =
static_cast<unsigned>(DefaultArgumentKind::None);
Expand All @@ -5745,7 +5748,6 @@ ParamDecl::ParamDecl(ParamDecl *PD, bool withTypes)
ArgumentNameLoc(PD->getArgumentNameLoc()),
SpecifierLoc(PD->getSpecifierLoc()),
DefaultValueAndFlags(nullptr, PD->DefaultValueAndFlags.getInt()) {
Bits.ParamDecl.Specifier = static_cast<unsigned>(PD->getSpecifier());
Bits.ParamDecl.IsTypeLocImplicit = PD->Bits.ParamDecl.IsTypeLocImplicit;
Bits.ParamDecl.defaultArgumentKind = PD->Bits.ParamDecl.defaultArgumentKind;
typeLoc = PD->getTypeLoc().clone(PD->getASTContext());
Expand All @@ -5755,6 +5757,7 @@ ParamDecl::ParamDecl(ParamDecl *PD, bool withTypes)
if (withTypes && PD->hasInterfaceType())
setInterfaceType(PD->getInterfaceType());

setSpecifier(PD->getSpecifier());
setImplicitlyUnwrappedOptional(PD->isImplicitlyUnwrappedOptional());
}

Expand Down Expand Up @@ -6553,41 +6556,13 @@ ParamDecl *AbstractFunctionDecl::getImplicitSelfDecl(bool createIfNeeded) {

// Create and save our 'self' parameter.
auto &ctx = getASTContext();
*selfDecl = new (ctx) ParamDecl(ParamDecl::Specifier::Default,
SourceLoc(), SourceLoc(), Identifier(),
*selfDecl = new (ctx) ParamDecl(SourceLoc(), SourceLoc(), Identifier(),
getLoc(), ctx.Id_self, this);
(*selfDecl)->setImplicit();

// If we already have an interface type, compute the 'self' parameter type.
// Otherwise, we'll do it later.
if (hasInterfaceType())
computeSelfDeclType();

return *selfDecl;
}

void AbstractFunctionDecl::computeSelfDeclType() {
assert(hasImplicitSelfDecl());
assert(hasInterfaceType());

auto *selfDecl = getImplicitSelfDecl(/*createIfNeeded=*/false);

// If we haven't created a 'self' parameter yet, do nothing, we'll compute
// the type later.
if (selfDecl == nullptr)
return;

auto selfParam = computeSelfParam(this,
/*isInitializingCtor*/true,
/*wantDynamicSelf*/true);
selfDecl->setInterfaceType(selfParam.getPlainType());

auto specifier = selfParam.getParameterFlags().isInOut()
? ParamDecl::Specifier::InOut
: ParamDecl::Specifier::Default;
selfDecl->setSpecifier(specifier);
}

void AbstractFunctionDecl::setParameters(ParameterList *BodyParams) {
#ifndef NDEBUG
auto Name = getFullName();
Expand Down Expand Up @@ -6709,14 +6684,6 @@ void AbstractFunctionDecl::computeType(AnyFunctionType::ExtInfo info) {

// Record the interface type.
setInterfaceType(funcTy);

// Compute the type of the 'self' parameter if we're created one already.
if (hasSelf)
computeSelfDeclType();

// Make sure that there are no unresolved dependent types in the
// generic signature.
assert(!funcTy->findUnresolvedDependentMemberType());
}

bool AbstractFunctionDecl::hasInlinableBodyText() const {
Expand Down
14 changes: 14 additions & 0 deletions lib/AST/TypeCheckRequests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -926,3 +926,17 @@ void NeedsNewVTableEntryRequest::cacheResult(bool value) const {
decl->LazySemanticInfo.NeedsNewVTableEntryComputed = true;
decl->LazySemanticInfo.NeedsNewVTableEntry = value;
}

//----------------------------------------------------------------------------//
// ParamSpecifierRequest computation.
//----------------------------------------------------------------------------//

Optional<ParamSpecifier> ParamSpecifierRequest::getCachedResult() const {
auto *decl = std::get<0>(getStorage());
return decl->getCachedSpecifier();
}

void ParamSpecifierRequest::cacheResult(ParamSpecifier specifier) const {
auto *decl = std::get<0>(getStorage());
decl->setSpecifier(specifier);
}
Loading