mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Default access for many synthesized members to 'internal'.
More detail: some members are intended to have the same the access as their containing types. This doesn't fly for SE-0025 'private', which would limit the members to only being accessed from lexically within the type decl, instead anywhere the type itself can be seen. Instead, follow the rule for user-written members---internal by default---and then raise the access level to 'public' if necessary. This affects: - enum cases - deinitializers - protocol requirements - generic parameters - implicit initializers - inherited initializers - derived conformance members - synthesized typealiases for associated types
This commit is contained in:
@@ -1917,9 +1917,9 @@ ConstructorDecl *swift::createImplicitConstructor(TypeChecker &tc,
|
||||
ImplicitConstructorKind ICK) {
|
||||
ASTContext &context = tc.Context;
|
||||
SourceLoc Loc = decl->getLoc();
|
||||
Accessibility accessLevel = decl->getFormalAccess();
|
||||
if (!decl->hasClangNode())
|
||||
accessLevel = std::min(accessLevel, Accessibility::Internal);
|
||||
auto accessLevel = Accessibility::Internal;
|
||||
if (decl->hasClangNode())
|
||||
accessLevel = std::max(accessLevel, decl->getFormalAccess());
|
||||
|
||||
// Determine the parameter type of the implicit constructor.
|
||||
SmallVector<ParamDecl*, 8> params;
|
||||
@@ -2114,8 +2114,11 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
|
||||
/*GenericParams=*/nullptr, classDecl);
|
||||
|
||||
ctor->setImplicit();
|
||||
ctor->setAccessibility(std::min(classDecl->getFormalAccess(),
|
||||
superclassCtor->getFormalAccess()));
|
||||
|
||||
Accessibility access = classDecl->getFormalAccess();
|
||||
access = std::max(access, Accessibility::Internal);
|
||||
access = std::min(access, superclassCtor->getFormalAccess());
|
||||
ctor->setAccessibility(access);
|
||||
|
||||
// Make sure the constructor is only as available as its superclass's
|
||||
// constructor.
|
||||
|
||||
@@ -417,7 +417,8 @@ deriveHashable_enum_hashValue(TypeChecker &tc, Decl *parentDecl,
|
||||
interfaceType = FunctionType::get(selfType, methodType);
|
||||
|
||||
getterDecl->setInterfaceType(interfaceType);
|
||||
getterDecl->setAccessibility(enumDecl->getFormalAccess());
|
||||
getterDecl->setAccessibility(std::max(Accessibility::Internal,
|
||||
enumDecl->getFormalAccess()));
|
||||
|
||||
// If the enum was not imported, the derived conformance is either from the
|
||||
// enum itself or an extension, in which case we will emit the declaration
|
||||
@@ -433,7 +434,7 @@ deriveHashable_enum_hashValue(TypeChecker &tc, Decl *parentDecl,
|
||||
hashValueDecl->setImplicit();
|
||||
hashValueDecl->makeComputed(SourceLoc(), getterDecl,
|
||||
nullptr, nullptr, SourceLoc());
|
||||
hashValueDecl->setAccessibility(enumDecl->getFormalAccess());
|
||||
hashValueDecl->setAccessibility(getterDecl->getFormalAccess());
|
||||
|
||||
Pattern *hashValuePat = new (C) NamedPattern(hashValueDecl, /*implicit*/true);
|
||||
hashValuePat->setType(intType);
|
||||
|
||||
@@ -336,7 +336,8 @@ static ConstructorDecl *deriveRawRepresentable_init(TypeChecker &tc,
|
||||
}
|
||||
initDecl->setInterfaceType(allocIfaceType);
|
||||
initDecl->setInitializerInterfaceType(initIfaceType);
|
||||
initDecl->setAccessibility(enumDecl->getFormalAccess());
|
||||
initDecl->setAccessibility(std::max(Accessibility::Internal,
|
||||
enumDecl->getFormalAccess()));
|
||||
|
||||
// If the enum was not imported, the derived conformance is either from the
|
||||
// enum itself or an extension, in which case we will emit the declaration
|
||||
|
||||
@@ -151,7 +151,8 @@ FuncDecl *DerivedConformance::declareDerivedPropertyGetter(TypeChecker &tc,
|
||||
} else
|
||||
interfaceType = type;
|
||||
getterDecl->setInterfaceType(interfaceType);
|
||||
getterDecl->setAccessibility(typeDecl->getFormalAccess());
|
||||
getterDecl->setAccessibility(std::max(typeDecl->getFormalAccess(),
|
||||
Accessibility::Internal));
|
||||
|
||||
// If the enum was not imported, the derived conformance is either from the
|
||||
// enum itself or an extension, in which case we will emit the declaration
|
||||
@@ -181,7 +182,7 @@ DerivedConformance::declareDerivedReadOnlyProperty(TypeChecker &tc,
|
||||
propDecl->setImplicit();
|
||||
propDecl->makeComputed(SourceLoc(), getterDecl, nullptr, nullptr,
|
||||
SourceLoc());
|
||||
propDecl->setAccessibility(typeDecl->getFormalAccess());
|
||||
propDecl->setAccessibility(getterDecl->getFormalAccess());
|
||||
propDecl->setInterfaceType(propertyInterfaceType);
|
||||
|
||||
Pattern *propPat = new (C) NamedPattern(propDecl, /*implicit*/ true);
|
||||
|
||||
@@ -1371,7 +1371,7 @@ void TypeChecker::computeAccessibility(ValueDecl *D) {
|
||||
validateAccessibility(generic);
|
||||
Accessibility access = Accessibility::Internal;
|
||||
if (isa<ProtocolDecl>(generic))
|
||||
access = generic->getFormalAccess();
|
||||
access = std::max(access, generic->getFormalAccess());
|
||||
D->setAccessibility(access);
|
||||
break;
|
||||
}
|
||||
@@ -3522,9 +3522,7 @@ public:
|
||||
assocType->setIsBeingTypeChecked();
|
||||
|
||||
TC.checkDeclAttributesEarly(assocType);
|
||||
if (!assocType->hasAccessibility())
|
||||
assocType->setAccessibility(assocType->getProtocol()->getFormalAccess());
|
||||
|
||||
TC.validateAccessibility(assocType);
|
||||
TC.checkInheritanceClause(assocType);
|
||||
|
||||
// Check the default definition, if there is one.
|
||||
@@ -5785,12 +5783,7 @@ public:
|
||||
|
||||
|
||||
TC.checkDeclAttributesEarly(EED);
|
||||
|
||||
EnumDecl *ED = EED->getParentEnum();
|
||||
|
||||
if (!EED->hasAccessibility())
|
||||
EED->setAccessibility(ED->getFormalAccess());
|
||||
|
||||
TC.validateAccessibility(EED);
|
||||
EED->setIsBeingTypeChecked();
|
||||
|
||||
// Only attempt to validate the argument type or raw value if the element
|
||||
@@ -5811,6 +5804,7 @@ public:
|
||||
|
||||
// If we have a raw value, make sure there's a raw type as well.
|
||||
if (auto *rawValue = EED->getRawValueExpr()) {
|
||||
EnumDecl *ED = EED->getParentEnum();
|
||||
if (!ED->hasRawType()) {
|
||||
TC.diagnose(rawValue->getLoc(),diag::enum_raw_value_without_raw_type);
|
||||
// Recover by setting the raw type as this element's type.
|
||||
@@ -6522,7 +6516,8 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
|
||||
if (!assocType->hasType())
|
||||
assocType->computeType();
|
||||
if (!typeParam->hasAccessibility())
|
||||
typeParam->setAccessibility(nominal->getFormalAccess());
|
||||
typeParam->setAccessibility(std::max(nominal->getFormalAccess(),
|
||||
Accessibility::Internal));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -6543,7 +6538,8 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
|
||||
if (!assocType->hasType())
|
||||
assocType->computeType();
|
||||
if (!typeParam->hasAccessibility())
|
||||
typeParam->setAccessibility(fn->getFormalAccess());
|
||||
typeParam->setAccessibility(std::max(fn->getFormalAccess(),
|
||||
Accessibility::Internal));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -6905,7 +6901,8 @@ void TypeChecker::validateAccessibility(ValueDecl *D) {
|
||||
auto assocType = cast<AssociatedTypeDecl>(D);
|
||||
auto prot = assocType->getProtocol();
|
||||
validateAccessibility(prot);
|
||||
assocType->setAccessibility(prot->getFormalAccess());
|
||||
assocType->setAccessibility(std::max(prot->getFormalAccess(),
|
||||
Accessibility::Internal));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -6928,7 +6925,8 @@ void TypeChecker::validateAccessibility(ValueDecl *D) {
|
||||
} else {
|
||||
auto container = cast<NominalTypeDecl>(D->getDeclContext());
|
||||
validateAccessibility(container);
|
||||
D->setAccessibility(container->getFormalAccess());
|
||||
D->setAccessibility(std::max(container->getFormalAccess(),
|
||||
Accessibility::Internal));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -801,6 +801,7 @@ void TypeChecker::finalizeGenericParamList(ArchetypeBuilder &builder,
|
||||
access = nominal->getFormalAccess();
|
||||
else
|
||||
access = Accessibility::Internal;
|
||||
access = std::max(access, Accessibility::Internal);
|
||||
|
||||
// Wire up the archetypes.
|
||||
for (auto GP : *genericParams) {
|
||||
|
||||
@@ -1960,7 +1960,14 @@ void ConformanceChecker::recordTypeWitness(AssociatedTypeDecl *assocType,
|
||||
// Inject the typealias into the nominal decl that conforms to the protocol.
|
||||
if (auto nominal = DC->getAsNominalTypeOrNominalTypeExtensionContext()) {
|
||||
TC.computeAccessibility(nominal);
|
||||
aliasDecl->setAccessibility(nominal->getFormalAccess());
|
||||
// FIXME: Ideally this would use the protocol's access too---that is,
|
||||
// a typealias added for an internal protocol shouldn't need to be
|
||||
// public---but that can be problematic if the same type conforms to two
|
||||
// protocols with different access levels.
|
||||
Accessibility aliasAccess = nominal->getFormalAccess();
|
||||
aliasAccess = std::max(aliasAccess, Accessibility::Internal);
|
||||
aliasDecl->setAccessibility(aliasAccess);
|
||||
|
||||
if (nominal == DC) {
|
||||
nominal->addMember(aliasDecl);
|
||||
} else {
|
||||
|
||||
@@ -3036,7 +3036,8 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
elem->setInterfaceType(interfaceType);
|
||||
if (isImplicit)
|
||||
elem->setImplicit();
|
||||
elem->setAccessibility(cast<EnumDecl>(DC)->getFormalAccess());
|
||||
elem->setAccessibility(std::max(cast<EnumDecl>(DC)->getFormalAccess(),
|
||||
Accessibility::Internal));
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -3203,7 +3204,8 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
/*selfpat*/nullptr, DC);
|
||||
declOrOffset = dtor;
|
||||
|
||||
dtor->setAccessibility(cast<ClassDecl>(DC)->getFormalAccess());
|
||||
dtor->setAccessibility(std::max(cast<ClassDecl>(DC)->getFormalAccess(),
|
||||
Accessibility::Internal));
|
||||
auto *selfParams = readParameterList();
|
||||
selfParams->get(0)->setImplicit(); // self is implicit.
|
||||
|
||||
|
||||
@@ -112,16 +112,16 @@ public class TestPublicABC : ProtocolAPrivate, ProtocolBInternal, ProtocolCPubli
|
||||
|
||||
// TEST_INTERNAL_ABC: Begin completions, 15 items
|
||||
// TEST_INTERNAL_ABC-DAG: Decl[Constructor]/Super: init(fromProtocolA: TagPA) {|}{{; name=.+$}}
|
||||
// TEST_INTERNAL_ABC-DAG: Decl[InstanceMethod]/Super: private func protoAFunc(x: TagPA) {|}{{; name=.+$}}
|
||||
// TEST_INTERNAL_ABC-DAG: Decl[InstanceMethod]/Super: private func protoAFuncOptional(x: TagPA) {|}{{; name=.+$}}
|
||||
// TEST_INTERNAL_ABC-DAG: Decl[InstanceMethod]/Super: func protoAFunc(x: TagPA) {|}{{; name=.+$}}
|
||||
// TEST_INTERNAL_ABC-DAG: Decl[InstanceMethod]/Super: func protoAFuncOptional(x: TagPA) {|}{{; name=.+$}}
|
||||
// TEST_INTERNAL_ABC-DAG: Decl[Constructor]/Super: init(fromProtocolB: TagPB) {|}{{; name=.+$}}
|
||||
// TEST_INTERNAL_ABC-DAG: Decl[InstanceMethod]/Super: func protoBFunc(x: TagPB) {|}{{; name=.+$}}
|
||||
// TEST_INTERNAL_ABC-DAG: Decl[InstanceMethod]/Super: func protoBFuncOptional(x: TagPB) {|}{{; name=.+$}}
|
||||
// TEST_INTERNAL_ABC-DAG: Decl[Constructor]/Super: init(fromProtocolC: TagPC) {|}{{; name=.+$}}
|
||||
// TEST_INTERNAL_ABC-DAG: Decl[InstanceMethod]/Super: func protoCFunc(x: TagPC) {|}{{; name=.+$}}
|
||||
// TEST_INTERNAL_ABC-DAG: Decl[InstanceMethod]/Super: func protoCFuncOptional(x: TagPC) {|}{{; name=.+$}}
|
||||
// TEST_INTERNAL_ABC-DAG: Decl[InstanceVar]/Super: private var protoAVarRW: TagPA
|
||||
// TEST_INTERNAL_ABC-DAG: Decl[InstanceVar]/Super: private var protoAVarRO: TagPA
|
||||
// TEST_INTERNAL_ABC-DAG: Decl[InstanceVar]/Super: var protoAVarRW: TagPA
|
||||
// TEST_INTERNAL_ABC-DAG: Decl[InstanceVar]/Super: var protoAVarRO: TagPA
|
||||
// TEST_INTERNAL_ABC-DAG: Decl[InstanceVar]/Super: var protoBVarRW: TagPB
|
||||
// TEST_INTERNAL_ABC-DAG: Decl[InstanceVar]/Super: var protoBVarRO: TagPB
|
||||
// TEST_INTERNAL_ABC-DAG: Decl[InstanceVar]/Super: var protoCVarRW: TagPC
|
||||
@@ -130,16 +130,16 @@ public class TestPublicABC : ProtocolAPrivate, ProtocolBInternal, ProtocolCPubli
|
||||
|
||||
// TEST_PUBLIC_ABC: Begin completions, 15 items
|
||||
// TEST_PUBLIC_ABC-DAG: Decl[Constructor]/Super: init(fromProtocolA: TagPA) {|}{{; name=.+$}}
|
||||
// TEST_PUBLIC_ABC-DAG: Decl[InstanceMethod]/Super: private func protoAFunc(x: TagPA) {|}{{; name=.+$}}
|
||||
// TEST_PUBLIC_ABC-DAG: Decl[InstanceMethod]/Super: private func protoAFuncOptional(x: TagPA) {|}{{; name=.+$}}
|
||||
// TEST_PUBLIC_ABC-DAG: Decl[InstanceMethod]/Super: func protoAFunc(x: TagPA) {|}{{; name=.+$}}
|
||||
// TEST_PUBLIC_ABC-DAG: Decl[InstanceMethod]/Super: func protoAFuncOptional(x: TagPA) {|}{{; name=.+$}}
|
||||
// TEST_PUBLIC_ABC-DAG: Decl[Constructor]/Super: init(fromProtocolB: TagPB) {|}{{; name=.+$}}
|
||||
// TEST_PUBLIC_ABC-DAG: Decl[InstanceMethod]/Super: func protoBFunc(x: TagPB) {|}{{; name=.+$}}
|
||||
// TEST_PUBLIC_ABC-DAG: Decl[InstanceMethod]/Super: func protoBFuncOptional(x: TagPB) {|}{{; name=.+$}}
|
||||
// TEST_PUBLIC_ABC-DAG: Decl[Constructor]/Super: init(fromProtocolC: TagPC) {|}{{; name=.+$}}
|
||||
// TEST_PUBLIC_ABC-DAG: Decl[InstanceMethod]/Super: public func protoCFunc(x: TagPC) {|}{{; name=.+$}}
|
||||
// TEST_PUBLIC_ABC-DAG: Decl[InstanceMethod]/Super: public func protoCFuncOptional(x: TagPC) {|}{{; name=.+$}}
|
||||
// TEST_PUBLIC_ABC-DAG: Decl[InstanceVar]/Super: private var protoAVarRW: TagPA
|
||||
// TEST_PUBLIC_ABC-DAG: Decl[InstanceVar]/Super: private var protoAVarRO: TagPA
|
||||
// TEST_PUBLIC_ABC-DAG: Decl[InstanceVar]/Super: var protoAVarRW: TagPA
|
||||
// TEST_PUBLIC_ABC-DAG: Decl[InstanceVar]/Super: var protoAVarRO: TagPA
|
||||
// TEST_PUBLIC_ABC-DAG: Decl[InstanceVar]/Super: var protoBVarRW: TagPB
|
||||
// TEST_PUBLIC_ABC-DAG: Decl[InstanceVar]/Super: var protoBVarRO: TagPB
|
||||
// TEST_PUBLIC_ABC-DAG: Decl[InstanceVar]/Super: public var protoCVarRW: TagPC
|
||||
|
||||
@@ -29,8 +29,8 @@ struct BA_DefaultStruct {
|
||||
private struct BB_PrivateStruct {
|
||||
// CHECK: internal var x
|
||||
var x = 0
|
||||
// CHECK: private init(x: Int)
|
||||
// CHECK: private init()
|
||||
// CHECK: internal init(x: Int)
|
||||
// CHECK: internal init()
|
||||
} // CHECK: {{^[}]}}
|
||||
|
||||
// CHECK-LABEL: internal{{(\*/)?}} struct BC_InternalStruct {
|
||||
@@ -60,8 +60,8 @@ public struct BE_PublicStructPrivateMembers {
|
||||
fileprivate struct BF_FilePrivateStruct {
|
||||
// CHECK: {{^}} internal var x
|
||||
var x = 0
|
||||
// CHECK: {{^}} fileprivate init(x: Int)
|
||||
// CHECK: {{^}} fileprivate init()
|
||||
// CHECK: {{^}} internal init(x: Int)
|
||||
// CHECK: {{^}} internal init()
|
||||
} // CHECK: {{^[}]}}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ fileprivate struct BF_FilePrivateStruct {
|
||||
private class CA_PrivateClass {
|
||||
// CHECK: {{^}} deinit
|
||||
deinit {}
|
||||
// CHECK: private init()
|
||||
// CHECK: internal init()
|
||||
} // CHECK: {{^[}]}}
|
||||
|
||||
// CHECK-LABEL: internal{{(\*/)?}} class CB_InternalClass
|
||||
@@ -94,7 +94,7 @@ private enum DA_PrivateEnum {
|
||||
case Foo, Bar
|
||||
// CHECK: internal init()
|
||||
init() { self = .Foo }
|
||||
// CHECK: private var hashValue
|
||||
// CHECK: internal var hashValue
|
||||
} // CHECK: {{^[}]}}
|
||||
|
||||
// CHECK-LABEL: internal{{(\*/)?}} enum DB_InternalEnum {
|
||||
@@ -122,9 +122,9 @@ public enum DC_PublicEnum {
|
||||
private protocol EA_PrivateProtocol {
|
||||
// CHECK: {{^}} associatedtype Foo
|
||||
associatedtype Foo
|
||||
// CHECK: private var Bar
|
||||
// CHECK: internal var Bar
|
||||
var Bar: Int { get }
|
||||
// CHECK: private func baz()
|
||||
// CHECK: internal func baz()
|
||||
func baz()
|
||||
} // CHECK: {{^[}]}}
|
||||
|
||||
@@ -325,19 +325,52 @@ extension HC_PrivateProtocol where Assoc == HC_PrivateStruct {
|
||||
func constrained() {}
|
||||
} // CHECK: {{^[}]}}
|
||||
|
||||
public protocol IA_PublicAssocTypeProto {
|
||||
associatedtype PublicValue
|
||||
var publicValue: PublicValue { get }
|
||||
}
|
||||
fileprivate protocol IB_FilePrivateAssocTypeProto {
|
||||
associatedtype FilePrivateValue
|
||||
var filePrivateValue: FilePrivateValue { get }
|
||||
}
|
||||
// CHECK-LABEL: public{{(\*/)?}} class IC_PublicAssocTypeImpl : IA_PublicAssocTypeProto, IB_FilePrivateAssocTypeProto {
|
||||
public class IC_PublicAssocTypeImpl: IA_PublicAssocTypeProto, IB_FilePrivateAssocTypeProto {
|
||||
public var publicValue: Int = 0
|
||||
public var filePrivateValue: Int = 0
|
||||
// CHECK-DAG: {{^}} public typealias PublicValue
|
||||
// CHECK-DAG: {{^}} public typealias FilePrivateValue
|
||||
} // CHECK: {{^[}]}}
|
||||
|
||||
// CHECK-LABEL: private{{(\*/)?}} class ID_PrivateAssocTypeImpl : IA_PublicAssocTypeProto, IB_FilePrivateAssocTypeProto {
|
||||
private class ID_PrivateAssocTypeImpl: IA_PublicAssocTypeProto, IB_FilePrivateAssocTypeProto {
|
||||
public var publicValue: Int = 0
|
||||
public var filePrivateValue: Int = 0
|
||||
// CHECK-DAG: {{^}} internal typealias PublicValue
|
||||
// CHECK-DAG: {{^}} internal typealias FilePrivateValue
|
||||
} // CHECK: {{^[}]}}
|
||||
|
||||
// CHECK-LABEL: class MultipleAttributes {
|
||||
class MultipleAttributes {
|
||||
// CHECK: {{^}} final {{(/\*)?private(\*/)?}} func foo()
|
||||
final private func foo() {}
|
||||
}
|
||||
} // CHECK: {{^[}]}}
|
||||
|
||||
// CHECK-LABEL: public{{(\*/)?}} class PublicInitBase {
|
||||
public class PublicInitBase {
|
||||
// CHECK: {{^}} {{(/\*)?public(\*/)?}} init()
|
||||
public init() {}
|
||||
}
|
||||
// CHECK: {{^}} {{(/\*)?fileprivate(\*/)?}} init(other: PublicInitBase)
|
||||
fileprivate init(other: PublicInitBase) {}
|
||||
} // CHECK: {{^[}]}}
|
||||
|
||||
// CHECK-LABEL: public{{(\*/)?}} class PublicInitInheritor : PublicInitBase {
|
||||
public class PublicInitInheritor : PublicInitBase {
|
||||
// CHECK: {{^}} public init()
|
||||
}
|
||||
// CHECK: {{^}} fileprivate init(other: PublicInitBase)
|
||||
} // CHECK: {{^[}]}}
|
||||
|
||||
// CHECK-LABEL: {{(/\*)?private(\*/)?}} class PublicInitPrivateInheritor : PublicInitBase {
|
||||
private class PublicInitPrivateInheritor : PublicInitBase {
|
||||
// CHECK: {{^}} internal init()
|
||||
// CHECK: {{^}} fileprivate init(other: PublicInitBase)
|
||||
} // CHECK: {{^[}]}}
|
||||
|
||||
Reference in New Issue
Block a user