Skip to content

Commit 0c5eac5

Browse files
committed
Sema: Downgrade missing import diagnostics for key paths.
For now, downgrade the `MemberImportVisibility` diagnostics introduced in #83934 to warnings. Resolves rdar://160146503.
1 parent ca35ad7 commit 0c5eac5

File tree

6 files changed

+52
-27
lines changed

6 files changed

+52
-27
lines changed

include/swift/AST/SourceFile.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ class SourceFile final : public FileUnit {
137137

138138
/// Associates a list of source locations to the member declarations that must
139139
/// be diagnosed as being out of scope due to a missing import.
140-
using DelayedMissingImportForMemberDiags =
141-
llvm::SmallDenseMap<const ValueDecl *, std::vector<SourceLoc>>;
140+
using DelayedMissingImportForMemberDiags = llvm::SmallDenseMap<
141+
const ValueDecl *, std::vector<std::pair<SourceLoc, DiagnosticBehavior>>>;
142142
DelayedMissingImportForMemberDiags MissingImportForMemberDiagnostics;
143143

144144
/// A unique identifier representing this file; used to mark private decls
@@ -518,8 +518,9 @@ class SourceFile final : public FileUnit {
518518
/// Add a source location for which a delayed missing import for member
519519
/// diagnostic should be emited.
520520
void addDelayedMissingImportForMemberDiagnostic(const ValueDecl *decl,
521-
SourceLoc loc) {
522-
MissingImportForMemberDiagnostics[decl].push_back(loc);
521+
SourceLoc loc,
522+
DiagnosticBehavior limit) {
523+
MissingImportForMemberDiagnostics[decl].push_back({loc, limit});
523524
}
524525

525526
DelayedMissingImportForMemberDiags

lib/Sema/MiscDiagnostics.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6382,20 +6382,25 @@ static void diagnoseMissingMemberImports(const Expr *E, const DeclContext *DC) {
63826382
if (auto *KPE = dyn_cast<KeyPathExpr>(E)) {
63836383
for (const auto &component : KPE->getComponents()) {
63846384
if (component.hasDeclRef())
6385-
checkDecl(component.getDeclRef().getDecl(), component.getLoc());
6385+
checkDecl(component.getDeclRef().getDecl(), component.getLoc(),
6386+
/*downgradeToWarning=*/true);
63866387
}
63876388
}
63886389

63896390
return Action::Continue(E);
63906391
}
63916392

6392-
void checkDecl(const ValueDecl *decl, SourceLoc loc) {
6393+
void checkDecl(const ValueDecl *decl, SourceLoc loc,
6394+
bool downgradeToWarning = false) {
63936395
// Only diagnose uses of members.
63946396
if (!decl->getDeclContext()->isTypeContext())
63956397
return;
63966398

63976399
if (!dc->isDeclImported(decl))
6398-
maybeDiagnoseMissingImportForMember(decl, dc, loc);
6400+
maybeDiagnoseMissingImportForMember(
6401+
decl, dc, loc,
6402+
downgradeToWarning ? DiagnosticBehavior::Warning
6403+
: DiagnosticBehavior::Unspecified);
63996404
}
64006405
};
64016406

lib/Sema/TypeCheckNameLookup.cpp

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -924,20 +924,23 @@ class MissingImportFixItCache {
924924
}
925925
};
926926

927-
static void
928-
diagnoseMissingImportsForMember(const ValueDecl *decl,
929-
SmallVectorImpl<ModuleDecl *> &modulesToImport,
930-
SourceFile *sf, SourceLoc loc) {
927+
static void diagnoseMissingImportsForMember(
928+
const ValueDecl *decl, SmallVectorImpl<ModuleDecl *> &modulesToImport,
929+
SourceFile *sf, SourceLoc loc, DiagnosticBehavior limit) {
931930
auto &ctx = sf->getASTContext();
932931
auto count = modulesToImport.size();
933932
ASSERT(count > 0);
934933

935934
if (count > 1) {
936-
ctx.Diags.diagnose(loc, diag::member_from_missing_imports_2_or_more, decl,
937-
bool(count > 2), modulesToImport[0], modulesToImport[1]);
935+
ctx.Diags
936+
.diagnose(loc, diag::member_from_missing_imports_2_or_more, decl,
937+
bool(count > 2), modulesToImport[0], modulesToImport[1])
938+
.limitBehavior(limit);
938939
} else {
939-
ctx.Diags.diagnose(loc, diag::member_from_missing_import, decl,
940-
modulesToImport.front());
940+
ctx.Diags
941+
.diagnose(loc, diag::member_from_missing_import, decl,
942+
modulesToImport.front())
943+
.limitBehavior(limit);
941944
}
942945
}
943946

@@ -983,7 +986,7 @@ static void emitMissingImportNoteAndFixIt(
983986

984987
static void
985988
diagnoseAndFixMissingImportForMember(const ValueDecl *decl, SourceFile *sf,
986-
SourceLoc loc,
989+
SourceLoc loc, DiagnosticBehavior limit,
987990
MissingImportFixItCache &fixItCache) {
988991

989992
auto modulesAndFixits =
@@ -994,7 +997,7 @@ diagnoseAndFixMissingImportForMember(const ValueDecl *decl, SourceFile *sf,
994997
if (modulesToImport.empty())
995998
return;
996999

997-
diagnoseMissingImportsForMember(decl, modulesToImport, sf, loc);
1000+
diagnoseMissingImportsForMember(decl, modulesToImport, sf, loc, limit);
9981001

9991002
auto &ctx = sf->getASTContext();
10001003
SourceLoc bestLoc = ctx.Diags.getBestAddImportFixItLoc(sf);
@@ -1008,7 +1011,8 @@ diagnoseAndFixMissingImportForMember(const ValueDecl *decl, SourceFile *sf,
10081011

10091012
bool swift::maybeDiagnoseMissingImportForMember(const ValueDecl *decl,
10101013
const DeclContext *dc,
1011-
SourceLoc loc) {
1014+
SourceLoc loc,
1015+
DiagnosticBehavior limit) {
10121016
if (dc->isDeclImported(decl))
10131017
return false;
10141018

@@ -1040,11 +1044,11 @@ bool swift::maybeDiagnoseMissingImportForMember(const ValueDecl *decl,
10401044
if (modulesToImport.empty())
10411045
return false;
10421046

1043-
diagnoseMissingImportsForMember(decl, modulesToImport, sf, loc);
1047+
diagnoseMissingImportsForMember(decl, modulesToImport, sf, loc, limit);
10441048
return true;
10451049
}
10461050

1047-
sf->addDelayedMissingImportForMemberDiagnostic(decl, loc);
1051+
sf->addDelayedMissingImportForMemberDiagnostic(decl, loc, limit);
10481052
return false;
10491053
}
10501054

@@ -1103,7 +1107,8 @@ void migrateToMemberImportVisibility(SourceFile &sf) {
11031107
if (locs == delayedDiags.end())
11041108
continue;
11051109

1106-
for (auto loc : locs->second) {
1110+
for (auto locAndLimit : locs->second) {
1111+
auto loc = locAndLimit.first;
11071112
ctx.Diags.diagnose(loc, diag::decl_from_module_used_here, decl, mod);
11081113
}
11091114
}
@@ -1122,8 +1127,9 @@ void swift::diagnoseMissingImports(SourceFile &sf) {
11221127
auto fixItCache = MissingImportFixItCache(sf);
11231128

11241129
for (auto declAndLocs : delayedDiags) {
1125-
for (auto loc : declAndLocs.second) {
1126-
diagnoseAndFixMissingImportForMember(declAndLocs.first, &sf, loc,
1130+
for (auto locAndLimit : declAndLocs.second) {
1131+
auto [loc, limit] = locAndLimit;
1132+
diagnoseAndFixMissingImportForMember(declAndLocs.first, &sf, loc, limit,
11271133
fixItCache);
11281134
}
11291135
}

lib/Sema/TypeChecker.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,8 +1531,9 @@ void diagnoseUnnecessaryPublicImports(SourceFile &SF);
15311531
/// delayed, the diagnostic will instead be emitted after type checking the
15321532
/// entire file and will include an appropriate fix-it. Returns true if a
15331533
/// diagnostic was emitted (and not delayed).
1534-
bool maybeDiagnoseMissingImportForMember(const ValueDecl *decl,
1535-
const DeclContext *dc, SourceLoc loc);
1534+
bool maybeDiagnoseMissingImportForMember(
1535+
const ValueDecl *decl, const DeclContext *dc, SourceLoc loc,
1536+
DiagnosticBehavior limit = DiagnosticBehavior::Unspecified);
15361537

15371538
/// Emit delayed diagnostics regarding imports that should be added to the
15381539
/// source file.

test/NameLookup/member_import_visibility.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ func testExtensionMembers(x: X, y: Y<Z>) {
4747
func takesKeyPath<T, U>(_ t: T, _ keyPath: KeyPath<T, U>) -> () { }
4848

4949
takesKeyPath(x, \.propXinA)
50-
takesKeyPath(x, \.propXinB) // expected-member-visibility-error{{property 'propXinB' is not available due to missing import of defining module 'members_B'}}
50+
takesKeyPath(x, \.propXinB) // expected-member-visibility-warning{{property 'propXinB' is not available due to missing import of defining module 'members_B'}}
5151
takesKeyPath(x, \.propXinC)
5252

5353
takesKeyPath(x, \.propXinA.description)
54-
takesKeyPath(x, \.propXinB.description) // expected-member-visibility-error{{property 'propXinB' is not available due to missing import of defining module 'members_B'}}
54+
takesKeyPath(x, \.propXinB.description) // expected-member-visibility-warning{{property 'propXinB' is not available due to missing import of defining module 'members_B'}}
5555
takesKeyPath(x, \.propXinC.description)
5656
}
5757

test/NameLookup/member_import_visibility_migrate.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ func internalFunc(_ x: Int) {
4848
_ = x.memberInInternalUsesOnlyTransitivelyImported // expected-note {{property 'memberInInternalUsesOnlyTransitivelyImported' from 'InternalUsesOnlyTransitivelyImported' used here}}
4949
}
5050

51+
func keyPaths(_ x: Int) {
52+
func takesKeyPath<T, U>(_ t: T, _ keyPath: KeyPath<T, U>) -> () { }
53+
54+
takesKeyPath(x, \.memberInInternalUsesOnly) // expected-note {{property 'memberInInternalUsesOnly' from 'InternalUsesOnly' used here}}
55+
takesKeyPath(x, \.memberInInternalUsesOnlyDefaultedImport) // expected-note {{property 'memberInInternalUsesOnlyDefaultedImport' from 'InternalUsesOnlyDefaultedImport' used here}}
56+
takesKeyPath(x, \.memberInMixedUses) // expected-note {{property 'memberInMixedUses' from 'MixedUses' used here}}
57+
takesKeyPath(x, \.memberInInternalUsesOnlyReexported) // expected-note {{property 'memberInInternalUsesOnlyReexported' from 'InternalUsesOnlyReexported' used here}}
58+
takesKeyPath(x, \.memberInInternalUsesOnlySPIOnly) // expected-note {{property 'memberInInternalUsesOnlySPIOnly' from 'InternalUsesOnlySPIOnly' used here}}
59+
takesKeyPath(x, \.memberInInternalUsesOnlyDefaultedImportSPIOnly) // expected-note {{property 'memberInInternalUsesOnlyDefaultedImportSPIOnly' from 'InternalUsesOnlyDefaultedImportSPIOnly' used here}}
60+
takesKeyPath(x, \.memberInInternalUsesOnlyTransitivelyImported) // expected-note {{property 'memberInInternalUsesOnlyTransitivelyImported' from 'InternalUsesOnlyTransitivelyImported' used here}}
61+
}
62+
5163
@inlinable package func packageInlinableFunc(_ x: Int) {
5264
_ = x.memberInPackageUsesOnly // expected-note {{property 'memberInPackageUsesOnly' from 'PackageUsesOnly' used here}}
5365
_ = x.memberInMixedUses // expected-note {{property 'memberInMixedUses' from 'MixedUses' used here}}

0 commit comments

Comments
 (0)