@@ -6928,174 +6928,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
6928
6928
checkAccessControl (TC, CD);
6929
6929
return ;
6930
6930
}
6931
- if (CD->hasInterfaceType () || CD->isBeingValidated ())
6932
- return ;
6933
-
6934
- CD->setIsBeingValidated ();
6935
-
6936
- TC.checkDeclAttributesEarly (CD);
6937
- TC.computeAccessLevel (CD);
6938
-
6939
- // convenience initializers are only allowed on classes and in
6940
- // extensions thereof.
6941
- if (CD->isConvenienceInit ()) {
6942
- if (auto extType = CD->getDeclContext ()->getDeclaredInterfaceType ()) {
6943
- auto extClass = extType->getClassOrBoundGenericClass ();
6944
-
6945
- // Forbid convenience inits on Foreign CF types, as Swift does not yet
6946
- // support user-defined factory inits.
6947
- if (extClass &&
6948
- extClass->getForeignClassKind () == ClassDecl::ForeignKind::CFType) {
6949
- TC.diagnose (CD->getLoc (), diag::cfclass_convenience_init);
6950
- }
6951
-
6952
- if (!extClass && !extType->hasError ()) {
6953
- auto ConvenienceLoc =
6954
- CD->getAttrs ().getAttribute <ConvenienceAttr>()->getLocation ();
6955
-
6956
- // Produce a tailored diagnostic for structs and enums.
6957
- bool isStruct = extType->getStructOrBoundGenericStruct () != nullptr ;
6958
- if (isStruct || extType->getEnumOrBoundGenericEnum ()) {
6959
- TC.diagnose (CD->getLoc (), diag::enumstruct_convenience_init,
6960
- isStruct ? " structs" : " enums" )
6961
- .fixItRemove (ConvenienceLoc);
6962
- } else {
6963
- TC.diagnose (CD->getLoc (), diag::nonclass_convenience_init, extType)
6964
- .fixItRemove (ConvenienceLoc);
6965
- }
6966
- CD->setInitKind (CtorInitializerKind::Designated);
6967
- }
6968
- }
6969
- } else if (auto extType = CD->getDeclContext ()->getDeclaredInterfaceType ()) {
6970
- // A designated initializer for a class must be written within the class
6971
- // itself.
6972
- //
6973
- // This is because designated initializers of classes get a vtable entry,
6974
- // and extensions cannot add vtable entries to the extended type.
6975
- //
6976
- // If we implement the ability for extensions defined in the same module
6977
- // (or the same file) to add vtable entries, we can re-evaluate this
6978
- // restriction.
6979
- if (extType->getClassOrBoundGenericClass () &&
6980
- isa<ExtensionDecl>(CD->getDeclContext ())) {
6981
- TC.diagnose (CD->getLoc (), diag::designated_init_in_extension, extType)
6982
- .fixItInsert (CD->getLoc (), " convenience " );
6983
- CD->setInitKind (CtorInitializerKind::Convenience);
6984
- } else if (CD->getDeclContext ()->getAsProtocolExtensionContext ()) {
6985
- CD->setInitKind (CtorInitializerKind::Convenience);
6986
- }
6987
- }
6988
-
6989
- if (CD->getDeclContext ()->isTypeContext ())
6990
- configureImplicitSelf (TC, CD);
6991
-
6992
- if (auto gp = CD->getGenericParams ()) {
6993
- // Write up generic parameters and check the generic parameter list.
6994
- gp->setOuterParameters (CD->getDeclContext ()->getGenericParamsOfContext ());
6995
-
6996
- auto *sig = TC.validateGenericFuncSignature (CD);
6997
- auto *env = sig->createGenericEnvironment ();
6998
- CD->setGenericEnvironment (env);
6999
-
7000
- // Revert the types within the signature so it can be type-checked with
7001
- // archetypes below.
7002
- TC.revertGenericFuncSignature (CD);
7003
- } else if (CD->getDeclContext ()->getGenericSignatureOfContext ()) {
7004
- (void )TC.validateGenericFuncSignature (CD);
7005
6931
7006
- // Revert all of the types within the signature of the constructor.
7007
- TC.revertGenericFuncSignature (CD);
7008
-
7009
- CD->setGenericEnvironment (
7010
- CD->getDeclContext ()->getGenericEnvironmentOfContext ());
7011
- }
7012
-
7013
- // Set the context type of 'self'.
7014
- if (CD->getDeclContext ()->isTypeContext ())
7015
- recordSelfContextType (CD);
7016
-
7017
- // Type check the constructor parameters.
7018
- GenericTypeToArchetypeResolver resolver (CD);
7019
- if (TC.typeCheckParameterLists (CD, resolver) || CD->isInvalid ()) {
7020
- CD->setInterfaceType (ErrorType::get (TC.Context ));
7021
- CD->setInvalid ();
7022
- } else {
7023
- if (!CD->getGenericSignatureOfContext ())
7024
- TC.configureInterfaceType (CD, CD->getGenericSignature ());
7025
- }
7026
-
7027
- // We want the constructor to be available for name lookup as soon
7028
- // as it has a valid interface type.
7029
- CD->setIsBeingValidated (false );
7030
-
7031
- validateAttributes (TC, CD);
7032
-
7033
- // Check whether this initializer overrides an initializer in its
7034
- // superclass.
7035
- if (!checkOverrides (TC, CD)) {
7036
- // If an initializer has an override attribute but does not override
7037
- // anything or overrides something that doesn't need an 'override'
7038
- // keyword (e.g., a convenience initializer), complain.
7039
- // anything, or overrides something that complain.
7040
- if (auto *attr = CD->getAttrs ().getAttribute <OverrideAttr>()) {
7041
- if (!CD->getOverriddenDecl ()) {
7042
- TC.diagnose (CD, diag::initializer_does_not_override)
7043
- .highlight (attr->getLocation ());
7044
- attr->setInvalid ();
7045
- } else if (!overrideRequiresKeyword (CD->getOverriddenDecl ())) {
7046
- // Special case: we are overriding a 'required' initializer, so we
7047
- // need (only) the 'required' keyword.
7048
- if (cast<ConstructorDecl>(CD->getOverriddenDecl ())->isRequired ()) {
7049
- if (CD->getAttrs ().hasAttribute <RequiredAttr>()) {
7050
- TC.diagnose (CD, diag::required_initializer_override_keyword)
7051
- .fixItRemove (attr->getLocation ());
7052
- } else {
7053
- TC.diagnose (CD, diag::required_initializer_override_wrong_keyword)
7054
- .fixItReplace (attr->getLocation (), " required" );
7055
- CD->getAttrs ().add (
7056
- new (TC.Context ) RequiredAttr (/* IsImplicit=*/ true ));
7057
- }
7058
-
7059
- TC.diagnose (findNonImplicitRequiredInit (CD->getOverriddenDecl ()),
7060
- diag::overridden_required_initializer_here);
7061
- } else {
7062
- // We tried to override a convenience initializer.
7063
- TC.diagnose (CD, diag::initializer_does_not_override)
7064
- .highlight (attr->getLocation ());
7065
- TC.diagnose (CD->getOverriddenDecl (),
7066
- diag::convenience_init_override_here);
7067
- }
7068
- }
7069
- }
7070
-
7071
- // A failable initializer cannot override a non-failable one.
7072
- // This would normally be diagnosed by the covariance rules;
7073
- // however, those are disabled so that we can provide a more
7074
- // specific diagnostic here.
7075
- if (CD->getFailability () != OTK_None &&
7076
- CD->getOverriddenDecl () &&
7077
- CD->getOverriddenDecl ()->getFailability () == OTK_None) {
7078
- TC.diagnose (CD, diag::failable_initializer_override,
7079
- CD->getFullName ());
7080
- TC.diagnose (CD->getOverriddenDecl (),
7081
- diag::nonfailable_initializer_override_here,
7082
- CD->getOverriddenDecl ()->getFullName ());
7083
- }
7084
- }
7085
-
7086
- // An initializer is ObjC-compatible if it's explicitly @objc or a member
7087
- // of an ObjC-compatible class.
7088
- if (CD->getDeclContext ()->isTypeContext ()) {
7089
- Optional<ObjCReason> isObjC = shouldMarkAsObjC (TC, CD,
7090
- /* allowImplicit=*/ true );
7091
-
7092
- Optional<ForeignErrorConvention> errorConvention;
7093
- if (isObjC &&
7094
- (CD->isInvalid () ||
7095
- !TC.isRepresentableInObjC (CD, *isObjC, errorConvention)))
7096
- isObjC = None;
7097
- markAsObjC (TC, CD, isObjC, errorConvention);
7098
- }
6932
+ TC.validateDecl (CD);
7099
6933
7100
6934
// If this initializer overrides a 'required' initializer, it must itself
7101
6935
// be marked 'required'.
@@ -7137,14 +6971,6 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
7137
6971
}
7138
6972
}
7139
6973
7140
- inferDynamic (TC.Context , CD);
7141
-
7142
- if (CD->getFailability () == OTK_ImplicitlyUnwrappedOptional) {
7143
- auto &C = CD->getASTContext ();
7144
- CD->getAttrs ().add (
7145
- new (C) ImplicitlyUnwrappedOptionalAttr (/* implicit= */ true ));
7146
- }
7147
-
7148
6974
TC.checkDeclAttributes (CD);
7149
6975
}
7150
6976
@@ -7665,12 +7491,191 @@ void TypeChecker::validateDecl(ValueDecl *D) {
7665
7491
}
7666
7492
7667
7493
case DeclKind::Func:
7668
- case DeclKind::Accessor:
7669
- case DeclKind::Constructor: {
7494
+ case DeclKind::Accessor: {
7670
7495
typeCheckDecl (D, true );
7671
7496
break ;
7672
7497
}
7673
7498
7499
+ case DeclKind::Constructor: {
7500
+ auto *CD = cast<ConstructorDecl>(D);
7501
+
7502
+ CD->setIsBeingValidated ();
7503
+
7504
+ checkDeclAttributesEarly (CD);
7505
+ computeAccessLevel (CD);
7506
+
7507
+ // convenience initializers are only allowed on classes and in
7508
+ // extensions thereof.
7509
+ if (CD->isConvenienceInit ()) {
7510
+ if (auto extType = CD->getDeclContext ()->getDeclaredInterfaceType ()) {
7511
+ auto extClass = extType->getClassOrBoundGenericClass ();
7512
+
7513
+ // Forbid convenience inits on Foreign CF types, as Swift does not yet
7514
+ // support user-defined factory inits.
7515
+ if (extClass &&
7516
+ extClass->getForeignClassKind () == ClassDecl::ForeignKind::CFType) {
7517
+ diagnose (CD->getLoc (), diag::cfclass_convenience_init);
7518
+ }
7519
+
7520
+ if (!extClass && !extType->hasError ()) {
7521
+ auto ConvenienceLoc =
7522
+ CD->getAttrs ().getAttribute <ConvenienceAttr>()->getLocation ();
7523
+
7524
+ // Produce a tailored diagnostic for structs and enums.
7525
+ bool isStruct = extType->getStructOrBoundGenericStruct () != nullptr ;
7526
+ if (isStruct || extType->getEnumOrBoundGenericEnum ()) {
7527
+ diagnose (CD->getLoc (), diag::enumstruct_convenience_init,
7528
+ isStruct ? " structs" : " enums" )
7529
+ .fixItRemove (ConvenienceLoc);
7530
+ } else {
7531
+ diagnose (CD->getLoc (), diag::nonclass_convenience_init, extType)
7532
+ .fixItRemove (ConvenienceLoc);
7533
+ }
7534
+ CD->setInitKind (CtorInitializerKind::Designated);
7535
+ }
7536
+ }
7537
+ } else if (auto extType = CD->getDeclContext ()->getDeclaredInterfaceType ()) {
7538
+ // A designated initializer for a class must be written within the class
7539
+ // itself.
7540
+ //
7541
+ // This is because designated initializers of classes get a vtable entry,
7542
+ // and extensions cannot add vtable entries to the extended type.
7543
+ //
7544
+ // If we implement the ability for extensions defined in the same module
7545
+ // (or the same file) to add vtable entries, we can re-evaluate this
7546
+ // restriction.
7547
+ if (extType->getClassOrBoundGenericClass () &&
7548
+ isa<ExtensionDecl>(CD->getDeclContext ())) {
7549
+ diagnose (CD->getLoc (), diag::designated_init_in_extension, extType)
7550
+ .fixItInsert (CD->getLoc (), " convenience " );
7551
+ CD->setInitKind (CtorInitializerKind::Convenience);
7552
+ } else if (CD->getDeclContext ()->getAsProtocolExtensionContext ()) {
7553
+ CD->setInitKind (CtorInitializerKind::Convenience);
7554
+ }
7555
+ }
7556
+
7557
+ if (CD->getDeclContext ()->isTypeContext ())
7558
+ configureImplicitSelf (*this , CD);
7559
+
7560
+ if (auto gp = CD->getGenericParams ()) {
7561
+ // Write up generic parameters and check the generic parameter list.
7562
+ gp->setOuterParameters (CD->getDeclContext ()->getGenericParamsOfContext ());
7563
+
7564
+ auto *sig = validateGenericFuncSignature (CD);
7565
+ auto *env = sig->createGenericEnvironment ();
7566
+ CD->setGenericEnvironment (env);
7567
+
7568
+ // Revert the types within the signature so it can be type-checked with
7569
+ // archetypes below.
7570
+ revertGenericFuncSignature (CD);
7571
+ } else if (CD->getDeclContext ()->getGenericSignatureOfContext ()) {
7572
+ (void )validateGenericFuncSignature (CD);
7573
+
7574
+ // Revert all of the types within the signature of the constructor.
7575
+ revertGenericFuncSignature (CD);
7576
+
7577
+ CD->setGenericEnvironment (
7578
+ CD->getDeclContext ()->getGenericEnvironmentOfContext ());
7579
+ }
7580
+
7581
+ // Set the context type of 'self'.
7582
+ if (CD->getDeclContext ()->isTypeContext ())
7583
+ recordSelfContextType (CD);
7584
+
7585
+ // Type check the constructor parameters.
7586
+ GenericTypeToArchetypeResolver resolver (CD);
7587
+ if (typeCheckParameterLists (CD, resolver) || CD->isInvalid ()) {
7588
+ CD->setInterfaceType (ErrorType::get (Context));
7589
+ CD->setInvalid ();
7590
+ } else {
7591
+ if (!CD->getGenericSignatureOfContext ())
7592
+ configureInterfaceType (CD, CD->getGenericSignature ());
7593
+ }
7594
+
7595
+ // We want the constructor to be available for name lookup as soon
7596
+ // as it has a valid interface type.
7597
+ CD->setIsBeingValidated (false );
7598
+
7599
+ validateAttributes (*this , CD);
7600
+
7601
+ // Check whether this initializer overrides an initializer in its
7602
+ // superclass.
7603
+ if (!checkOverrides (*this , CD)) {
7604
+ // If an initializer has an override attribute but does not override
7605
+ // anything or overrides something that doesn't need an 'override'
7606
+ // keyword (e.g., a convenience initializer), complain.
7607
+ // anything, or overrides something that complain.
7608
+ if (auto *attr = CD->getAttrs ().getAttribute <OverrideAttr>()) {
7609
+ if (!CD->getOverriddenDecl ()) {
7610
+ diagnose (CD, diag::initializer_does_not_override)
7611
+ .highlight (attr->getLocation ());
7612
+ attr->setInvalid ();
7613
+ } else if (!DeclChecker::overrideRequiresKeyword (CD->getOverriddenDecl ())) {
7614
+ // Special case: we are overriding a 'required' initializer, so we
7615
+ // need (only) the 'required' keyword.
7616
+ if (cast<ConstructorDecl>(CD->getOverriddenDecl ())->isRequired ()) {
7617
+ if (CD->getAttrs ().hasAttribute <RequiredAttr>()) {
7618
+ diagnose (CD, diag::required_initializer_override_keyword)
7619
+ .fixItRemove (attr->getLocation ());
7620
+ } else {
7621
+ diagnose (CD, diag::required_initializer_override_wrong_keyword)
7622
+ .fixItReplace (attr->getLocation (), " required" );
7623
+ CD->getAttrs ().add (
7624
+ new (Context) RequiredAttr (/* IsImplicit=*/ true ));
7625
+ }
7626
+
7627
+ diagnose (findNonImplicitRequiredInit (CD->getOverriddenDecl ()),
7628
+ diag::overridden_required_initializer_here);
7629
+ } else {
7630
+ // We tried to override a convenience initializer.
7631
+ diagnose (CD, diag::initializer_does_not_override)
7632
+ .highlight (attr->getLocation ());
7633
+ diagnose (CD->getOverriddenDecl (),
7634
+ diag::convenience_init_override_here);
7635
+ }
7636
+ }
7637
+ }
7638
+
7639
+ // A failable initializer cannot override a non-failable one.
7640
+ // This would normally be diagnosed by the covariance rules;
7641
+ // however, those are disabled so that we can provide a more
7642
+ // specific diagnostic here.
7643
+ if (CD->getFailability () != OTK_None &&
7644
+ CD->getOverriddenDecl () &&
7645
+ CD->getOverriddenDecl ()->getFailability () == OTK_None) {
7646
+ diagnose (CD, diag::failable_initializer_override,
7647
+ CD->getFullName ());
7648
+ diagnose (CD->getOverriddenDecl (),
7649
+ diag::nonfailable_initializer_override_here,
7650
+ CD->getOverriddenDecl ()->getFullName ());
7651
+ }
7652
+ }
7653
+
7654
+ // An initializer is ObjC-compatible if it's explicitly @objc or a member
7655
+ // of an ObjC-compatible class.
7656
+ if (CD->getDeclContext ()->isTypeContext ()) {
7657
+ Optional<ObjCReason> isObjC = shouldMarkAsObjC (*this , CD,
7658
+ /* allowImplicit=*/ true );
7659
+
7660
+ Optional<ForeignErrorConvention> errorConvention;
7661
+ if (isObjC &&
7662
+ (CD->isInvalid () ||
7663
+ !isRepresentableInObjC (CD, *isObjC, errorConvention)))
7664
+ isObjC = None;
7665
+ markAsObjC (*this , CD, isObjC, errorConvention);
7666
+ }
7667
+
7668
+ inferDynamic (Context, CD);
7669
+
7670
+ if (CD->getFailability () == OTK_ImplicitlyUnwrappedOptional) {
7671
+ auto &C = CD->getASTContext ();
7672
+ CD->getAttrs ().add (
7673
+ new (C) ImplicitlyUnwrappedOptionalAttr (/* implicit= */ true ));
7674
+ }
7675
+
7676
+ break ;
7677
+ }
7678
+
7674
7679
case DeclKind::Destructor: {
7675
7680
auto *DD = cast<DestructorDecl>(D);
7676
7681
0 commit comments