Skip to content

Commit 8d95352

Browse files
authored
Give a proper error when a member type is inaccessible. (#4033)
This doesn't yet cover top-level types or top-level non-type values, but it's a start. Part of rdar://problem/27663403.
1 parent 7ad3e83 commit 8d95352

File tree

3 files changed

+47
-5
lines changed

3 files changed

+47
-5
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2587,6 +2587,7 @@ diagnoseUnviableLookupResults(MemberLookupResult &result, Type baseObjTy,
25872587

25882588
case MemberLookupResult::UR_Inaccessible: {
25892589
auto decl = result.UnviableCandidates[0].first;
2590+
// FIXME: What if the unviable candidates have different levels of access?
25902591
diagnose(nameLoc, diag::candidate_inaccessible, decl->getName(),
25912592
decl->getFormalAccess());
25922593
for (auto cand : result.UnviableCandidates)

lib/Sema/TypeCheckType.cpp

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,7 @@ static Type diagnoseUnknownType(TypeChecker &tc, DeclContext *dc,
724724
SourceRange parentRange,
725725
ComponentIdentTypeRepr *comp,
726726
TypeResolutionOptions options,
727+
NameLookupOptions lookupOptions,
727728
GenericTypeResolver *resolver,
728729
UnsatisfiedDependency *unsatisfiedDependency) {
729730
// Unqualified lookup case.
@@ -785,6 +786,30 @@ static Type diagnoseUnknownType(TypeChecker &tc, DeclContext *dc,
785786
}
786787

787788
// Qualified lookup case.
789+
790+
// Try ignoring access control.
791+
NameLookupOptions relookupOptions = lookupOptions;
792+
relookupOptions |= NameLookupFlags::KnownPrivate;
793+
relookupOptions |= NameLookupFlags::IgnoreAccessibility;
794+
auto inaccessibleMembers = tc.lookupMemberType(dc, parentType,
795+
comp->getIdentifier(),
796+
relookupOptions);
797+
if (inaccessibleMembers) {
798+
// FIXME: What if the unviable candidates have different levels of access?
799+
const TypeDecl *first = inaccessibleMembers.front().first;
800+
tc.diagnose(comp->getIdLoc(), diag::candidate_inaccessible,
801+
comp->getIdentifier(), first->getFormalAccess());
802+
803+
// FIXME: If any of the candidates (usually just one) are in the same module
804+
// we could offer a fix-it.
805+
for (auto lookupResult : inaccessibleMembers)
806+
tc.diagnose(lookupResult.first, diag::type_declared_here);
807+
808+
// Don't try to recover here; we'll get more access-related diagnostics
809+
// downstream if we do.
810+
return ErrorType::get(tc.Context);
811+
}
812+
788813
// FIXME: Typo correction!
789814

790815
// Lookup into a type.
@@ -986,7 +1011,7 @@ resolveTopLevelIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
9861011
return ErrorType::get(TC.Context);
9871012

9881013
return diagnoseUnknownType(TC, DC, nullptr, SourceRange(), comp, options,
989-
resolver, unsatisfiedDependency);
1014+
lookupOptions, resolver, unsatisfiedDependency);
9901015
}
9911016

9921017
comp->setValue(currentDecl);
@@ -1150,7 +1175,8 @@ static Type resolveNestedIdentTypeComponent(
11501175
}
11511176

11521177
Type ty = diagnoseUnknownType(TC, DC, parentTy, parentRange, comp, options,
1153-
resolver, unsatisfiedDependency);
1178+
lookupOptions, resolver,
1179+
unsatisfiedDependency);
11541180
if (!ty || ty->is<ErrorType>()) {
11551181
return ErrorType::get(TC.Context);
11561182
}

test/Sema/accessibility_private.swift

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ extension Container {
7171

7272
// FIXME: Why do these errors happen twice?
7373
var extensionInner: PrivateInner? { return nil } // FIXME expected-error 2 {{use of undeclared type 'PrivateInner'}}
74-
var extensionInnerQualified: Container.PrivateInner? { return nil } // FIXME expected-error 2 {{'PrivateInner' is not a member type of 'Container'}}
74+
var extensionInnerQualified: Container.PrivateInner? { return nil } // expected-error 2 {{'PrivateInner' is inaccessible due to 'private' protection level}}
7575
}
7676

7777
extension Container.Inner {
@@ -87,7 +87,7 @@ extension Container.Inner {
8787

8888
// FIXME: Why do these errors happen twice?
8989
var inner: PrivateInner? { return nil } // FIXME expected-error 2 {{use of undeclared type 'PrivateInner'}}
90-
var innerQualified: Container.PrivateInner? { return nil } // FIXME expected-error 2 {{'PrivateInner' is not a member type of 'Container'}}
90+
var innerQualified: Container.PrivateInner? { return nil } // expected-error 2 {{'PrivateInner' is inaccessible due to 'private' protection level}}
9191
}
9292

9393
class Sub : Container {
@@ -108,7 +108,7 @@ class Sub : Container {
108108
}
109109

110110
var subInner: PrivateInner? // FIXME expected-error {{use of undeclared type 'PrivateInner'}}
111-
var subInnerQualified: Container.PrivateInner? // FIXME expected-error {{'PrivateInner' is not a member type of 'Container'}}
111+
var subInnerQualified: Container.PrivateInner? // expected-error {{'PrivateInner' is inaccessible due to 'private' protection level}}
112112
}
113113

114114

@@ -145,3 +145,18 @@ private class VIPPrivateSetPropBase {
145145
private class VIPPrivateSetPropSub : VIPPrivateSetPropBase, VeryImportantProto {
146146
typealias Assoc = Int
147147
}
148+
149+
extension Container {
150+
private typealias ExtensionConflictingType = Int // expected-note * {{declared here}}
151+
}
152+
extension Container {
153+
private typealias ExtensionConflictingType = Double // expected-note * {{declared here}}
154+
}
155+
extension Container {
156+
func test() {
157+
let a: ExtensionConflictingType? = nil // FIXME expected-error {{use of undeclared type 'ExtensionConflictingType'}}
158+
let b: Container.ExtensionConflictingType? = nil // expected-error {{'ExtensionConflictingType' is inaccessible due to 'private' protection level}}
159+
_ = ExtensionConflictingType() // FIXME expected-error {{use of unresolved identifier 'ExtensionConflictingType'}}
160+
_ = Container.ExtensionConflictingType() // expected-error {{'ExtensionConflictingType' is inaccessible due to 'private' protection level}}
161+
}
162+
}

0 commit comments

Comments
 (0)