mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[CodeCompletion] Fix crash when completing inside a protocol that inherits from other protocol with extension
rdar://119408961
This commit is contained in:
@@ -30,35 +30,7 @@ bool CompletionOverrideLookup::addAccessControl(
|
||||
if (AccessOfContext < AccessLevel::Public)
|
||||
return false;
|
||||
|
||||
auto Access = VD->getFormalAccess();
|
||||
// Use the greater access between the protocol requirement and the witness.
|
||||
// In case of:
|
||||
//
|
||||
// public protocol P { func foo() }
|
||||
// public class B { func foo() {} }
|
||||
// public class C: B, P {
|
||||
// <complete>
|
||||
// }
|
||||
//
|
||||
// 'VD' is 'B.foo()' which is implicitly 'internal'. But as the overriding
|
||||
// declaration, the user needs to write both 'public' and 'override':
|
||||
//
|
||||
// public class C: B {
|
||||
// public override func foo() {}
|
||||
// }
|
||||
if (Access < AccessLevel::Public &&
|
||||
!isa<ProtocolDecl>(VD->getDeclContext())) {
|
||||
for (auto Conformance : CurrentNominal->getAllConformances()) {
|
||||
Conformance->getRootConformance()->forEachValueWitness(
|
||||
[&](ValueDecl *req, Witness witness) {
|
||||
if (witness.getDecl() == VD)
|
||||
Access = std::max(Access,
|
||||
Conformance->getProtocol()->getFormalAccess());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Access = std::min(Access, AccessOfContext);
|
||||
AccessLevel Access = std::min(VD->getFormalAccess(), AccessOfContext);
|
||||
// Only emit 'public', not needed otherwise.
|
||||
if (Access < AccessLevel::Public)
|
||||
return false;
|
||||
|
||||
13
test/IDE/complete_override_access_level.swift
Normal file
13
test/IDE/complete_override_access_level.swift
Normal file
@@ -0,0 +1,13 @@
|
||||
// RUN: %batch-code-completion
|
||||
|
||||
|
||||
// Use the greater access between the protocol requirement and the witness. In this test
|
||||
// case the completed declaration is 'B.foo()' which is implicitly 'internal'.
|
||||
// But as the overriding declaration, the user needs to write both 'public' and 'override'.
|
||||
public protocol P { func foo() }
|
||||
public class B { internal func foo() {} }
|
||||
public class C: B, P {
|
||||
#^COMPLETE^#
|
||||
// COMPLETE-DAG: Decl[InstanceMethod]/Super: public override func foo() {|}; name=foo()
|
||||
// COMPLETE-DAG: Decl[Constructor]/Super: override init() {|}; name=init()
|
||||
}
|
||||
16
validation-test/IDE/crashers_2_fixed/rdar119408961.swift
Normal file
16
validation-test/IDE/crashers_2_fixed/rdar119408961.swift
Normal file
@@ -0,0 +1,16 @@
|
||||
// RUN: %batch-code-completion
|
||||
|
||||
public protocol BaseProtocol {}
|
||||
|
||||
extension BaseProtocol {
|
||||
var indexInParent: Int {
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
public protocol InheritedProtocol: BaseProtocol {}
|
||||
|
||||
extension InheritedProtocol {
|
||||
#^COMPLETE^#
|
||||
// COMPLETE: Decl[InstanceVar]/Super: var indexInParent: Int; name=indexInParent
|
||||
}
|
||||
Reference in New Issue
Block a user