Skip to content

Commit 16cff49

Browse files
authored
[Sema] Requestify inheritsSuperclassInitializers (swiftlang#27936)
* [Sema] Factor out shouldAttemptInitializerSynthesis This makes sure we don't attempt to synthesize a memberwise or default initializer for an invalid decl, or one in a module interface. * [Sema] Requesify inheritsSuperclassInitializers This commit introduces a request for computing whether a class inherits both designated and convenience initializers from its superclass. The shared logic of finding initializers which the subclass hasn't overriden has been factored out into `collectNonOveriddenSuperclassInits`. * Cleanup addImplicitInheritedConstructorsToClass This commit removes some code that's no longer needed. In addition, now that we've requestified `inheritsSuperclassInitializers`, we can directly diagnose on non-inherited required convenience inits within the loop. * Inherited init synthesis no longer deals with clang decls Now that the computation of `inheritsSuperclassInitializers` has been split off into a request, we can avoid calling `addImplicitInheritedConstructorsToClass` for clang decls. * Address review feedback Continue to cache the InheritsSuperclassInits bit on the AST.
1 parent 1a5a8dd commit 16cff49

File tree

8 files changed

+183
-130
lines changed

8 files changed

+183
-130
lines changed

include/swift/AST/Decl.h

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -527,12 +527,13 @@ class alignas(1 << DeclAlignInBits) Decl {
527527
NumRequirementsInSignature : 16
528528
);
529529

530-
SWIFT_INLINE_BITFIELD(ClassDecl, NominalTypeDecl, 2+1+2+1+7+1+1+1+1+1+1,
530+
SWIFT_INLINE_BITFIELD(ClassDecl, NominalTypeDecl, 2+1+1+2+1+7+1+1+1+1+1+1,
531531
/// The stage of the inheritance circularity check for this class.
532532
Circularity : 2,
533533

534534
/// Whether this class inherits its superclass's convenience initializers.
535535
InheritsSuperclassInits : 1,
536+
ComputedInheritsSuperclassInits : 1,
536537

537538
/// \see ClassDecl::ForeignKind
538539
RawForeignKind : 2,
@@ -3810,9 +3811,24 @@ class ClassDecl final : public NominalTypeDecl {
38103811
Bits.ClassDecl.HasForcedEmittedMembers = true;
38113812
}
38123813

3814+
Optional<bool> getCachedInheritsSuperclassInitializers() const {
3815+
if (Bits.ClassDecl.ComputedInheritsSuperclassInits)
3816+
return Bits.ClassDecl.InheritsSuperclassInits;
3817+
3818+
return None;
3819+
}
3820+
3821+
/// Marks that this class inherits convenience initializers from its
3822+
/// superclass.
3823+
void setInheritsSuperclassInitializers(bool value) {
3824+
Bits.ClassDecl.InheritsSuperclassInits = value;
3825+
Bits.ClassDecl.ComputedInheritsSuperclassInits = true;
3826+
}
3827+
38133828
friend class SuperclassDeclRequest;
38143829
friend class SuperclassTypeRequest;
38153830
friend class EmittedMembersRequest;
3831+
friend class InheritsSuperclassInitializersRequest;
38163832
friend class TypeChecker;
38173833

38183834
public:
@@ -3970,15 +3986,6 @@ class ClassDecl final : public NominalTypeDecl {
39703986
/// from its superclass.
39713987
bool inheritsSuperclassInitializers();
39723988

3973-
/// Marks that this class inherits convenience initializers from its
3974-
/// superclass.
3975-
///
3976-
/// This is computed as part of adding implicit initializers.
3977-
void setInheritsSuperclassInitializers() {
3978-
assert(addedImplicitInitializers());
3979-
Bits.ClassDecl.InheritsSuperclassInits = true;
3980-
}
3981-
39823989
/// Walks the class hierarchy starting from this class, checking various
39833990
/// conditions.
39843991
AncestryOptions checkAncestry() const;

include/swift/AST/TypeCheckRequests.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1647,6 +1647,27 @@ class CompareDeclSpecializationRequest
16471647
bool isCached() const { return true; }
16481648
};
16491649

1650+
/// Checks whether this declaration inherits its superclass' designated and
1651+
/// convenience initializers.
1652+
class InheritsSuperclassInitializersRequest
1653+
: public SimpleRequest<InheritsSuperclassInitializersRequest,
1654+
bool(ClassDecl *), CacheKind::SeparatelyCached> {
1655+
public:
1656+
using SimpleRequest::SimpleRequest;
1657+
1658+
private:
1659+
friend SimpleRequest;
1660+
1661+
// Evaluation.
1662+
llvm::Expected<bool> evaluate(Evaluator &evaluator, ClassDecl *decl) const;
1663+
1664+
public:
1665+
// Separate caching.
1666+
bool isCached() const { return true; }
1667+
Optional<bool> getCachedResult() const;
1668+
void cacheResult(bool value) const;
1669+
};
1670+
16501671
// Allow AnyValue to compare two Type values, even though Type doesn't
16511672
// support ==.
16521673
template<>

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,5 @@ SWIFT_REQUEST(TypeChecker, HasDefaultInitRequest,
180180
bool(NominalTypeDecl *), Cached, NoLocationInfo)
181181
SWIFT_REQUEST(TypeChecker, SynthesizeDefaultInitRequest,
182182
ConstructorDecl *(NominalTypeDecl *), Cached, NoLocationInfo)
183+
SWIFT_REQUEST(TypeChecker, InheritsSuperclassInitializersRequest,
184+
bool(ClassDecl *), SeparatelyCached, NoLocationInfo)

lib/AST/Decl.cpp

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3957,6 +3957,7 @@ ClassDecl::ClassDecl(SourceLoc ClassLoc, Identifier Name, SourceLoc NameLoc,
39573957
Bits.ClassDecl.Circularity
39583958
= static_cast<unsigned>(CircularityCheck::Unchecked);
39593959
Bits.ClassDecl.InheritsSuperclassInits = 0;
3960+
Bits.ClassDecl.ComputedInheritsSuperclassInits = 0;
39603961
Bits.ClassDecl.RawForeignKind = 0;
39613962
Bits.ClassDecl.HasMissingDesignatedInitializers = 0;
39623963
Bits.ClassDecl.ComputedHasMissingDesignatedInitializers = 0;
@@ -4072,31 +4073,16 @@ bool ClassDecl::isIncompatibleWithWeakReferences() const {
40724073
}
40734074

40744075
bool ClassDecl::inheritsSuperclassInitializers() {
4075-
// Check whether we already have a cached answer.
4076-
if (addedImplicitInitializers())
4077-
return Bits.ClassDecl.InheritsSuperclassInits;
4078-
40794076
// If there's no superclass, there's nothing to inherit.
4080-
ClassDecl *superclassDecl;
4081-
if (!(superclassDecl = getSuperclassDecl())) {
4082-
setAddedImplicitInitializers();
4083-
return false;
4084-
}
4085-
4086-
// If the superclass has known-missing designated initializers, inheriting
4087-
// is unsafe.
4088-
if (superclassDecl->hasMissingDesignatedInitializers())
4077+
if (!getSuperclass())
40894078
return false;
40904079

4091-
// Otherwise, do all the work of resolving constructors, which will also
4092-
// calculate the right answer.
4093-
if (auto *resolver = getASTContext().getLazyResolver())
4094-
resolver->resolveImplicitConstructors(this);
4095-
4096-
return Bits.ClassDecl.InheritsSuperclassInits;
4080+
auto &ctx = getASTContext();
4081+
auto *mutableThis = const_cast<ClassDecl *>(this);
4082+
return evaluateOrDefault(
4083+
ctx.evaluator, InheritsSuperclassInitializersRequest{mutableThis}, false);
40974084
}
40984085

4099-
41004086
AncestryOptions ClassDecl::checkAncestry() const {
41014087
return AncestryOptions(evaluateOrDefault(getASTContext().evaluator,
41024088
ClassAncestryFlagsRequest{const_cast<ClassDecl *>(this)},

lib/AST/TypeCheckRequests.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,3 +1057,17 @@ void swift::simple_display(llvm::raw_ostream &out,
10571057
out << "precedence group " << desc.ident << " at ";
10581058
desc.nameLoc.print(out, desc.dc->getASTContext().SourceMgr);
10591059
}
1060+
1061+
//----------------------------------------------------------------------------//
1062+
// InheritsSuperclassInitializersRequest computation.
1063+
//----------------------------------------------------------------------------//
1064+
1065+
Optional<bool> InheritsSuperclassInitializersRequest::getCachedResult() const {
1066+
auto *decl = std::get<0>(getStorage());
1067+
return decl->getCachedInheritsSuperclassInitializers();
1068+
}
1069+
1070+
void InheritsSuperclassInitializersRequest::cacheResult(bool value) const {
1071+
auto *decl = std::get<0>(getStorage());
1072+
decl->setInheritsSuperclassInitializers(value);
1073+
}

0 commit comments

Comments
 (0)