@@ -2153,35 +2153,6 @@ OpaqueReadOwnershipRequest::evaluate(Evaluator &evaluator,
2153
2153
: OpaqueReadOwnership::Owned);
2154
2154
}
2155
2155
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
-
2185
2156
// / Check the requirements in the where clause of the given \c source
2186
2157
// / to ensure that they don't introduce additional 'Self' requirements.
2187
2158
static void checkProtocolSelfRequirements (ProtocolDecl *proto,
@@ -2255,6 +2226,18 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
2255
2226
if (auto VD = dyn_cast<ValueDecl>(decl)) {
2256
2227
checkRedeclaration (TC, VD);
2257
2228
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
+
2258
2241
// Make sure we finalize this declaration.
2259
2242
TC.DeclsToFinalize .insert (VD);
2260
2243
@@ -2974,6 +2957,24 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
2974
2957
TC.addImplicitConstructors (CD);
2975
2958
CD->addImplicitDestructor ();
2976
2959
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
+
2977
2978
if (auto superclassTy = CD->getSuperclass ()) {
2978
2979
ClassDecl *Super = superclassTy->getClassOrBoundGenericClass ();
2979
2980
@@ -3961,8 +3962,11 @@ void TypeChecker::validateDecl(ValueDecl *D) {
3961
3962
checkDeclAttributesEarly (VD);
3962
3963
validateAttributes (*this , VD);
3963
3964
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
+ }
3966
3970
3967
3971
break ;
3968
3972
}
@@ -4240,7 +4244,11 @@ void TypeChecker::validateDecl(ValueDecl *D) {
4240
4244
}
4241
4245
4242
4246
// 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
+ }
4244
4252
4245
4253
break ;
4246
4254
}
@@ -4423,29 +4431,9 @@ void TypeChecker::requestMemberLayout(ValueDecl *member) {
4423
4431
if (auto *protocolDecl = dyn_cast<ProtocolDecl>(dc))
4424
4432
requestNominalLayout (protocolDecl);
4425
4433
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
-
4434
4434
// 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);
4449
4437
}
4450
4438
4451
4439
void TypeChecker::requestNominalLayout (NominalTypeDecl *nominalDecl) {
@@ -4485,20 +4473,19 @@ static void finalizeType(TypeChecker &TC, NominalTypeDecl *nominal) {
4485
4473
4486
4474
TC.DeclsToFinalize .insert (VD);
4487
4475
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.
4489
4478
auto *prop = dyn_cast<VarDecl>(D);
4490
4479
if (!prop)
4491
4480
continue ;
4492
4481
4493
4482
if (prop->getAttrs ().hasAttribute <LazyAttr>() && !prop->isStatic () &&
4494
4483
(!prop->getGetter () || !prop->getGetter ()->hasBody ())) {
4495
- finalizeAbstractStorageDecl (TC, prop);
4496
4484
(void ) prop->getLazyStorageProperty ();
4497
4485
}
4498
4486
4499
4487
// Ensure that we create the backing variable for a wrapped property.
4500
4488
if (prop->hasAttachedPropertyWrapper ()) {
4501
- finalizeAbstractStorageDecl (TC, prop);
4502
4489
(void ) prop->getPropertyWrapperBackingProperty ();
4503
4490
}
4504
4491
}
@@ -4530,12 +4517,9 @@ static void finalizeType(TypeChecker &TC, NominalTypeDecl *nominal) {
4530
4517
forceConformance (TC.Context .getProtocol (KnownProtocolKind::Hashable));
4531
4518
}
4532
4519
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.
4536
4520
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 );
4539
4523
}
4540
4524
}
4541
4525
@@ -4548,18 +4532,8 @@ void TypeChecker::finalizeDecl(ValueDecl *decl) {
4548
4532
if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
4549
4533
finalizeType (*this , nominal);
4550
4534
} else if (auto storage = dyn_cast<AbstractStorageDecl>(decl)) {
4551
- finalizeAbstractStorageDecl (* this , storage);
4535
+ maybeAddAccessorsToStorage ( storage);
4552
4536
}
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 ();
4563
4537
}
4564
4538
4565
4539
// / Determine whether this is a "pass-through" typealias, which has the
0 commit comments