Skip to content

Commit d015d16

Browse files
committed
Sema: Diagnose missing imports in during type lookup.
1 parent 1a854e1 commit d015d16

File tree

5 files changed

+42
-4
lines changed

5 files changed

+42
-4
lines changed

lib/Sema/TypeCheckType.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "swift/AST/ExistentialLayout.h"
3131
#include "swift/AST/ForeignErrorConvention.h"
3232
#include "swift/AST/GenericEnvironment.h"
33+
#include "swift/AST/Module.h"
3334
#include "swift/AST/NameLookup.h"
3435
#include "swift/AST/PackExpansionMatcher.h"
3536
#include "swift/AST/ParameterList.h"
@@ -1364,8 +1365,14 @@ static Type diagnoseUnknownType(TypeResolution resolution,
13641365
if (!inaccessibleResults.empty()) {
13651366
// FIXME: What if the unviable candidates have different levels of access?
13661367
auto first = cast<TypeDecl>(inaccessibleResults.front().getValueDecl());
1367-
diags.diagnose(repr->getNameLoc(), diag::candidate_inaccessible,
1368-
first, first->getFormalAccess());
1368+
auto formalAccess = first->getFormalAccess();
1369+
auto nameLoc = repr->getNameLoc();
1370+
if (formalAccess >= AccessLevel::Public &&
1371+
diagnoseMissingImportForMember(first, dc, nameLoc.getStartLoc()))
1372+
return ErrorType::get(ctx);
1373+
1374+
diags.diagnose(nameLoc, diag::candidate_inaccessible, first,
1375+
formalAccess);
13691376

13701377
// FIXME: If any of the candidates (usually just one) are in the same
13711378
// module we could offer a fix-it.
@@ -1454,8 +1461,13 @@ static Type diagnoseUnknownType(TypeResolution resolution,
14541461
if (inaccessibleMembers) {
14551462
// FIXME: What if the unviable candidates have different levels of access?
14561463
const TypeDecl *first = inaccessibleMembers.front().Member;
1457-
diags.diagnose(repr->getNameLoc(), diag::candidate_inaccessible,
1458-
first, first->getFormalAccess());
1464+
auto formalAccess = first->getFormalAccess();
1465+
auto nameLoc = repr->getNameLoc();
1466+
if (formalAccess >= AccessLevel::Public &&
1467+
diagnoseMissingImportForMember(first, dc, nameLoc.getStartLoc()))
1468+
return ErrorType::get(ctx);
1469+
1470+
diags.diagnose(nameLoc, diag::candidate_inaccessible, first, formalAccess);
14591471

14601472
// FIXME: If any of the candidates (usually just one) are in the same module
14611473
// we could offer a fix-it.

test/NameLookup/Inputs/members_A.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ extension X {
1818
public var propXinA: Bool { return true }
1919

2020
public static func <<<(a: Self, b: Self) -> Self { a }
21+
22+
public struct NestedInA {}
2123
}
2224

2325
extension Y {

test/NameLookup/Inputs/members_B.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ extension X {
77
public var propXinB: Bool { return true }
88

99
public static func >>>(a: Self, b: Self) -> Self { b }
10+
11+
public struct NestedInB {}
1012
}
1113

1214
extension Y {

test/NameLookup/Inputs/members_C.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ extension X {
88
public var propXinC: Bool { return true }
99

1010
public static func <>(a: Self, b: Self) -> Self { a }
11+
12+
public struct NestedInC {}
1113
}
1214

1315
extension Y {

test/NameLookup/members_transitive.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,24 @@ extension X {
4646
propXinC
4747
)
4848
}
49+
50+
func testNestedTypes() {
51+
_ = NestedInA.self
52+
_ = NestedInB.self // expected-member-visibility-error{{struct 'NestedInB' is not available due to missing import of defining module 'members_B'}}
53+
_ = NestedInC.self
54+
}
55+
56+
var nestedInA: NestedInA { fatalError() }
57+
var nestedInB: NestedInB { fatalError() } // expected-member-visibility-error{{struct 'NestedInB' is not available due to missing import of defining module 'members_B'}}
58+
var nestedInC: NestedInC { fatalError() }
59+
}
60+
61+
extension X.NestedInA {}
62+
extension X.NestedInB {} // expected-member-visibility-error{{struct 'NestedInB' is not available due to missing import of defining module 'members_B'}}
63+
extension X.NestedInC {}
64+
65+
func testTopLevelTypes() {
66+
_ = EnumInA.self
67+
_ = EnumInB.self // expected-error{{cannot find 'EnumInB' in scope}}
68+
_ = EnumInC.self
4969
}

0 commit comments

Comments
 (0)