Skip to content

Commit a26fbd2

Browse files
committed
[Sema] Improve note on access-level downgrade from import
Using an access-level on an import downgrades imported decl from public to the import's access-level. When we can identify which decl is problematic, name it in the note displayed on the import. This should help understanding the effect of the import's access level on the decl causing an error further down in the source file.
1 parent 342e5f6 commit a26fbd2

File tree

6 files changed

+103
-60
lines changed

6 files changed

+103
-60
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2111,6 +2111,11 @@ ERROR(access_level_conflict_with_exported,none,
21112111
NOTE(module_imported_here,none,
21122112
"module %0 imported as '%select{private|fileprivate|internal|package|%ERROR|%ERROR}1' here",
21132113
(Identifier, AccessLevel))
2114+
NOTE(decl_import_via_here,none,
2115+
"%0 %1 imported as "
2116+
"'%select{private|fileprivate|internal|package|%ERROR|%ERROR}2' "
2117+
"from %3 here",
2118+
(DescriptiveDeclKind, DeclName, AccessLevel, Identifier))
21142119

21152120
// Opaque return types
21162121
ERROR(opaque_type_invalid_constraint,none,

lib/Sema/ResilienceDiagnostics.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,10 @@ bool TypeChecker::diagnoseInlinableDeclRefAccess(SourceLoc loc,
124124
if (problematicImport.has_value() &&
125125
diagAccessLevel == importAccessLevel) {
126126
Context.Diags.diagnose(problematicImport->accessLevelLoc,
127-
diag::module_imported_here,
128-
problematicImport->module.importedModule->getName(),
129-
problematicImport->accessLevel);
127+
diag::decl_import_via_here,
128+
D->getDescriptiveKind(), diagName,
129+
problematicImport->accessLevel,
130+
problematicImport->module.importedModule->getName());
130131
}
131132

132133
return (downgradeToWarning == DowngradeToWarning::No);

lib/Sema/TypeCheckAccess.cpp

Lines changed: 63 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -343,15 +343,26 @@ static void highlightOffendingType(InFlightDiagnostic &diag,
343343
/// Emit a note on \p limitImport when it restricted the access level
344344
/// of a type.
345345
static void noteLimitingImport(ASTContext &ctx,
346-
const ImportAccessLevel limitImport) {
346+
const ImportAccessLevel limitImport,
347+
const TypeRepr *complainRepr) {
347348
if (!limitImport.has_value())
348349
return;
349350

350351
assert(limitImport->accessLevel != AccessLevel::Public &&
351352
"a public import shouldn't limit the access level of a decl");
352-
ctx.Diags.diagnose(limitImport->accessLevelLoc, diag::module_imported_here,
353-
limitImport->module.importedModule->getName(),
354-
limitImport->accessLevel);
353+
354+
if (auto ITR = dyn_cast_or_null<IdentTypeRepr>(complainRepr)) {
355+
const ValueDecl *VD = ITR->getBoundDecl();
356+
ctx.Diags.diagnose(limitImport->accessLevelLoc, diag::decl_import_via_here,
357+
DescriptiveDeclKind::Type,
358+
VD->getName(),
359+
limitImport->accessLevel,
360+
limitImport->module.importedModule->getName());
361+
} else {
362+
ctx.Diags.diagnose(limitImport->accessLevelLoc, diag::module_imported_here,
363+
limitImport->module.importedModule->getName(),
364+
limitImport->accessLevel);
365+
}
355366
}
356367

357368
void AccessControlCheckerBase::checkGenericParamAccess(
@@ -435,7 +446,7 @@ void AccessControlCheckerBase::checkGenericParamAccess(
435446
Context.Diags.diagnose(ownerDecl, diagID, ownerDecl->getDescriptiveKind(),
436447
accessControlErrorKind == ACEK::Requirement);
437448
highlightOffendingType(diag, complainRepr);
438-
noteLimitingImport(Context, minImportLimit);
449+
noteLimitingImport(Context, minImportLimit, complainRepr);
439450
return;
440451
}
441452

@@ -450,7 +461,7 @@ void AccessControlCheckerBase::checkGenericParamAccess(
450461
contextAccess, minDiagAccessLevel, isa<FileUnit>(DC),
451462
accessControlErrorKind == ACEK::Requirement);
452463
highlightOffendingType(diag, complainRepr);
453-
noteLimitingImport(Context, minImportLimit);
464+
noteLimitingImport(Context, minImportLimit, complainRepr);
454465
}
455466

456467
void AccessControlCheckerBase::checkGenericParamAccess(
@@ -483,7 +494,7 @@ void AccessControlCheckerBase::checkGlobalActorAccess(const Decl *D) {
483494
auto diag = D->diagnose(diag::global_actor_not_usable_from_inline,
484495
D->getDescriptiveKind(), VD->getName());
485496
highlightOffendingType(diag, complainRepr);
486-
noteLimitingImport(D->getASTContext(), importLimit);
497+
noteLimitingImport(D->getASTContext(), importLimit, complainRepr);
487498
return;
488499
}
489500

@@ -495,7 +506,7 @@ void AccessControlCheckerBase::checkGlobalActorAccess(const Decl *D) {
495506
D->getDescriptiveKind(), VD->getName(),
496507
diagAccessLevel, globalActorDecl->getName());
497508
highlightOffendingType(diag, complainRepr);
498-
noteLimitingImport(D->getASTContext(), importLimit);
509+
noteLimitingImport(D->getASTContext(), importLimit, complainRepr);
499510
});
500511
}
501512

@@ -576,12 +587,11 @@ class AccessControlChecker : public AccessControlCheckerBase,
576587
if (downgradeToWarning == DowngradeToWarning::Yes)
577588
diagID = diag::pattern_type_access_inferred_warn;
578589
auto &DE = theVar->getASTContext().Diags;
579-
auto diag = DE.diagnose(NP->getLoc(), diagID, theVar->isLet(),
580-
isTypeContext, isExplicit, theVarAccess,
581-
isa<FileUnit>(theVar->getDeclContext()),
582-
diagAccessLevel, theVar->getInterfaceType());
583-
diag.flush();
584-
noteLimitingImport(theVar->getASTContext(), importLimit);
590+
DE.diagnose(NP->getLoc(), diagID, theVar->isLet(),
591+
isTypeContext, isExplicit, theVarAccess,
592+
isa<FileUnit>(theVar->getDeclContext()),
593+
diagAccessLevel, theVar->getInterfaceType());
594+
noteLimitingImport(theVar->getASTContext(), importLimit, complainRepr);
585595
});
586596
}
587597

@@ -616,7 +626,7 @@ class AccessControlChecker : public AccessControlCheckerBase,
616626
anyVarAccess, isa<FileUnit>(anyVar->getDeclContext()),
617627
diagAccessLevel);
618628
highlightOffendingType(diag, complainRepr);
619-
noteLimitingImport(anyVar->getASTContext(), importLimit);
629+
noteLimitingImport(anyVar->getASTContext(), importLimit, complainRepr);
620630
});
621631

622632
// Check the property wrapper types.
@@ -642,7 +652,7 @@ class AccessControlChecker : public AccessControlCheckerBase,
642652
isa<FileUnit>(anyVar->getDeclContext()),
643653
diagAccessLevel);
644654
highlightOffendingType(diag, complainRepr);
645-
noteLimitingImport(anyVar->getASTContext(), importLimit);
655+
noteLimitingImport(anyVar->getASTContext(), importLimit, complainRepr);
646656
});
647657
}
648658
}
@@ -692,7 +702,7 @@ class AccessControlChecker : public AccessControlCheckerBase,
692702
diagAccessLevel,
693703
isa<FileUnit>(TAD->getDeclContext()));
694704
highlightOffendingType(diag, complainRepr);
695-
noteLimitingImport(TAD->getASTContext(), importLimit);
705+
noteLimitingImport(TAD->getASTContext(), importLimit, complainRepr);
696706
});
697707
}
698708

@@ -787,7 +797,8 @@ class AccessControlChecker : public AccessControlCheckerBase,
787797
minDiagAccessLevel,
788798
accessControlErrorKind);
789799
highlightOffendingType(diag, complainRepr);
790-
noteLimitingImport(assocType->getASTContext(), minImportLimit);
800+
noteLimitingImport(assocType->getASTContext(), minImportLimit,
801+
complainRepr);
791802
}
792803
}
793804

@@ -823,7 +834,7 @@ class AccessControlChecker : public AccessControlCheckerBase,
823834
diagAccessLevel,
824835
isa<FileUnit>(ED->getDeclContext()));
825836
highlightOffendingType(diag, complainRepr);
826-
noteLimitingImport(ED->getASTContext(), importLimit);
837+
noteLimitingImport(ED->getASTContext(), importLimit, complainRepr);
827838
});
828839
}
829840
}
@@ -885,7 +896,7 @@ class AccessControlChecker : public AccessControlCheckerBase,
885896
isa<FileUnit>(CD->getDeclContext()),
886897
superclassLocIter->getTypeRepr() != complainRepr);
887898
highlightOffendingType(diag, complainRepr);
888-
noteLimitingImport(CD->getASTContext(), importLimit);
899+
noteLimitingImport(CD->getASTContext(), importLimit, complainRepr);
889900
});
890901
}
891902
}
@@ -988,7 +999,7 @@ class AccessControlChecker : public AccessControlCheckerBase,
988999
protocolControlErrorKind, minDiagAccessLevel,
9891000
isa<FileUnit>(proto->getDeclContext()), declKind);
9901001
highlightOffendingType(diag, complainRepr);
991-
noteLimitingImport(proto->getASTContext(), minImportLimit);
1002+
noteLimitingImport(proto->getASTContext(), minImportLimit, complainRepr);
9921003
}
9931004
}
9941005

@@ -1052,7 +1063,7 @@ class AccessControlChecker : public AccessControlCheckerBase,
10521063
auto diag = SD->diagnose(diagID, isExplicit, subscriptDeclAccess,
10531064
minDiagAccessLevel, problemIsElement);
10541065
highlightOffendingType(diag, complainRepr);
1055-
noteLimitingImport(SD->getASTContext(), minImportLimit);
1066+
noteLimitingImport(SD->getASTContext(), minImportLimit, complainRepr);
10561067
}
10571068
}
10581069

@@ -1159,7 +1170,7 @@ class AccessControlChecker : public AccessControlCheckerBase,
11591170
functionKind, problemIsResult,
11601171
hasInaccessibleParameterWrapper);
11611172
highlightOffendingType(diag, complainRepr);
1162-
noteLimitingImport(fn->getASTContext(), minImportLimit);
1173+
noteLimitingImport(fn->getASTContext(), minImportLimit, complainRepr);
11631174
}
11641175
}
11651176

@@ -1178,7 +1189,8 @@ class AccessControlChecker : public AccessControlCheckerBase,
11781189
auto diag =
11791190
EED->diagnose(diagID, EED->getFormalAccess(), diagAccessLevel);
11801191
highlightOffendingType(diag, complainRepr);
1181-
noteLimitingImport(EED->getASTContext(), importLimit);
1192+
noteLimitingImport(EED->getASTContext(), importLimit,
1193+
complainRepr);
11821194
});
11831195
}
11841196
}
@@ -1244,7 +1256,7 @@ class AccessControlChecker : public AccessControlCheckerBase,
12441256
auto diag = MD->diagnose(diagID, isExplicit, macroDeclAccess,
12451257
minDiagAccessLevel, problemIsResult);
12461258
highlightOffendingType(diag, complainRepr);
1247-
noteLimitingImport(MD->getASTContext(), minImportLimit);
1259+
noteLimitingImport(MD->getASTContext(), minImportLimit, complainRepr);
12481260
}
12491261
}
12501262
};
@@ -1353,7 +1365,8 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
13531365
}
13541366
Ctx.Diags.diagnose(NP->getLoc(), diagID, theVar->isLet(),
13551367
isTypeContext, theVar->getInterfaceType());
1356-
noteLimitingImport(theVar->getASTContext(), importLimit);
1368+
noteLimitingImport(theVar->getASTContext(), importLimit,
1369+
complainRepr);
13571370
});
13581371
}
13591372

@@ -1392,7 +1405,8 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
13921405
auto diag = Ctx.Diags.diagnose(TP->getLoc(), diagID, anyVar->isLet(),
13931406
isTypeContext);
13941407
highlightOffendingType(diag, complainRepr);
1395-
noteLimitingImport(anyVar->getASTContext(), importLimit);
1408+
noteLimitingImport(anyVar->getASTContext(), importLimit,
1409+
complainRepr);
13961410
});
13971411

13981412
for (auto attr : anyVar->getAttachedPropertyWrappers()) {
@@ -1403,12 +1417,13 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
14031417
[&](AccessScope typeAccessScope,
14041418
const TypeRepr *complainRepr,
14051419
DowngradeToWarning downgradeToWarning,
1406-
ImportAccessLevel importLimit, AccessLevel diagAccessLevel) {
1420+
ImportAccessLevel importLimit,
1421+
AccessLevel diagAccessLevel) {
14071422
auto diag = anyVar->diagnose(
14081423
diag::property_wrapper_type_not_usable_from_inline,
14091424
anyVar->isLet(), isTypeContext);
14101425
highlightOffendingType(diag, complainRepr);
1411-
noteLimitingImport(anyVar->getASTContext(), importLimit);
1426+
noteLimitingImport(anyVar->getASTContext(), importLimit, complainRepr);
14121427
});
14131428
}
14141429
}
@@ -1447,7 +1462,7 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
14471462
diagID = diag::type_alias_underlying_type_not_usable_from_inline_warn;
14481463
auto diag = TAD->diagnose(diagID);
14491464
highlightOffendingType(diag, complainRepr);
1450-
noteLimitingImport(TAD->getASTContext(), importLimit);
1465+
noteLimitingImport(TAD->getASTContext(), importLimit, complainRepr);
14511466
});
14521467
}
14531468

@@ -1471,7 +1486,8 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
14711486
diagID = diag::associated_type_not_usable_from_inline_warn;
14721487
auto diag = assocType->diagnose(diagID, ACEK_Requirement);
14731488
highlightOffendingType(diag, complainRepr);
1474-
noteLimitingImport(assocType->getASTContext(), importLimit);
1489+
noteLimitingImport(assocType->getASTContext(), importLimit,
1490+
complainRepr);
14751491
});
14761492
});
14771493
checkTypeAccess(assocType->getDefaultDefinitionType(),
@@ -1487,7 +1503,8 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
14871503
diagID = diag::associated_type_not_usable_from_inline_warn;
14881504
auto diag = assocType->diagnose(diagID, ACEK_DefaultDefinition);
14891505
highlightOffendingType(diag, complainRepr);
1490-
noteLimitingImport(assocType->getASTContext(), importLimit);
1506+
noteLimitingImport(assocType->getASTContext(), importLimit,
1507+
complainRepr);
14911508
});
14921509

14931510
if (assocType->getTrailingWhereClause()) {
@@ -1506,7 +1523,8 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
15061523
diagID = diag::associated_type_not_usable_from_inline_warn;
15071524
auto diag = assocType->diagnose(diagID, ACEK_Requirement);
15081525
highlightOffendingType(diag, complainRepr);
1509-
noteLimitingImport(assocType->getASTContext(), importLimit);
1526+
noteLimitingImport(assocType->getASTContext(), importLimit,
1527+
complainRepr);
15101528
});
15111529
}
15121530
}
@@ -1537,7 +1555,7 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
15371555
diagID = diag::enum_raw_type_not_usable_from_inline_warn;
15381556
auto diag = ED->diagnose(diagID);
15391557
highlightOffendingType(diag, complainRepr);
1540-
noteLimitingImport(ED->getASTContext(), importLimit);
1558+
noteLimitingImport(ED->getASTContext(), importLimit, complainRepr);
15411559
});
15421560
}
15431561
}
@@ -1583,7 +1601,7 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
15831601
auto diag = CD->diagnose(diagID, superclassLocIter->getTypeRepr() !=
15841602
complainRepr);
15851603
highlightOffendingType(diag, complainRepr);
1586-
noteLimitingImport(CD->getASTContext(), importLimit);
1604+
noteLimitingImport(CD->getASTContext(), importLimit, complainRepr);
15871605
});
15881606
}
15891607
}
@@ -1609,7 +1627,7 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
16091627
diagID = diag::protocol_usable_from_inline_warn;
16101628
auto diag = proto->diagnose(diagID, PCEK_Refine);
16111629
highlightOffendingType(diag, complainRepr);
1612-
noteLimitingImport(proto->getASTContext(), importLimit);
1630+
noteLimitingImport(proto->getASTContext(), importLimit, complainRepr);
16131631
});
16141632
});
16151633

@@ -1629,7 +1647,7 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
16291647
diagID = diag::protocol_usable_from_inline_warn;
16301648
auto diag = proto->diagnose(diagID, PCEK_Requirement);
16311649
highlightOffendingType(diag, complainRepr);
1632-
noteLimitingImport(proto->getASTContext(), importLimit);
1650+
noteLimitingImport(proto->getASTContext(), importLimit, complainRepr);
16331651
});
16341652
}
16351653
}
@@ -1649,7 +1667,7 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
16491667
diagID = diag::subscript_type_usable_from_inline_warn;
16501668
auto diag = SD->diagnose(diagID, /*problemIsElement=*/false);
16511669
highlightOffendingType(diag, complainRepr);
1652-
noteLimitingImport(SD->getASTContext(), importLimit);
1670+
noteLimitingImport(SD->getASTContext(), importLimit, complainRepr);
16531671
});
16541672
}
16551673

@@ -1665,7 +1683,7 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
16651683
diagID = diag::subscript_type_usable_from_inline_warn;
16661684
auto diag = SD->diagnose(diagID, /*problemIsElement=*/true);
16671685
highlightOffendingType(diag, complainRepr);
1668-
noteLimitingImport(SD->getASTContext(), importLimit);
1686+
noteLimitingImport(SD->getASTContext(), importLimit, complainRepr);
16691687
});
16701688
}
16711689

@@ -1703,7 +1721,8 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
17031721
/*problemIsResult=*/false,
17041722
/*inaccessibleWrapper=*/true);
17051723
highlightOffendingType(diag, complainRepr);
1706-
noteLimitingImport(fn->getASTContext(), importLimit);
1724+
noteLimitingImport(fn->getASTContext(), importLimit,
1725+
complainRepr);
17071726
});
17081727
}
17091728
}
@@ -1720,7 +1739,7 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
17201739
/*problemIsResult=*/false,
17211740
/*inaccessibleWrapper=*/false);
17221741
highlightOffendingType(diag, complainRepr);
1723-
noteLimitingImport(fn->getASTContext(), importLimit);
1742+
noteLimitingImport(fn->getASTContext(), importLimit, complainRepr);
17241743
});
17251744
}
17261745

@@ -1738,7 +1757,7 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
17381757
/*problemIsResult=*/true,
17391758
/*inaccessibleWrapper=*/false);
17401759
highlightOffendingType(diag, complainRepr);
1741-
noteLimitingImport(fn->getASTContext(), importLimit);
1760+
noteLimitingImport(fn->getASTContext(), importLimit, complainRepr);
17421761
});
17431762
}
17441763
}
@@ -1762,7 +1781,8 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
17621781
diagID = diag::enum_case_usable_from_inline_warn;
17631782
auto diag = EED->diagnose(diagID);
17641783
highlightOffendingType(diag, complainRepr);
1765-
noteLimitingImport(EED->getASTContext(), importLimit);
1784+
noteLimitingImport(EED->getASTContext(), importLimit,
1785+
complainRepr);
17661786
});
17671787
}
17681788
}

0 commit comments

Comments
 (0)