Skip to content

Circular validation cleanups, part 3 #27546

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
3 changes: 0 additions & 3 deletions include/swift/AST/ASTDemangler.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,6 @@ class ASTBuilder {
using BuiltTypeDecl = swift::GenericTypeDecl *; // nominal or type alias
using BuiltProtocolDecl = swift::ProtocolDecl *;
explicit ASTBuilder(ASTContext &ctx) : Ctx(ctx) {}

/// The resolver to use for type checking, if necessary.
LazyResolver *Resolver = nullptr;

ASTContext &getASTContext() { return Ctx; }
DeclContext *getNotionalDC();
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/ASTTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ SWIFT_TYPEID_NAMED(InfixOperatorDecl *, InfixOperatorDecl)
SWIFT_TYPEID_NAMED(IterableDeclContext *, IterableDeclContext)
SWIFT_TYPEID_NAMED(ModuleDecl *, ModuleDecl)
SWIFT_TYPEID_NAMED(NominalTypeDecl *, NominalTypeDecl)
SWIFT_TYPEID_NAMED(OpaqueTypeDecl *, OpaqueTypeDecl)
SWIFT_TYPEID_NAMED(OperatorDecl *, OperatorDecl)
SWIFT_TYPEID_NAMED(Optional<PropertyWrapperMutability>,
PropertyWrapperMutability)
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/ASTTypeIDs.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class IterableDeclContext;
class ModuleDecl;
class NominalTypeDecl;
class OperatorDecl;
class OpaqueTypeDecl;
class PrecedenceGroupDecl;
struct PropertyWrapperBackingPropertyInfo;
struct PropertyWrapperTypeInfo;
Expand Down
65 changes: 21 additions & 44 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,10 @@ class alignas(1 << DeclAlignInBits) Decl {
HasSingleExpressionBody : 1
);

SWIFT_INLINE_BITFIELD(FuncDecl, AbstractFunctionDecl, 1+2+1+1+2,
SWIFT_INLINE_BITFIELD(FuncDecl, AbstractFunctionDecl, 1+1+2+1+1+2,
/// Whether we've computed the 'static' flag yet.
IsStaticComputed : 1,

/// Whether this function is a 'static' method.
IsStatic : 1,

Expand Down Expand Up @@ -854,17 +857,6 @@ class alignas(1 << DeclAlignInBits) Decl {
return getValidationState() > ValidationState::Unchecked;
}

/// Manually indicate that validation is complete for the declaration. For
/// example: during importing, code synthesis, or derived conformances.
///
/// For normal code validation, please use DeclValidationRAII instead.
///
/// FIXME -- Everything should use DeclValidationRAII instead of this.
void setValidationToChecked() {
if (!isBeingValidated())
Bits.Decl.ValidationState = unsigned(ValidationState::Checked);
}

bool escapedFromIfConfig() const {
return Bits.Decl.EscapedFromIfConfig;
}
Expand Down Expand Up @@ -2605,6 +2597,9 @@ class ValueDecl : public Decl {
/// if the base declaration is \c open, the override might have to be too.
bool hasOpenAccess(const DeclContext *useDC) const;

/// FIXME: This is deprecated.
bool isRecursiveValidation() const;

/// Retrieve the "interface" type of this value, which uses
/// GenericTypeParamType if the declaration is generic. For a generic
/// function, this will have a GenericFunctionType with a
Expand Down Expand Up @@ -2764,12 +2759,6 @@ class ValueDecl : public Decl {
/// Get the representative for this value's opaque result type, if it has one.
OpaqueReturnTypeRepr *getOpaqueResultTypeRepr() const;

/// Set the opaque return type decl for this decl.
///
/// `this` must be of a decl type that supports opaque return types, and
/// must not have previously had an opaque result type set.
void setOpaqueResultTypeDecl(OpaqueTypeDecl *D);

/// Retrieve the attribute associating this declaration with a
/// function builder, if there is one.
CustomAttr *getAttachedFunctionBuilder() const;
Expand Down Expand Up @@ -4530,8 +4519,6 @@ class AbstractStorageDecl : public ValueDecl {
Bits.AbstractStorageDecl.IsStatic = IsStatic;
}

OpaqueTypeDecl *OpaqueReturn = nullptr;

public:

/// Should this declaration be treated as if annotated with transparent
Expand Down Expand Up @@ -4789,14 +4776,6 @@ class AbstractStorageDecl : public ValueDecl {

bool hasAnyDynamicReplacementAccessors() const;

OpaqueTypeDecl *getOpaqueResultTypeDecl() const {
return OpaqueReturn;
}
void setOpaqueResultTypeDecl(OpaqueTypeDecl *decl) {
assert(!OpaqueReturn && "already has opaque type decl");
OpaqueReturn = decl;
}

// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() >= DeclKind::First_AbstractStorageDecl &&
Expand Down Expand Up @@ -5976,14 +5955,13 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, SelfAccessKind SAK);
class FuncDecl : public AbstractFunctionDecl {
friend class AbstractFunctionDecl;
friend class SelfAccessKindRequest;
friend class IsStaticRequest;

SourceLoc StaticLoc; // Location of the 'static' token or invalid.
SourceLoc FuncLoc; // Location of the 'func' token.

TypeLoc FnRetType;

OpaqueTypeDecl *OpaqueReturn = nullptr;

protected:
FuncDecl(DeclKind Kind,
SourceLoc StaticLoc, StaticSpellingKind StaticSpelling,
Expand All @@ -5999,14 +5977,14 @@ class FuncDecl : public AbstractFunctionDecl {
StaticLoc(StaticLoc), FuncLoc(FuncLoc) {
assert(!Name.getBaseName().isSpecial());

Bits.FuncDecl.IsStatic =
StaticLoc.isValid() || StaticSpelling != StaticSpellingKind::None;
Bits.FuncDecl.StaticSpelling = static_cast<unsigned>(StaticSpelling);

Bits.FuncDecl.ForcedStaticDispatch = false;
Bits.FuncDecl.SelfAccess =
static_cast<unsigned>(SelfAccessKind::NonMutating);
Bits.FuncDecl.SelfAccessComputed = false;
Bits.FuncDecl.IsStaticComputed = false;
Bits.FuncDecl.IsStatic = false;
}

private:
Expand All @@ -6026,6 +6004,13 @@ class FuncDecl : public AbstractFunctionDecl {
return None;
}

Optional<bool> getCachedIsStatic() const {
if (Bits.FuncDecl.IsStaticComputed)
return Bits.FuncDecl.IsStatic;

return None;
}

public:
/// Factory function only for use by deserialization.
static FuncDecl *createDeserialized(ASTContext &Context, SourceLoc StaticLoc,
Expand All @@ -6048,16 +6033,16 @@ class FuncDecl : public AbstractFunctionDecl {

Identifier getName() const { return getFullName().getBaseIdentifier(); }

bool isStatic() const {
return Bits.FuncDecl.IsStatic;
}
bool isStatic() const;

/// \returns the way 'static'/'class' was spelled in the source.
StaticSpellingKind getStaticSpelling() const {
return static_cast<StaticSpellingKind>(Bits.FuncDecl.StaticSpelling);
}
/// \returns the way 'static'/'class' should be spelled for this declaration.
StaticSpellingKind getCorrectStaticSpelling() const;
void setStatic(bool IsStatic = true) {
Bits.FuncDecl.IsStaticComputed = true;
Bits.FuncDecl.IsStatic = IsStatic;
}

Expand Down Expand Up @@ -6129,15 +6114,7 @@ class FuncDecl : public AbstractFunctionDecl {
}

OperatorDecl *getOperatorDecl() const;

OpaqueTypeDecl *getOpaqueResultTypeDecl() const {
return OpaqueReturn;
}
void setOpaqueResultTypeDecl(OpaqueTypeDecl *decl) {
assert(!OpaqueReturn && "already has opaque type decl");
OpaqueReturn = decl;
}


/// Returns true if the function is forced to be statically dispatched.
bool hasForcedStaticDispatch() const {
return Bits.FuncDecl.ForcedStaticDispatch;
Expand Down
3 changes: 1 addition & 2 deletions include/swift/AST/FileUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ class FileUnit : public DeclContext {

/// Look up an opaque return type by the mangled name of the declaration
/// that defines it.
virtual OpaqueTypeDecl *lookupOpaqueResultType(StringRef MangledName,
LazyResolver *resolver) {
virtual OpaqueTypeDecl *lookupOpaqueResultType(StringRef MangledName) {
return nullptr;
}

Expand Down
3 changes: 1 addition & 2 deletions include/swift/AST/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,8 +354,7 @@ class ModuleDecl : public DeclContext, public TypeDecl {

/// Look up an opaque return type by the mangled name of the declaration
/// that defines it.
OpaqueTypeDecl *lookupOpaqueResultType(StringRef MangledName,
LazyResolver *resolver);
OpaqueTypeDecl *lookupOpaqueResultType(StringRef MangledName);

/// Find ValueDecls in the module and pass them to the given consumer object.
///
Expand Down
19 changes: 9 additions & 10 deletions include/swift/AST/SourceFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@ class SourceFile final : public FileUnit {
/// The scope map that describes this source file.
std::unique_ptr<ASTScope> Scope;

/// The set of validated opaque return type decls in the source file.
llvm::SmallVector<OpaqueTypeDecl *, 4> OpaqueReturnTypes;
llvm::StringMap<OpaqueTypeDecl *> ValidatedOpaqueReturnTypes;
/// The set of parsed decls with opaque return types that have not yet
/// been validated.
llvm::SetVector<ValueDecl *> UnvalidatedDeclsWithOpaqueReturnTypes;

friend ASTContext;
friend Impl;
public:
Expand All @@ -130,13 +137,6 @@ class SourceFile final : public FileUnit {
/// The list of local type declarations in the source file.
llvm::SetVector<TypeDecl *> LocalTypeDecls;

/// The set of validated opaque return type decls in the source file.
llvm::SmallVector<OpaqueTypeDecl *, 4> OpaqueReturnTypes;
llvm::StringMap<OpaqueTypeDecl *> ValidatedOpaqueReturnTypes;
/// The set of parsed decls with opaque return types that have not yet
/// been validated.
llvm::DenseSet<ValueDecl *> UnvalidatedDeclsWithOpaqueReturnTypes;

/// A set of special declaration attributes which require the
/// Foundation module to be imported to work. If the foundation
/// module is still not imported by the time type checking is
Expand Down Expand Up @@ -430,14 +430,13 @@ class SourceFile final : public FileUnit {
void setSyntaxRoot(syntax::SourceFileSyntax &&Root);
bool hasSyntaxRoot() const;

OpaqueTypeDecl *lookupOpaqueResultType(StringRef MangledName,
LazyResolver *resolver) override;
OpaqueTypeDecl *lookupOpaqueResultType(StringRef MangledName) override;

void addUnvalidatedDeclWithOpaqueResultType(ValueDecl *vd) {
UnvalidatedDeclsWithOpaqueReturnTypes.insert(vd);
}

void markDeclWithOpaqueResultTypeAsValidated(ValueDecl *vd);
ArrayRef<OpaqueTypeDecl *> getOpaqueReturnTypeDecls();

private:

Expand Down
44 changes: 43 additions & 1 deletion include/swift/AST/TypeCheckRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -1188,7 +1188,7 @@ class GenericSignatureRequest :
void cacheResult(GenericSignature value) const;
};

/// Compute the interface type of the underlying definition type of a typealias declaration.
/// Compute the underlying interface type of a typealias.
class UnderlyingTypeRequest :
public SimpleRequest<UnderlyingTypeRequest,
Type(TypeAliasDecl *),
Expand All @@ -1211,6 +1211,7 @@ class UnderlyingTypeRequest :
void diagnoseCycle(DiagnosticEngine &diags) const;
};

/// Looks up the precedence group of an operator declaration.
class OperatorPrecedenceGroupRequest
: public SimpleRequest<OperatorPrecedenceGroupRequest,
PrecedenceGroupDecl *(InfixOperatorDecl *),
Expand Down Expand Up @@ -1272,6 +1273,47 @@ class IsABICompatibleOverrideRequest
bool isCached() const { return true; }
};

/// Builds an opaque result type for a declaration.
class OpaqueResultTypeRequest
: public SimpleRequest<OpaqueResultTypeRequest,
OpaqueTypeDecl *(ValueDecl *),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

llvm::Expected<OpaqueTypeDecl *>
evaluate(Evaluator &evaluator, ValueDecl *VD) const;

public:
// Caching.
bool isCached() const { return true; }
};

/// Determines if a function declaration is 'static'.
class IsStaticRequest :
public SimpleRequest<IsStaticRequest,
bool(FuncDecl *),
CacheKind::SeparatelyCached> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

// Evaluation.
llvm::Expected<bool>
evaluate(Evaluator &evaluator, FuncDecl *value) const;

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

// Allow AnyValue to compare two Type values, even though Type doesn't
// support ==.
template<>
Expand Down
5 changes: 5 additions & 0 deletions include/swift/AST/TypeCheckerTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ SWIFT_REQUEST(TypeChecker, MangleLocalTypeDeclRequest,
SWIFT_REQUEST(TypeChecker, OpaqueReadOwnershipRequest,
OpaqueReadOwnership(AbstractStorageDecl *), SeparatelyCached,
NoLocationInfo)
SWIFT_REQUEST(TypeChecker, OpaqueResultTypeRequest,
OpaqueTypeDecl *(ValueDecl *),
Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, OperatorPrecedenceGroupRequest,
PrecedenceGroupDecl *(PrecedenceGroupDecl *),
Cached, NoLocationInfo)
Expand Down Expand Up @@ -144,3 +147,5 @@ SWIFT_REQUEST(TypeChecker, USRGenerationRequest, std::string(const ValueDecl *),
Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, IsABICompatibleOverrideRequest,
bool(ValueDecl *), Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, IsStaticRequest,
bool(FuncDecl *), SeparatelyCached, NoLocationInfo)
3 changes: 0 additions & 3 deletions include/swift/Sema/IDETypeChecking.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ namespace swift {
class ValueDecl;
class DeclName;

/// Typecheck a declaration parsed during code completion.
void typeCheckCompletionDecl(Decl *D);

/// Typecheck binding initializer at \p bindingIndex.
void typeCheckPatternBinding(PatternBindingDecl *PBD, unsigned bindingIndex);

Expand Down
2 changes: 1 addition & 1 deletion include/swift/Serialization/SerializedModuleLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ class SerializedASTFile final : public LoadedFile {
virtual TypeDecl *lookupLocalType(StringRef MangledName) const override;

virtual OpaqueTypeDecl *
lookupOpaqueResultType(StringRef MangledName, LazyResolver *resolver) override;
lookupOpaqueResultType(StringRef MangledName) override;

virtual TypeDecl *
lookupNestedType(Identifier name,
Expand Down
3 changes: 1 addition & 2 deletions lib/AST/ASTDemangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,7 @@ Type ASTBuilder::resolveOpaqueType(NodePointer opaqueDescriptor,
if (!parentModule)
return Type();

auto opaqueDecl = parentModule->lookupOpaqueResultType(mangledName,
Resolver);
auto opaqueDecl = parentModule->lookupOpaqueResultType(mangledName);
if (!opaqueDecl)
return Type();
// TODO: multiple opaque types
Expand Down
6 changes: 0 additions & 6 deletions lib/AST/ASTVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3190,12 +3190,6 @@ class Verifier : public ASTWalker {
void verifyParsed(AccessorDecl *FD) {
PrettyStackTraceDecl debugStack("verifying AccessorDecl", FD);

auto storage = FD->getStorage();
if (storage->isStatic() != FD->isStatic()) {
Out << "accessor static-ness must match static-ness of storage\n";
abort();
}

verifyParsedBase(FD);
}

Expand Down
Loading