Skip to content

Commit 6a6cc48

Browse files
authored
Merge pull request #77832 from rmaz/namedpatterndiag
Add access level import diagnostic for named pattern.
2 parents c1ff2c3 + 5bcf1bf commit 6a6cc48

File tree

2 files changed

+49
-22
lines changed

2 files changed

+49
-22
lines changed

lib/Sema/TypeCheckAccess.cpp

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -376,33 +376,27 @@ static void highlightOffendingType(InFlightDiagnostic &diag,
376376

377377
/// Emit a note on \p limitImport when it restricted the access level
378378
/// of a type.
379-
static void noteLimitingImport(const Decl *userDecl,
380-
ASTContext &ctx,
379+
static void noteLimitingImport(const Decl *userDecl, ASTContext &ctx,
381380
const ImportAccessLevel limitImport,
382-
const TypeRepr *complainRepr) {
381+
const Decl *complainDecl) {
383382
if (!limitImport.has_value())
384383
return;
385384

386385
assert(limitImport->accessLevel != AccessLevel::Public &&
387386
"a public import shouldn't limit the access level of a decl");
388387

389-
if (auto *declRefTR = dyn_cast_or_null<DeclRefTypeRepr>(complainRepr)) {
390-
ValueDecl *VD = declRefTR->getBoundDecl();
391-
388+
if (complainDecl) {
392389
// When using an IDE in a large file the decl_import_via_here note
393390
// may be easy to miss on the import. Duplicate the information on the
394391
// error line as well so it can't be missed.
395392
if (userDecl)
396-
userDecl->diagnose(diag::decl_import_via_local,
397-
VD,
398-
limitImport->accessLevel,
399-
limitImport->module.importedModule);
393+
userDecl->diagnose(diag::decl_import_via_local, complainDecl,
394+
limitImport->accessLevel,
395+
limitImport->module.importedModule);
400396

401397
if (limitImport->importLoc.isValid())
402-
ctx.Diags.diagnose(limitImport->importLoc,
403-
diag::decl_import_via_here,
404-
VD,
405-
limitImport->accessLevel,
398+
ctx.Diags.diagnose(limitImport->importLoc, diag::decl_import_via_here,
399+
complainDecl, limitImport->accessLevel,
406400
limitImport->module.importedModule);
407401
} else if (limitImport->importLoc.isValid()) {
408402
ctx.Diags.diagnose(limitImport->importLoc, diag::module_imported_here,
@@ -411,14 +405,21 @@ static void noteLimitingImport(const Decl *userDecl,
411405
}
412406
}
413407

414-
static void noteLimitingImport(const Decl *userDecl,
408+
static void noteLimitingImport(const Decl *userDecl, ASTContext &ctx,
415409
const ImportAccessLevel limitImport,
416410
const TypeRepr *complainRepr) {
417-
if (!limitImport.has_value())
418-
return;
411+
const Decl *complainDecl = nullptr;
412+
if (auto *declRefTR = dyn_cast_or_null<DeclRefTypeRepr>(complainRepr))
413+
complainDecl = declRefTR->getBoundDecl();
419414

420-
ASTContext &ctx = userDecl->getASTContext();
421-
noteLimitingImport(userDecl, ctx, limitImport, complainRepr);
415+
noteLimitingImport(userDecl, ctx, limitImport, complainDecl);
416+
}
417+
418+
static void noteLimitingImport(const Decl *userDecl,
419+
const ImportAccessLevel limitImport,
420+
const TypeRepr *complainRepr) {
421+
noteLimitingImport(userDecl, userDecl->getASTContext(), limitImport,
422+
complainRepr);
422423
}
423424

424425
void AccessControlCheckerBase::checkGenericParamAccess(
@@ -625,7 +626,8 @@ class AccessControlChecker : public AccessControlCheckerBase,
625626
if (seenVars.count(theVar) || theVar->isInvalid())
626627
return;
627628

628-
checkTypeAccess(theVar->getInterfaceType(), nullptr, theVar,
629+
Type interfaceType = theVar->getInterfaceType();
630+
checkTypeAccess(interfaceType, nullptr, theVar,
629631
/*mayBeInferred*/false,
630632
[&](AccessScope typeAccessScope,
631633
const TypeRepr *complainRepr,
@@ -644,8 +646,24 @@ class AccessControlChecker : public AccessControlCheckerBase,
644646
DE.diagnose(NP->getLoc(), diagID, theVar->isLet(),
645647
isTypeContext, isExplicit, theVarAccess,
646648
isa<FileUnit>(theVar->getDeclContext()),
647-
typeAccess, theVar->getInterfaceType());
648-
noteLimitingImport(theVar, importLimit, complainRepr);
649+
typeAccess, interfaceType);
650+
651+
// As we pass in a null typeRepr the complainRepr will always be null.
652+
// Extract the module import from the interface type instead.
653+
const Decl *complainDecl = nullptr;
654+
ImportAccessLevel complainImport = std::nullopt;
655+
interfaceType.walk(SimpleTypeDeclFinder([&](const ValueDecl *VD) {
656+
ImportAccessLevel import = VD->getImportAccessFrom(theVar->getDeclContext());
657+
if (import.has_value() && import->accessLevel < VD->getFormalAccess()) {
658+
complainDecl = VD;
659+
complainImport = import;
660+
return TypeWalker::Action::Stop;
661+
}
662+
return TypeWalker::Action::Continue;
663+
}));
664+
665+
noteLimitingImport(theVar, theVar->getASTContext(), complainImport,
666+
complainDecl);
649667
});
650668
}
651669

test/Sema/access-level-import-exportability.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,9 +760,13 @@ public struct PublicVars {
760760

761761
public var k = PublicImportType()
762762
public var l = PackageImportType() // expected-error {{property cannot be declared public because its type 'PackageImportType' uses a package type}}
763+
// expected-note @-1 {{is imported by this file as}}
763764
public var m = InternalImportType() // expected-error {{property cannot be declared public because its type 'InternalImportType' uses an internal type}}
765+
// expected-note @-1 {{is imported by this file as}}
764766
public var n = FileprivateImportType() // expected-error {{property cannot be declared public because its type 'FileprivateImportType' uses a fileprivate type}}
767+
// expected-note @-1 {{is imported by this file as}}
765768
public var o = PrivateImportType() // expected-error {{property cannot be declared public because its type 'PrivateImportType' uses a private type}}
769+
// expected-note @-1 {{is imported by this file as}}
766770
}
767771

768772
package struct PackageVars {
@@ -792,8 +796,11 @@ package struct PackageVars {
792796
package var k = PublicImportType()
793797
package var l = PackageImportType()
794798
package var m = InternalImportType() // expected-error {{property cannot be declared package because its type 'InternalImportType' uses an internal type}}
799+
// expected-note @-1 {{is imported by this file as}}
795800
package var n = FileprivateImportType() // expected-error {{property cannot be declared package because its type 'FileprivateImportType' uses a fileprivate type}}
801+
// expected-note @-1 {{is imported by this file as}}
796802
package var o = PrivateImportType() // expected-error {{property cannot be declared package because its type 'PrivateImportType' uses a private type}}
803+
// expected-note @-1 {{is imported by this file as}}
797804
}
798805

799806
internal struct InternalVars {
@@ -822,7 +829,9 @@ internal struct InternalVars {
822829
internal var l = PackageImportType()
823830
internal var m = InternalImportType()
824831
internal var n = FileprivateImportType() // expected-error {{property cannot be declared internal because its type 'FileprivateImportType' uses a fileprivate type}}
832+
// expected-note @-1 {{is imported by this file as}}
825833
internal var o = PrivateImportType() // expected-error {{property cannot be declared internal because its type 'PrivateImportType' uses a private type}}
834+
// expected-note @-1 {{is imported by this file as}}
826835
}
827836

828837
fileprivate struct FileprivateVars {

0 commit comments

Comments
 (0)