@@ -8748,37 +8748,8 @@ void TypeChecker::addImplicitConstructors(NominalTypeDecl *decl) {
8748
8748
bool FoundMemberwiseInitializedProperty = false ;
8749
8749
bool SuppressDefaultInitializer = false ;
8750
8750
bool SuppressMemberwiseInitializer = false ;
8751
- bool FoundSynthesizedInit = false ;
8752
8751
bool FoundDesignatedInit = false ;
8753
8752
8754
- // Before we look for constructors, we need to make sure that all synthesized
8755
- // initializers are properly synthesized.
8756
- //
8757
- // NOTE: Lookups of synthesized initializers MUST come after
8758
- // decl->setAddedImplicitInitializers() in case synthesis requires
8759
- // protocol conformance checking, which might be recursive here.
8760
- // FIXME: Disable this code and prevent _any_ implicit constructors from doing
8761
- // this. Investigate why this hasn't worked otherwise.
8762
- DeclName synthesizedInitializers[1 ] = {
8763
- // init(from:) is synthesized by derived conformance to Decodable.
8764
- DeclName (Context, DeclBaseName::createConstructor (), Context.Id_from )
8765
- };
8766
-
8767
- auto initializerIsSynthesized = [=](ConstructorDecl *initializer) {
8768
- if (!initializer->isImplicit ())
8769
- return false ;
8770
-
8771
- for (auto &name : synthesizedInitializers)
8772
- if (initializer->getFullName () == name)
8773
- return true ;
8774
-
8775
- return false ;
8776
- };
8777
-
8778
- for (auto &name : synthesizedInitializers) {
8779
- synthesizeMemberForLookup (decl, name);
8780
- }
8781
-
8782
8753
SmallPtrSet<CanType, 4 > initializerParamTypes;
8783
8754
llvm::SmallPtrSet<ConstructorDecl *, 4 > overriddenInits;
8784
8755
if (decl->hasClangNode () && isa<ClassDecl>(decl)) {
@@ -8800,13 +8771,10 @@ void TypeChecker::addImplicitConstructors(NominalTypeDecl *decl) {
8800
8771
} else {
8801
8772
for (auto member : decl->getMembers ()) {
8802
8773
if (auto ctor = dyn_cast<ConstructorDecl>(member)) {
8803
- // Synthesized initializers others than the default initializer should
8804
- // not prevent default initializer synthesis.
8805
- if (initializerIsSynthesized (ctor)) {
8806
- FoundSynthesizedInit = true ;
8807
- } else if (ctor->isDesignatedInit ()) {
8774
+ // Initializers that were synthesized to fulfill derived conformances
8775
+ // should not prevent default initializer synthesis.
8776
+ if (ctor->isDesignatedInit () && !ctor->isSynthesized ())
8808
8777
FoundDesignatedInit = true ;
8809
- }
8810
8778
8811
8779
if (isa<StructDecl>(decl))
8812
8780
continue ;
@@ -8878,8 +8846,10 @@ void TypeChecker::addImplicitConstructors(NominalTypeDecl *decl) {
8878
8846
}
8879
8847
8880
8848
if (auto structDecl = dyn_cast<StructDecl>(decl)) {
8881
- if (!FoundDesignatedInit && !SuppressMemberwiseInitializer
8882
- && !structDecl->hasUnreferenceableStorage ()) {
8849
+ assert (!structDecl->hasUnreferenceableStorage () &&
8850
+ " User-defined structs cannot have unreferenceable storage" );
8851
+
8852
+ if (!FoundDesignatedInit && !SuppressMemberwiseInitializer) {
8883
8853
// For a struct with memberwise initialized properties, we add a
8884
8854
// memberwise init.
8885
8855
if (FoundMemberwiseInitializedProperty) {
@@ -8901,12 +8871,13 @@ void TypeChecker::addImplicitConstructors(NominalTypeDecl *decl) {
8901
8871
// FIXME: Currently skipping generic classes.
8902
8872
auto classDecl = cast<ClassDecl>(decl);
8903
8873
if (classDecl->hasSuperclass ()) {
8904
- bool canInheritInitializers = !FoundDesignatedInit;
8874
+ bool canInheritInitializers = (!SuppressDefaultInitializer &&
8875
+ !FoundDesignatedInit);
8905
8876
8906
8877
// We can't define these overrides if we have any uninitialized
8907
8878
// stored properties.
8908
- if (SuppressDefaultInitializer && !FoundDesignatedInit
8909
- && !FoundSynthesizedInit && !classDecl->hasClangNode ()) {
8879
+ if (SuppressDefaultInitializer && !FoundDesignatedInit &&
8880
+ !classDecl->hasClangNode ()) {
8910
8881
return ;
8911
8882
}
8912
8883
@@ -9019,14 +8990,9 @@ void TypeChecker::synthesizeMemberForLookup(NominalTypeDecl *target,
9019
8990
auto baseName = member.getBaseName ();
9020
8991
9021
8992
// Checks whether the target conforms to the given protocol. If the
9022
- // conformance is incomplete, check the conformance to force synthesis, if
9023
- // possible.
9024
- //
9025
- // Swallows diagnostics if conformance checking is already in progress (so we
9026
- // don't display diagnostics twice).
8993
+ // conformance is incomplete, force the conformance.
9027
8994
//
9028
- // Returns whether the target conforms to the protocol and the conformance is
9029
- // complete.
8995
+ // Returns whether the target conforms to the protocol.
9030
8996
auto evaluateTargetConformanceTo = [&](ProtocolDecl *protocol) {
9031
8997
auto targetType = target->getDeclaredInterfaceType ();
9032
8998
if (auto ref = conformsToProtocol (
@@ -9035,26 +9001,12 @@ void TypeChecker::synthesizeMemberForLookup(NominalTypeDecl *target,
9035
9001
ConformanceCheckFlags::SkipConditionalRequirements),
9036
9002
SourceLoc ())) {
9037
9003
if (auto *conformance = ref->getConcrete ()->getRootNormalConformance ()) {
9038
- if (conformance->isIncomplete ()) {
9039
- // Check conformance, forcing synthesis.
9040
- //
9041
- // If synthesizing conformance fails, this will produce diagnostics.
9042
- // If conformance checking was already in progress elsewhere, though,
9043
- // this could produce diagnostics twice.
9044
- //
9045
- // To prevent this duplication, we swallow the diagnostics if the
9046
- // state of the conformance is not Incomplete.
9047
- DiagnosticTransaction transaction (Context.Diags );
9048
- auto shouldSwallowDiagnostics =
9049
- conformance->getState () != ProtocolConformanceState::Incomplete;
9050
-
9004
+ if (conformance->getState () == ProtocolConformanceState::Incomplete) {
9051
9005
checkConformance (conformance);
9052
- if (shouldSwallowDiagnostics)
9053
- transaction.abort ();
9054
-
9055
- return conformance->isComplete ();
9056
9006
}
9057
9007
}
9008
+
9009
+ return true ;
9058
9010
}
9059
9011
9060
9012
return false ;
@@ -9076,13 +9028,6 @@ void TypeChecker::synthesizeMemberForLookup(NominalTypeDecl *target,
9076
9028
auto *encodableProto = Context.getProtocol (KnownProtocolKind::Encodable);
9077
9029
if (!evaluateTargetConformanceTo (decodableProto))
9078
9030
(void )evaluateTargetConformanceTo (encodableProto);
9079
- } else if (baseName.getIdentifier () == Context.Id_allCases ||
9080
- baseName.getIdentifier () == Context.Id_AllCases ) {
9081
- // If the target should conform to the CaseIterable protocol, check the
9082
- // conformance here to attempt synthesis.
9083
- auto *caseIterableProto
9084
- = Context.getProtocol (KnownProtocolKind::CaseIterable);
9085
- (void )evaluateTargetConformanceTo (caseIterableProto);
9086
9031
}
9087
9032
} else {
9088
9033
auto argumentNames = member.getArgumentNames ();
0 commit comments