mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Sema] Requestify areAllStoredPropertiesDefaultInitializable
This commit is contained in:
@@ -1508,6 +1508,26 @@ public:
|
|||||||
bool isCached() const { return true; }
|
bool isCached() const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Computes whether all of the stored properties in a nominal type have initial
|
||||||
|
/// values.
|
||||||
|
class AreAllStoredPropertiesDefaultInitableRequest
|
||||||
|
: public SimpleRequest<AreAllStoredPropertiesDefaultInitableRequest,
|
||||||
|
bool(NominalTypeDecl *), CacheKind::Cached> {
|
||||||
|
public:
|
||||||
|
using SimpleRequest::SimpleRequest;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend SimpleRequest;
|
||||||
|
|
||||||
|
// Evaluation.
|
||||||
|
llvm::Expected<bool> evaluate(Evaluator &evaluator,
|
||||||
|
NominalTypeDecl *decl) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Caching.
|
||||||
|
bool isCached() const { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
// Allow AnyValue to compare two Type values, even though Type doesn't
|
// Allow AnyValue to compare two Type values, even though Type doesn't
|
||||||
// support ==.
|
// support ==.
|
||||||
template<>
|
template<>
|
||||||
|
|||||||
@@ -165,3 +165,5 @@ SWIFT_REQUEST(TypeChecker, ParamSpecifierRequest,
|
|||||||
ParamDecl::Specifier(ParamDecl *), SeparatelyCached, NoLocationInfo)
|
ParamDecl::Specifier(ParamDecl *), SeparatelyCached, NoLocationInfo)
|
||||||
SWIFT_REQUEST(TypeChecker, ResultTypeRequest,
|
SWIFT_REQUEST(TypeChecker, ResultTypeRequest,
|
||||||
Type(ValueDecl *), SeparatelyCached, NoLocationInfo)
|
Type(ValueDecl *), SeparatelyCached, NoLocationInfo)
|
||||||
|
SWIFT_REQUEST(TypeChecker, AreAllStoredPropertiesDefaultInitableRequest,
|
||||||
|
bool(NominalTypeDecl *), Cached, NoLocationInfo)
|
||||||
|
|||||||
@@ -800,9 +800,9 @@ static void diagnoseMissingRequiredInitializer(
|
|||||||
diag::required_initializer_here);
|
diag::required_initializer_here);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool areAllStoredPropertiesDefaultInitializable(NominalTypeDecl *decl) {
|
llvm::Expected<bool> AreAllStoredPropertiesDefaultInitableRequest::evaluate(
|
||||||
if (decl->hasClangNode())
|
Evaluator &evaluator, NominalTypeDecl *decl) const {
|
||||||
return true;
|
assert(!decl->hasClangNode());
|
||||||
|
|
||||||
for (auto member : decl->getMembers()) {
|
for (auto member : decl->getMembers()) {
|
||||||
// If a stored property lacks an initial value and if there is no way to
|
// If a stored property lacks an initial value and if there is no way to
|
||||||
@@ -833,6 +833,15 @@ static bool areAllStoredPropertiesDefaultInitializable(NominalTypeDecl *decl) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool areAllStoredPropertiesDefaultInitializable(Evaluator &eval,
|
||||||
|
NominalTypeDecl *decl) {
|
||||||
|
if (decl->hasClangNode())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return evaluateOrDefault(
|
||||||
|
eval, AreAllStoredPropertiesDefaultInitableRequest{decl}, false);
|
||||||
|
}
|
||||||
|
|
||||||
static void addImplicitConstructorsToStruct(StructDecl *decl) {
|
static void addImplicitConstructorsToStruct(StructDecl *decl) {
|
||||||
assert(!decl->hasClangNode() &&
|
assert(!decl->hasClangNode() &&
|
||||||
"ClangImporter is responsible for adding implicit constructors");
|
"ClangImporter is responsible for adding implicit constructors");
|
||||||
@@ -864,15 +873,15 @@ static void addImplicitConstructorsToStruct(StructDecl *decl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto &ctx = decl->getASTContext();
|
||||||
if (FoundMemberwiseInitializedProperty) {
|
if (FoundMemberwiseInitializedProperty) {
|
||||||
// Create the implicit memberwise constructor.
|
// Create the implicit memberwise constructor.
|
||||||
auto &ctx = decl->getASTContext();
|
|
||||||
auto ctor = createImplicitConstructor(
|
auto ctor = createImplicitConstructor(
|
||||||
decl, ImplicitConstructorKind::Memberwise, ctx);
|
decl, ImplicitConstructorKind::Memberwise, ctx);
|
||||||
decl->addMember(ctor);
|
decl->addMember(ctor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (areAllStoredPropertiesDefaultInitializable(decl))
|
if (areAllStoredPropertiesDefaultInitializable(ctx.evaluator, decl))
|
||||||
TypeChecker::defineDefaultConstructor(decl);
|
TypeChecker::defineDefaultConstructor(decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -932,21 +941,18 @@ static void addImplicitConstructorsToClass(ClassDecl *decl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SuppressDefaultInitializer =
|
bool defaultInitable =
|
||||||
!areAllStoredPropertiesDefaultInitializable(decl);
|
areAllStoredPropertiesDefaultInitializable(ctx.evaluator, decl);
|
||||||
|
|
||||||
// For a class with a superclass, automatically define overrides
|
// For a class with a superclass, automatically define overrides
|
||||||
// for all of the superclass's designated initializers.
|
// for all of the superclass's designated initializers.
|
||||||
if (Type superclassTy = decl->getSuperclass()) {
|
if (Type superclassTy = decl->getSuperclass()) {
|
||||||
bool canInheritInitializers = (!SuppressDefaultInitializer &&
|
bool canInheritInitializers = defaultInitable && !FoundDesignatedInit;
|
||||||
!FoundDesignatedInit);
|
|
||||||
|
|
||||||
// We can't define these overrides if we have any uninitialized
|
// We can't define these overrides if we have any uninitialized
|
||||||
// stored properties.
|
// stored properties.
|
||||||
if (SuppressDefaultInitializer && !FoundDesignatedInit &&
|
if (!defaultInitable && !FoundDesignatedInit && !decl->hasClangNode())
|
||||||
!decl->hasClangNode()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
auto *superclassDecl = superclassTy->getClassOrBoundGenericClass();
|
auto *superclassDecl = superclassTy->getClassOrBoundGenericClass();
|
||||||
assert(superclassDecl && "Superclass of class is not a class?");
|
assert(superclassDecl && "Superclass of class is not a class?");
|
||||||
@@ -1056,7 +1062,7 @@ static void addImplicitConstructorsToClass(ClassDecl *decl) {
|
|||||||
// constructor.
|
// constructor.
|
||||||
|
|
||||||
// ... unless there are uninitialized stored properties.
|
// ... unless there are uninitialized stored properties.
|
||||||
if (SuppressDefaultInitializer)
|
if (!defaultInitable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Clang-imported types should never get a default constructor, just a
|
// Clang-imported types should never get a default constructor, just a
|
||||||
|
|||||||
Reference in New Issue
Block a user