@@ -193,6 +193,27 @@ static void recordShadowedDeclsAfterSignatureMatch(
193
193
auto firstDecl = decls[firstIdx];
194
194
auto firstModule = firstDecl->getModuleContext ();
195
195
auto name = firstDecl->getBaseName ();
196
+
197
+ auto isShadowed = [&](ArrayRef<ModuleDecl::AccessPathTy> paths) {
198
+ for (auto path : paths) {
199
+ if (ModuleDecl::matchesAccessPath (path, name))
200
+ return false ;
201
+ }
202
+
203
+ return true ;
204
+ };
205
+
206
+ auto isScopedImport = [&](ArrayRef<ModuleDecl::AccessPathTy> paths) {
207
+ for (auto path : paths) {
208
+ if (path.empty ())
209
+ continue ;
210
+ if (ModuleDecl::matchesAccessPath (path, name))
211
+ return true ;
212
+ }
213
+
214
+ return false ;
215
+ };
216
+
196
217
for (unsigned secondIdx : range (firstIdx + 1 , decls.size ())) {
197
218
// Determine whether one module takes precedence over another.
198
219
auto secondDecl = decls[secondIdx];
@@ -206,22 +227,28 @@ static void recordShadowedDeclsAfterSignatureMatch(
206
227
if (firstModule != secondModule &&
207
228
firstDecl->getDeclContext ()->isModuleScopeContext () &&
208
229
secondDecl->getDeclContext ()->isModuleScopeContext ()) {
209
- // First, scoped imports shadow unscoped imports.
210
- bool firstScoped = imports.isScopedImport (firstModule, name, dc);
211
- bool secondScoped = imports.isScopedImport (secondModule, name, dc);
212
- if (!firstScoped && secondScoped) {
230
+ auto firstPaths = imports.getAllAccessPathsNotShadowedBy (
231
+ firstModule, secondModule, dc);
232
+ auto secondPaths = imports.getAllAccessPathsNotShadowedBy (
233
+ secondModule, firstModule, dc);
234
+
235
+ // Check if one module shadows the other.
236
+ if (isShadowed (firstPaths)) {
213
237
shadowed.insert (firstDecl);
214
238
break ;
215
- } else if (firstScoped && !secondScoped ) {
239
+ } else if (isShadowed (secondPaths) ) {
216
240
shadowed.insert (secondDecl);
217
241
continue ;
218
242
}
219
243
220
- // Now check if one module shadows the other.
221
- if (imports.isShadowedBy (firstModule, secondModule, name, dc)) {
244
+ // We might be in a situation where neither module shadows the
245
+ // other, but one declaration is visible via a scoped import.
246
+ bool firstScoped = isScopedImport (firstPaths);
247
+ bool secondScoped = isScopedImport (secondPaths);
248
+ if (!firstScoped && secondScoped) {
222
249
shadowed.insert (firstDecl);
223
250
break ;
224
- } else if (imports. isShadowedBy (secondModule, firstModule, name, dc) ) {
251
+ } else if (firstScoped && !secondScoped ) {
225
252
shadowed.insert (secondDecl);
226
253
continue ;
227
254
}
@@ -278,10 +305,16 @@ static void recordShadowedDeclsAfterSignatureMatch(
278
305
if (firstModule != secondModule &&
279
306
!firstDecl->getDeclContext ()->isModuleScopeContext () &&
280
307
!secondDecl->getDeclContext ()->isModuleScopeContext ()) {
281
- if (imports.isShadowedBy (firstModule, secondModule, dc)) {
308
+ auto firstPaths = imports.getAllAccessPathsNotShadowedBy (
309
+ firstModule, secondModule, dc);
310
+ auto secondPaths = imports.getAllAccessPathsNotShadowedBy (
311
+ secondModule, firstModule, dc);
312
+
313
+ // Check if one module shadows the other.
314
+ if (isShadowed (firstPaths)) {
282
315
shadowed.insert (firstDecl);
283
316
break ;
284
- } else if (imports. isShadowedBy (secondModule, firstModule, dc )) {
317
+ } else if (isShadowed (secondPaths )) {
285
318
shadowed.insert (secondDecl);
286
319
continue ;
287
320
}
0 commit comments