@@ -2153,35 +2153,6 @@ OpaqueReadOwnershipRequest::evaluate(Evaluator &evaluator,
21532153 : OpaqueReadOwnership::Owned);
21542154}
21552155
2156- static void validateAbstractStorageDecl (TypeChecker &TC,
2157- AbstractStorageDecl *storage) {
2158- if (storage->getOpaqueResultTypeDecl ()) {
2159- if (auto sf = storage->getInnermostDeclContext ()->getParentSourceFile ()) {
2160- sf->markDeclWithOpaqueResultTypeAsValidated (storage);
2161- }
2162- }
2163-
2164- // Everything else about the accessors can wait until finalization.
2165- // This will validate all the accessors.
2166- TC.DeclsToFinalize .insert (storage);
2167- }
2168-
2169- static void finalizeAbstractStorageDecl (TypeChecker &TC,
2170- AbstractStorageDecl *storage) {
2171- TC.validateDecl (storage);
2172-
2173- // Add any mandatory accessors now.
2174- maybeAddAccessorsToStorage (storage);
2175-
2176- for (auto accessor : storage->getAllAccessors ()) {
2177- // Are there accessors we can safely ignore here, like maybe observers?
2178- TC.validateDecl (accessor);
2179-
2180- // Finalize the accessors as well.
2181- TC.DeclsToFinalize .insert (accessor);
2182- }
2183- }
2184-
21852156// / Check the requirements in the where clause of the given \c source
21862157// / to ensure that they don't introduce additional 'Self' requirements.
21872158static void checkProtocolSelfRequirements (ProtocolDecl *proto,
@@ -2255,6 +2226,18 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
22552226 if (auto VD = dyn_cast<ValueDecl>(decl)) {
22562227 checkRedeclaration (TC, VD);
22572228
2229+ // Force some requests, which can produce diagnostics.
2230+
2231+ // Compute access level.
2232+ (void ) VD->getFormalAccess ();
2233+
2234+ // Compute overrides.
2235+ (void ) VD->getOverriddenDecls ();
2236+
2237+ // Check whether the member is @objc or dynamic.
2238+ (void ) VD->isObjC ();
2239+ (void ) VD->isDynamic ();
2240+
22582241 // Make sure we finalize this declaration.
22592242 TC.DeclsToFinalize .insert (VD);
22602243
@@ -2974,6 +2957,24 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
29742957 TC.addImplicitConstructors (CD);
29752958 CD->addImplicitDestructor ();
29762959
2960+ // Compute @objc for each superclass member, to catch selector
2961+ // conflicts resulting from unintended overrides.
2962+ //
2963+ // FIXME: This should be a request so we can measure how much work
2964+ // we're doing here.
2965+ CD->walkSuperclasses (
2966+ [&](ClassDecl *superclass) {
2967+ for (auto *member : superclass->getMembers ()) {
2968+ if (auto *vd = dyn_cast<ValueDecl>(member)) {
2969+ if (vd->isPotentiallyOverridable ()) {
2970+ (void ) vd->isObjC ();
2971+ }
2972+ }
2973+ }
2974+
2975+ return TypeWalker::Action::Continue;
2976+ });
2977+
29772978 if (auto superclassTy = CD->getSuperclass ()) {
29782979 ClassDecl *Super = superclassTy->getClassOrBoundGenericClass ();
29792980
@@ -3961,8 +3962,11 @@ void TypeChecker::validateDecl(ValueDecl *D) {
39613962 checkDeclAttributesEarly (VD);
39623963 validateAttributes (*this , VD);
39633964
3964- // Perform accessor-related validation.
3965- validateAbstractStorageDecl (*this , VD);
3965+ if (VD->getOpaqueResultTypeDecl ()) {
3966+ if (auto SF = VD->getInnermostDeclContext ()->getParentSourceFile ()) {
3967+ SF->markDeclWithOpaqueResultTypeAsValidated (VD);
3968+ }
3969+ }
39663970
39673971 break ;
39683972 }
@@ -4240,7 +4244,11 @@ void TypeChecker::validateDecl(ValueDecl *D) {
42404244 }
42414245
42424246 // Perform accessor-related validation.
4243- validateAbstractStorageDecl (*this , SD);
4247+ if (SD->getOpaqueResultTypeDecl ()) {
4248+ if (auto SF = SD->getInnermostDeclContext ()->getParentSourceFile ()) {
4249+ SF->markDeclWithOpaqueResultTypeAsValidated (SD);
4250+ }
4251+ }
42444252
42454253 break ;
42464254 }
@@ -4423,29 +4431,9 @@ void TypeChecker::requestMemberLayout(ValueDecl *member) {
44234431 if (auto *protocolDecl = dyn_cast<ProtocolDecl>(dc))
44244432 requestNominalLayout (protocolDecl);
44254433
4426- if (auto ext = dyn_cast<ExtensionDecl>(dc)) {
4427- if (ext->getSelfClassDecl ()) {
4428- // Finalize members of class extensions, to ensure we compute their
4429- // @objc and dynamic state.
4430- DeclsToFinalize.insert (member);
4431- }
4432- }
4433-
44344434 // If this represents (abstract) storage, form the appropriate accessors.
4435- if (auto storage = dyn_cast<AbstractStorageDecl>(member)) {
4436- validateAbstractStorageDecl (*this , storage);
4437-
4438- // Request layout of the accessors for an @objc declaration.
4439- // We can't delay validation of getters and setters on @objc properties,
4440- // because if they never get validated at all then conformance checkers
4441- // will complain about selector mismatches.
4442- if (storage->isObjC ()) {
4443- maybeAddAccessorsToStorage (storage);
4444- for (auto accessor : storage->getAllAccessors ()) {
4445- requestMemberLayout (accessor);
4446- }
4447- }
4448- }
4435+ if (auto storage = dyn_cast<AbstractStorageDecl>(member))
4436+ DeclsToFinalize.insert (storage);
44494437}
44504438
44514439void TypeChecker::requestNominalLayout (NominalTypeDecl *nominalDecl) {
@@ -4485,20 +4473,19 @@ static void finalizeType(TypeChecker &TC, NominalTypeDecl *nominal) {
44854473
44864474 TC.DeclsToFinalize .insert (VD);
44874475
4488- // The only thing left to do is synthesize storage for lazy variables.
4476+ // The only thing left to do is synthesize storage for lazy variables
4477+ // and property wrappers.
44894478 auto *prop = dyn_cast<VarDecl>(D);
44904479 if (!prop)
44914480 continue ;
44924481
44934482 if (prop->getAttrs ().hasAttribute <LazyAttr>() && !prop->isStatic () &&
44944483 (!prop->getGetter () || !prop->getGetter ()->hasBody ())) {
4495- finalizeAbstractStorageDecl (TC, prop);
44964484 (void ) prop->getLazyStorageProperty ();
44974485 }
44984486
44994487 // Ensure that we create the backing variable for a wrapped property.
45004488 if (prop->hasAttachedPropertyWrapper ()) {
4501- finalizeAbstractStorageDecl (TC, prop);
45024489 (void ) prop->getPropertyWrapperBackingProperty ();
45034490 }
45044491 }
@@ -4530,12 +4517,9 @@ static void finalizeType(TypeChecker &TC, NominalTypeDecl *nominal) {
45304517 forceConformance (TC.Context .getProtocol (KnownProtocolKind::Hashable));
45314518 }
45324519
4533- // validateDeclForNameLookup will not trigger an immediate full
4534- // validation of protocols, but clients will assume that things
4535- // like the requirement signature have been set.
45364520 if (auto PD = dyn_cast<ProtocolDecl>(nominal)) {
4537- ( void ) PD->getInheritedProtocols ();
4538- TC.validateDecl (PD );
4521+ for ( auto *inherited : PD->getInheritedProtocols ())
4522+ TC.requestNominalLayout (inherited );
45394523 }
45404524}
45414525
@@ -4548,18 +4532,8 @@ void TypeChecker::finalizeDecl(ValueDecl *decl) {
45484532 if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
45494533 finalizeType (*this , nominal);
45504534 } else if (auto storage = dyn_cast<AbstractStorageDecl>(decl)) {
4551- finalizeAbstractStorageDecl (* this , storage);
4535+ maybeAddAccessorsToStorage ( storage);
45524536 }
4553-
4554- // Compute access level.
4555- (void )decl->getFormalAccess ();
4556-
4557- // Compute overrides.
4558- (void )decl->getOverriddenDecls ();
4559-
4560- // Check whether the member is @objc or dynamic.
4561- (void )decl->isObjC ();
4562- (void )decl->isDynamic ();
45634537}
45644538
45654539// / Determine whether this is a "pass-through" typealias, which has the
0 commit comments