@@ -193,6 +193,8 @@ static void recordShadowedDeclsAfterSignatureMatch(
193
193
for (unsigned firstIdx : indices (decls)) {
194
194
auto firstDecl = decls[firstIdx];
195
195
auto firstModule = firstDecl->getModuleContext ();
196
+ bool firstTopLevel = firstDecl->getDeclContext ()->isModuleScopeContext ();
197
+
196
198
auto name = firstDecl->getBaseName ();
197
199
198
200
auto isShadowed = [&](ArrayRef<ModuleDecl::AccessPathTy> paths) {
@@ -219,15 +221,37 @@ static void recordShadowedDeclsAfterSignatureMatch(
219
221
// Determine whether one module takes precedence over another.
220
222
auto secondDecl = decls[secondIdx];
221
223
auto secondModule = secondDecl->getModuleContext ();
224
+ bool secondTopLevel = secondDecl->getDeclContext ()->isModuleScopeContext ();
225
+
226
+ // For member types, we skip most of the below rules. Instead, we allow
227
+ // member types defined in a subclass to shadow member types defined in
228
+ // a superclass.
229
+ if (isa<TypeDecl>(firstDecl) &&
230
+ isa<TypeDecl>(secondDecl) &&
231
+ !firstTopLevel &&
232
+ !secondTopLevel) {
233
+ auto *firstClass = firstDecl->getDeclContext ()->getSelfClassDecl ();
234
+ auto *secondClass = secondDecl->getDeclContext ()->getSelfClassDecl ();
235
+ if (firstClass && secondClass && firstClass != secondClass) {
236
+ if (firstClass->isSuperclassOf (secondClass)) {
237
+ shadowed.insert (firstDecl);
238
+ continue ;
239
+ } else if (secondClass->isSuperclassOf (firstClass)) {
240
+ shadowed.insert (secondDecl);
241
+ continue ;
242
+ }
243
+ }
244
+
245
+ continue ;
246
+ }
222
247
223
248
// Top-level type declarations in a module shadow other declarations
224
249
// visible through the module's imports.
225
250
//
226
251
// [Backward compatibility] Note that members of types have the same
227
252
// shadowing check, but we do it after dropping unavailable members.
228
253
if (firstModule != secondModule &&
229
- firstDecl->getDeclContext ()->isModuleScopeContext () &&
230
- secondDecl->getDeclContext ()->isModuleScopeContext ()) {
254
+ firstTopLevel && secondTopLevel) {
231
255
auto firstPaths = imports.getAllAccessPathsNotShadowedBy (
232
256
firstModule, secondModule, dc);
233
257
auto secondPaths = imports.getAllAccessPathsNotShadowedBy (
@@ -304,8 +328,7 @@ static void recordShadowedDeclsAfterSignatureMatch(
304
328
// shadowing check is performed after unavailable candidates have
305
329
// already been dropped.
306
330
if (firstModule != secondModule &&
307
- !firstDecl->getDeclContext ()->isModuleScopeContext () &&
308
- !secondDecl->getDeclContext ()->isModuleScopeContext ()) {
331
+ !firstTopLevel && !secondTopLevel) {
309
332
auto firstPaths = imports.getAllAccessPathsNotShadowedBy (
310
333
firstModule, secondModule, dc);
311
334
auto secondPaths = imports.getAllAccessPathsNotShadowedBy (
@@ -478,9 +501,6 @@ static void recordShadowedDecls(ArrayRef<ValueDecl *> decls,
478
501
// type. This is layering a partial fix upon a total hack.
479
502
if (auto asd = dyn_cast<AbstractStorageDecl>(decl))
480
503
signature = asd->getOverloadSignatureType ();
481
- } else if (decl->getDeclContext ()->isTypeContext ()) {
482
- // Do not apply shadowing rules for member types.
483
- continue ;
484
504
}
485
505
486
506
// Record this declaration based on its signature.
0 commit comments