@@ -660,19 +660,58 @@ static void recordShadowedDeclsAfterTypeMatch(
660
660
}
661
661
}
662
662
663
- // Next, prefer any other module over the Foundation module
664
- if (auto foundationModule = ctx.getLoadedModule (ctx.Id_Foundation )) {
665
- if ((firstModule == foundationModule) !=
666
- (secondModule == foundationModule)) {
667
- // If second module is Foundation, then it is shadowed by first
668
- if (secondModule == foundationModule) {
669
- shadowed.insert (secondDecl);
670
- continue ;
671
- }
663
+ if (ctx.LangOpts .hasFeature (Feature::ShadowFoundation)) {
664
+ // If `ShadowFoundation` is enabled, allow all types from Foundation
665
+ // to be implicitly shadowed.
666
+ if (auto foundationModule = ctx.getLoadedModule (ctx.Id_Foundation )) {
667
+ if ((firstModule == foundationModule) !=
668
+ (secondModule == foundationModule)) {
669
+ // If second module is Foundation, then it is shadowed by first
670
+ if (secondModule == foundationModule) {
671
+ shadowed.insert (secondDecl);
672
+ continue ;
673
+ }
672
674
673
- // Otherwise, the first declaration is shadowed by the second.
674
- shadowed.insert (firstDecl);
675
- break ;
675
+ // Otherwise, the first declaration is shadowed by the second.
676
+ shadowed.insert (firstDecl);
677
+ break ;
678
+ }
679
+ }
680
+ } else {
681
+ // The Foundation overlay introduced Data.withUnsafeBytes, which is
682
+ // treated as being ambiguous with SwiftNIO's Data.withUnsafeBytes
683
+ // extension. Apply a special-case name shadowing rule to use the
684
+ // latter rather than the former, which be the consequence of a more
685
+ // significant change to name shadowing in the future.
686
+ if (auto owningStruct1
687
+ = firstDecl->getDeclContext ()->getSelfStructDecl ()) {
688
+ if (auto owningStruct2
689
+ = secondDecl->getDeclContext ()->getSelfStructDecl ()) {
690
+ if (owningStruct1 == owningStruct2 &&
691
+ owningStruct1->getName ().is (" Data" ) &&
692
+ isa<FuncDecl>(firstDecl) && isa<FuncDecl>(secondDecl) &&
693
+ firstDecl->getName () == secondDecl->getName () &&
694
+ firstDecl->getBaseName ().userFacingName () == " withUnsafeBytes" ) {
695
+ // If the second module is the Foundation module and the first
696
+ // is the NIOFoundationCompat module, the second is shadowed by the
697
+ // first.
698
+ if (firstDecl->getModuleContext ()->getName ()
699
+ .is (" NIOFoundationCompat" ) &&
700
+ secondDecl->getModuleContext ()->getName ().is (" Foundation" )) {
701
+ shadowed.insert (secondDecl);
702
+ continue ;
703
+ }
704
+
705
+ // If it's the other way around, the first declaration is shadowed
706
+ // by the second.
707
+ if (secondDecl->getModuleContext ()->getName ()
708
+ .is (" NIOFoundationCompat" ) &&
709
+ firstDecl->getModuleContext ()->getName ().is (" Foundation" )) {
710
+ shadowed.insert (firstDecl);
711
+ break ;
712
+ }
713
+ }
714
+ }
676
715
}
677
716
}
678
717
0 commit comments