@@ -393,6 +393,16 @@ static ConstructorComparison compareConstructors(ConstructorDecl *ctor1,
393393 return ConstructorComparison::Same;
394394}
395395
396+ static bool isMemberImplementation (ValueDecl *VD) {
397+ return VD->isObjCMemberImplementation ();
398+ }
399+ static bool isMemberImplementation (OperatorDecl *VD) {
400+ return false ;
401+ }
402+ static bool isMemberImplementation (PrecedenceGroupDecl *VD) {
403+ return false ;
404+ }
405+
396406// / Given a set of declarations whose names and interface types have matched,
397407// / figure out which of these declarations have been shadowed by others.
398408template <typename T>
@@ -412,7 +422,8 @@ static void recordShadowedDeclsAfterTypeMatch(
412422 for (unsigned firstIdx : indices (decls)) {
413423 auto firstDecl = decls[firstIdx];
414424 auto firstModule = firstDecl->getModuleContext ();
415- bool firstTopLevel = firstDecl->getDeclContext ()->isModuleScopeContext ();
425+ auto firstDC = firstDecl->getDeclContext ();
426+ bool firstTopLevel = firstDC->isModuleScopeContext ();
416427
417428 auto name = firstDecl->getBaseName ();
418429
@@ -454,7 +465,8 @@ static void recordShadowedDeclsAfterTypeMatch(
454465 // Determine whether one module takes precedence over another.
455466 auto secondDecl = decls[secondIdx];
456467 auto secondModule = secondDecl->getModuleContext ();
457- bool secondTopLevel = secondDecl->getDeclContext ()->isModuleScopeContext ();
468+ auto secondDC = secondDecl->getDeclContext ();
469+ bool secondTopLevel = secondDC->isModuleScopeContext ();
458470 bool secondPrivate = isPrivateImport (secondModule);
459471
460472 // For member types, we skip most of the below rules. Instead, we allow
@@ -538,6 +550,22 @@ static void recordShadowedDeclsAfterTypeMatch(
538550 }
539551 }
540552
553+ // Member implementations are usually filtered out by access control.
554+ // They're sometimes visible in contexts that can directly access storage,
555+ // though, and there they should shadow the matching imported declaration.
556+ if (firstDC != secondDC
557+ && firstDC->getImplementedObjCContext () ==
558+ secondDC->getImplementedObjCContext ()) {
559+ if (isMemberImplementation (firstDecl) && secondDecl->hasClangNode ()) {
560+ shadowed.insert (secondDecl);
561+ continue ;
562+ }
563+ if (isMemberImplementation (secondDecl) && firstDecl->hasClangNode ()) {
564+ shadowed.insert (firstDecl);
565+ continue ;
566+ }
567+ }
568+
541569 // Swift 4 compatibility hack: Don't shadow properties defined in
542570 // extensions of generic types with properties defined elsewhere.
543571 // This is due to the fact that in Swift 4, we only gave custom overload
0 commit comments