Revert "Handle package exportability."

This reverts commit d182d01c28.
This commit is contained in:
Xi Ge
2024-06-11 11:54:00 -07:00
parent 7ccd2adfb2
commit 6f5b40543d
17 changed files with 176 additions and 606 deletions

View File

@@ -2301,32 +2301,32 @@ ERROR(pattern_type_not_usable_from_inline,none,
"type referenced from a '@usableFromInline' "
"%select{%select{variable|constant}0|property}1 "
"must be '@usableFromInline' or public",
(bool, bool, /*ignored*/bool))
(bool, bool))
WARNING(pattern_type_not_usable_from_inline_warn,none,
"type referenced from a '@usableFromInline' "
"%select{%select{variable|constant}0|property}1 "
"should be '@usableFromInline' or public",
(bool, bool, /*ignored*/bool))
(bool, bool))
ERROR(pattern_type_not_usable_from_inline_frozen,none,
"type referenced from a stored property in a '@frozen%select{| package}2' struct must "
"be '@usableFromInline'%select{ or public|, public, or package}2",
(/*ignored*/bool, /*ignored*/bool, bool))
"type referenced from a stored property in a '@frozen' struct must "
"be '@usableFromInline' or public",
(/*ignored*/bool, /*ignored*/bool))
ERROR(pattern_type_not_usable_from_inline_inferred,none,
"type referenced from a '@usableFromInline' "
"%select{%select{variable|constant}0|property}1 "
"with inferred type %2 "
"must be '@usableFromInline' or public",
(bool, bool, Type, /*ignored*/bool))
(bool, bool, Type))
WARNING(pattern_type_not_usable_from_inline_inferred_warn,none,
"type referenced from a '@usableFromInline' "
"%select{%select{variable|constant}0|property}1 "
"with inferred type %2 "
"should be '@usableFromInline' or public",
(bool, bool, Type, /*ignored*/bool))
(bool, bool, Type))
ERROR(pattern_type_not_usable_from_inline_inferred_frozen,none,
"type referenced from a stored property with inferred type %2 in a "
"'@frozen%select{| package}3' struct must be '@usableFromInline'%select{ or public|, public, or package}3",
(/*ignored*/bool, /*ignored*/bool, Type, bool))
"'@frozen' struct must be '@usableFromInline' or public",
(/*ignored*/bool, /*ignored*/bool, Type))
ERROR(pattern_binds_no_variables,none,
"%select{property|global variable}0 declaration does not bind any "
@@ -3648,8 +3648,6 @@ ERROR(decl_from_hidden_module,none,
"cannot use %kind0 %select{here|as property wrapper here|"
"as result builder here|"
"in an extension with public or '@usableFromInline' members|"
"in an extension with conditional conformances|"
"in an extension with public, package, or '@usableFromInline' members|"
"in an extension with conditional conformances}1; "
"%select{%2 has been imported as implementation-only|"
"it is an SPI imported from %2|"
@@ -3657,9 +3655,7 @@ ERROR(decl_from_hidden_module,none,
"%2 was imported for SPI only|"
"%2 was not imported by this file|"
"C++ types from imported module %2 do not support library evolution|"
"%2 was not imported publicly|"
"%2 was imported as package}3"
"%select{||||| or as package| or as package}1",
"%2 was not imported publicly}3",
(const Decl *, unsigned, Identifier, unsigned))
ERROR(typealias_desugars_to_type_from_hidden_module,none,
"%0 aliases '%1.%2' and cannot be used %select{here|"
@@ -3675,8 +3671,7 @@ ERROR(typealias_desugars_to_type_from_hidden_module,none,
"%4 was imported for SPI only|"
"%4 was not imported by this file|"
"C++ types from imported module %4 do not support library evolution|"
"%4 was not imported publicly|"
"%4 was imported as package}5",
"%4 was not imported publicly}5",
(const TypeAliasDecl *, StringRef, StringRef, unsigned, Identifier, unsigned))
ERROR(conformance_from_implementation_only_module,none,
"cannot use conformance of %0 to %1 %select{here|as property wrapper here|"
@@ -3689,8 +3684,7 @@ ERROR(conformance_from_implementation_only_module,none,
"%3 was imported for SPI only|"
"%3 was not imported by this file|"
"C++ types from imported module %3 do not support library evolution|"
"%3 was not imported publicly|"
"%3 was imported as package}4",
"%3 was not imported publicly}4",
(Type, Identifier, unsigned, Identifier, unsigned))
NOTE(assoc_conformance_from_implementation_only_module,none,
"in associated type %0 (inferred as %1)", (Type, Type))
@@ -6928,8 +6922,7 @@ ERROR(inlinable_decl_ref_from_hidden_module,
"%2 was imported for SPI only|"
"%2 was not imported by this file|"
"C++ APIs from imported module %2 do not support library evolution|"
"%2 was not imported publicly|"
"%2 was imported as package}3",
"%2 was not imported publicly}3",
(const ValueDecl *, unsigned, Identifier, unsigned))
WARNING(inlinable_decl_ref_from_hidden_module_warn,
@@ -6947,8 +6940,7 @@ ERROR(inlinable_typealias_desugars_to_type_from_hidden_module,
"%4 was imported for SPI only|"
"%4 was not imported by this file|"
"C++ types from imported module %4 do not support library evolution|"
"%4 was not imported publicly|"
"%4 was imported as package}5",
"%4 was not imported publicly}5",
(const TypeAliasDecl *, StringRef, StringRef, unsigned, Identifier, unsigned))
NOTE(missing_import_inserted,
@@ -6962,8 +6954,8 @@ ERROR(availability_macro_in_inlinable, none,
#undef FRAGILE_FUNC_KIND
NOTE(resilience_decl_declared_here,
none, "%kind0 is not '@usableFromInline'%select{ or public|, public, or package}1",
(const ValueDecl *, bool))
none, "%kind0 is not '@usableFromInline' or public",
(const ValueDecl *))
ERROR(class_designated_init_inlinable_resilient,none,
"initializer for class %0 is "

View File

@@ -435,10 +435,6 @@ public:
void setImportUsedPreconcurrency(
AttributedImport<ImportedModule> import);
/// True if the highest access level of the declarations referencing
/// this import in signature or inlinable code is internal or less.
bool isMaxAccessLevelUsingImportInternal(AttributedImport<ImportedModule> import) const;
/// Return the highest access level of the declarations referencing
/// this import in signature or inlinable code.
AccessLevel

View File

@@ -2314,7 +2314,7 @@ bool VarDecl::isLayoutExposedToClients() const {
auto nominalAccess =
parent->getFormalAccessScope(/*useDC=*/nullptr,
/*treatUsableFromInlineAsPublic=*/true);
if (!nominalAccess.isPublicOrPackage()) return false;
if (!nominalAccess.isPublic()) return false;
if (!parent->getAttrs().hasAttribute<FrozenAttr>() &&
!parent->getAttrs().hasAttribute<FixedLayoutAttr>())
@@ -4680,10 +4680,8 @@ bool ValueDecl::isMoreVisibleThan(ValueDecl *other) const {
if (scope.isPublic())
return !otherScope.isPublic();
else if (scope.isPackage())
return !otherScope.isPublicOrPackage();
else if (scope.isInternal())
return !otherScope.isPublicOrPackage() && !otherScope.isInternal();
return !otherScope.isPublic() && !otherScope.isInternal();
else
return false;
}

View File

@@ -486,7 +486,7 @@ swift::FragileFunctionKindRequest::evaluate(Evaluator &evaluator,
auto effectiveAccess =
VD->getFormalAccessScope(/*useDC=*/nullptr,
/*treatUsableFromInlineAsPublic=*/true);
if (effectiveAccess.isPublicOrPackage()) {
if (effectiveAccess.isPublic()) {
return {FragileFunctionKind::DefaultArgument};
}
@@ -518,7 +518,7 @@ swift::FragileFunctionKindRequest::evaluate(Evaluator &evaluator,
// If the function is not externally visible, we will not be serializing
// its body.
if (!funcAccess.isPublicOrPackage()) {
if (!funcAccess.isPublic()) {
return {FragileFunctionKind::None};
}

View File

@@ -2650,12 +2650,6 @@ void SourceFile::setImportUsedPreconcurrency(
PreconcurrencyImportsUsed.insert(import);
}
bool SourceFile::isMaxAccessLevelUsingImportInternal(
AttributedImport<ImportedModule> import) const {
auto maxLevel = getMaxAccessLevelUsingImport(import.module.importedModule);
return maxLevel < AccessLevel::Package;
}
AccessLevel
SourceFile::getMaxAccessLevelUsingImport(
const ModuleDecl *mod) const {

View File

@@ -66,22 +66,17 @@ bool TypeChecker::diagnoseInlinableDeclRefAccess(SourceLoc loc,
ImportAccessLevel problematicImport = D->getImportAccessFrom(DC);
if (problematicImport.has_value()) {
auto SF = DC->getParentSourceFile();
if (SF) {
// The max used access level previously registered might be Package,
// in which case, don't reset it to Public here; this ensures proper
// diags between public and package.
if (SF->isMaxAccessLevelUsingImportInternal(problematicImport.value()))
SF->registerAccessLevelUsingImport(problematicImport.value(),
AccessLevel::Public);
if (SF)
SF->registerAccessLevelUsingImport(problematicImport.value(),
AccessLevel::Public);
if (Context.LangOpts.EnableModuleApiImportRemarks) {
ModuleDecl *importedVia = problematicImport->module.importedModule,
*sourceModule = D->getModuleContext();
Context.Diags.diagnose(loc, diag::module_api_import,
D, importedVia, sourceModule,
importedVia == sourceModule,
/*isImplicit*/false);
}
if (Context.LangOpts.EnableModuleApiImportRemarks) {
ModuleDecl *importedVia = problematicImport->module.importedModule,
*sourceModule = D->getModuleContext();
Context.Diags.diagnose(loc, diag::module_api_import,
D, importedVia, sourceModule,
importedVia == sourceModule,
/*isImplicit*/false);
}
}
@@ -124,27 +119,15 @@ bool TypeChecker::diagnoseInlinableDeclRefAccess(SourceLoc loc,
if (isa<TypeAliasDecl>(DC) && !Context.isSwiftVersionAtLeast(6))
downgradeToWarning = DowngradeToWarning::Yes;
auto diagID = diag::resilience_decl_unavailable;
if (downgradeToWarning == DowngradeToWarning::Yes)
diagID = diag::resilience_decl_unavailable_warn;
AccessLevel diagAccessLevel = declAccessScope.accessLevelForDiagnostics();
Context.Diags.diagnose(loc, diagID, D, diagAccessLevel,
fragileKind.getSelector());
auto allowedForPkgCtx = false;
auto originKind = getDisallowedOriginKind(D, where, downgradeToWarning);
// For a default argument or property initializer, package type is
// allowed at the use site with package access scope.
if (originKind == DisallowedOriginKind::None ||
originKind == DisallowedOriginKind::PackageImport) {
allowedForPkgCtx = where.isPackage() && diagAccessLevel >= AccessLevel::Package;
}
if (!allowedForPkgCtx) {
auto diagID = diag::resilience_decl_unavailable;
if (downgradeToWarning == DowngradeToWarning::Yes)
diagID = diag::resilience_decl_unavailable_warn;
Context.Diags.diagnose(loc, diagID, D, diagAccessLevel,
fragileKind.getSelector());
Context.Diags.diagnose(D, diag::resilience_decl_declared_here, D, allowedForPkgCtx);
}
Context.Diags.diagnose(D, diag::resilience_decl_declared_here, D);
if (problematicImport.has_value() &&
problematicImport->accessLevel < D->getFormalAccess()) {
@@ -173,14 +156,10 @@ static bool diagnoseTypeAliasDeclRefExportability(SourceLoc loc,
where.getDeclContext());
if (problematicImport.has_value()) {
auto SF = where.getDeclContext()->getParentSourceFile();
if (SF) {
// The max used access level previously registered might be Package,
// in which case, don't reset it to Public here; this ensures proper
// diags between public and package.
if (SF->isMaxAccessLevelUsingImportInternal(problematicImport.value()))
SF->registerAccessLevelUsingImport(problematicImport.value(),
AccessLevel::Public);
}
if (SF)
SF->registerAccessLevelUsingImport(problematicImport.value(),
AccessLevel::Public);
if (ctx.LangOpts.EnableModuleApiImportRemarks) {
ModuleDecl *importedVia = problematicImport->module.importedModule,
*sourceModule = D->getModuleContext();
@@ -207,8 +186,7 @@ static bool diagnoseTypeAliasDeclRefExportability(SourceLoc loc,
auto definingModule = D->getModuleContext();
auto fragileKind = where.getFragileFunctionKind();
bool warnPreSwift6 = originKind != DisallowedOriginKind::SPIOnly &&
originKind != DisallowedOriginKind::PackageImport &&
originKind != DisallowedOriginKind::InternalOrLessImport;
originKind != DisallowedOriginKind::NonPublicImport;
if (fragileKind.kind == FragileFunctionKind::None) {
auto reason = where.getExportabilityReason();
ctx.Diags
@@ -233,8 +211,7 @@ static bool diagnoseTypeAliasDeclRefExportability(SourceLoc loc,
addMissingImport(loc, D, where);
// If limited by an import, note which one.
if (originKind == DisallowedOriginKind::InternalOrLessImport ||
originKind == DisallowedOriginKind::PackageImport) {
if (originKind == DisallowedOriginKind::NonPublicImport) {
const DeclContext *DC = where.getDeclContext();
ImportAccessLevel limitImport = D->getImportAccessFrom(DC);
assert(limitImport.has_value() &&
@@ -265,31 +242,22 @@ static bool diagnoseValueDeclRefExportability(SourceLoc loc, const ValueDecl *D,
ImportAccessLevel import = D->getImportAccessFrom(DC);
if (import.has_value() && reason.has_value()) {
auto SF = DC->getParentSourceFile();
if (SF) {
// The max used access level previously registered might be Package,
// in which case, don't reset it to Public here; this ensures proper
// diags between public and package.
if (SF->isMaxAccessLevelUsingImportInternal(import.value()))
SF->registerAccessLevelUsingImport(import.value(),
AccessLevel::Public);
}
if (SF)
SF->registerAccessLevelUsingImport(import.value(),
AccessLevel::Public);
}
// Access levels from imports are reported with the others access levels.
// Except for extensions, we report them here.
if (originKind == DisallowedOriginKind::InternalOrLessImport ||
originKind == DisallowedOriginKind::PackageImport) {
if (reason != ExportabilityReason::ExtensionWithPublicMembers &&
reason != ExportabilityReason::ExtensionWithPackageMembers &&
reason != ExportabilityReason::ExtensionWithConditionalConformances &&
reason != ExportabilityReason::ExtensionWithPackageConditionalConformances)
return false;
}
if (originKind == DisallowedOriginKind::NonPublicImport &&
reason != ExportabilityReason::ExtensionWithPublicMembers &&
reason != ExportabilityReason::ExtensionWithConditionalConformances)
return false;
if (ctx.LangOpts.EnableModuleApiImportRemarks &&
import.has_value() && where.isExported() &&
reason != ExportabilityReason::General &&
originKind != DisallowedOriginKind::InternalOrLessImport) {
originKind != DisallowedOriginKind::NonPublicImport) {
// These may be reported twice, for the Type and for the TypeRepr.
ModuleDecl *importedVia = import->module.importedModule,
*sourceModule = D->getModuleContext();
@@ -302,14 +270,6 @@ static bool diagnoseValueDeclRefExportability(SourceLoc loc, const ValueDecl *D,
if (originKind == DisallowedOriginKind::None)
return false;
// No diags needed for extensions with package members or
// conformance to types with package access scope.
if (originKind == DisallowedOriginKind::PackageImport) {
if (reason == ExportabilityReason::ExtensionWithPackageMembers ||
reason == ExportabilityReason::ExtensionWithPackageConditionalConformances)
return false;
}
auto diagName = D->getName();
if (auto accessor = dyn_cast<AccessorDecl>(D)) {
// Only diagnose accessors if their disallowed origin kind differs from
@@ -353,8 +313,7 @@ static bool diagnoseValueDeclRefExportability(SourceLoc loc, const ValueDecl *D,
}
// If limited by an import, note which one.
if (originKind == DisallowedOriginKind::InternalOrLessImport ||
originKind == DisallowedOriginKind::PackageImport) {
if (originKind == DisallowedOriginKind::NonPublicImport) {
assert(import.has_value() &&
import->accessLevel < AccessLevel::Public &&
"The import should still be non-public");
@@ -403,14 +362,10 @@ TypeChecker::diagnoseConformanceExportability(SourceLoc loc,
ImportAccessLevel problematicImport = ext->getImportAccessFrom(where.getDeclContext());
if (problematicImport.has_value()) {
auto SF = where.getDeclContext()->getParentSourceFile();
if (SF) {
// The max used access level previously registered might be Package,
// in which case, don't reset it to Public here; this ensures proper
// diags between public and package.
if (SF->isMaxAccessLevelUsingImportInternal(problematicImport.value()))
SF->registerAccessLevelUsingImport(problematicImport.value(),
AccessLevel::Public);
}
if (SF)
SF->registerAccessLevelUsingImport(problematicImport.value(),
AccessLevel::Public);
if (ctx.LangOpts.EnableModuleApiImportRemarks) {
ModuleDecl *importedVia = problematicImport->module.importedModule,
*sourceModule = ext->getModuleContext();
@@ -437,8 +392,7 @@ TypeChecker::diagnoseConformanceExportability(SourceLoc loc,
static_cast<unsigned>(originKind))
.warnUntilSwiftVersionIf((warnIfConformanceUnavailablePreSwift6 &&
originKind != DisallowedOriginKind::SPIOnly &&
originKind != DisallowedOriginKind::PackageImport &&
originKind != DisallowedOriginKind::InternalOrLessImport) ||
originKind != DisallowedOriginKind::NonPublicImport) ||
originKind == DisallowedOriginKind::MissingImport,
6);
@@ -447,8 +401,7 @@ TypeChecker::diagnoseConformanceExportability(SourceLoc loc,
addMissingImport(loc, ext, where);
// If limited by an import, note which one.
if (originKind == DisallowedOriginKind::InternalOrLessImport ||
originKind == DisallowedOriginKind::PackageImport) {
if (originKind == DisallowedOriginKind::NonPublicImport) {
const DeclContext *DC = where.getDeclContext();
ImportAccessLevel limitImport = ext->getImportAccessFrom(DC);
assert(limitImport.has_value() &&

View File

@@ -1424,16 +1424,13 @@ public:
ImportAccessLevel importLimit) {
auto &Ctx = theVar->getASTContext();
auto diagID = diag::pattern_type_not_usable_from_inline_inferred;
auto hasPackageScope = false;
if (fixedLayoutStructContext) {
diagID = diag::pattern_type_not_usable_from_inline_inferred_frozen;
hasPackageScope = fixedLayoutStructContext->getFormalAccessScope(nullptr, true).isPackage();
} else if (!Ctx.isSwiftVersionAtLeast(5)) {
diagID = diag::pattern_type_not_usable_from_inline_inferred_warn;
}
Ctx.Diags.diagnose(NP->getLoc(), diagID, theVar->isLet(),
isTypeContext, theVar->getInterfaceType(),
hasPackageScope);
isTypeContext, theVar->getInterfaceType());
noteLimitingImport(theVar, importLimit, complainRepr);
});
}
@@ -1466,14 +1463,12 @@ public:
ImportAccessLevel importLimit) {
auto &Ctx = anyVar->getASTContext();
auto diagID = diag::pattern_type_not_usable_from_inline;
auto hasPackageScope = false;
if (fixedLayoutStructContext) {
if (fixedLayoutStructContext)
diagID = diag::pattern_type_not_usable_from_inline_frozen;
hasPackageScope = fixedLayoutStructContext->getFormalAccessScope(nullptr, true).isPackage();
} else if (!Ctx.isSwiftVersionAtLeast(5))
else if (!Ctx.isSwiftVersionAtLeast(5))
diagID = diag::pattern_type_not_usable_from_inline_warn;
auto diag = Ctx.Diags.diagnose(TP->getLoc(), diagID, anyVar->isLet(),
isTypeContext, hasPackageScope);
isTypeContext);
highlightOffendingType(diag, complainRepr);
noteLimitingImport(anyVar, importLimit, complainRepr);
});
@@ -2016,20 +2011,9 @@ swift::getDisallowedOriginKind(const Decl *decl,
// Report non-public import last as it can be ignored by the caller.
// See \c diagnoseValueDeclRefExportability.
auto importSource = decl->getImportAccessFrom(where.getDeclContext());
if (importSource.has_value()) {
if (importSource->accessLevel == AccessLevel::Package) {
auto kind = where.getFragileFunctionKind().kind;
if (where.isPackage() &&
(kind == FragileFunctionKind::None ||
kind == FragileFunctionKind::DefaultArgument ||
kind == FragileFunctionKind::PropertyInitializer))
return DisallowedOriginKind::None;
return DisallowedOriginKind::PackageImport;
}
if (importSource->accessLevel < AccessLevel::Package)
return DisallowedOriginKind::InternalOrLessImport;
}
if (importSource.has_value() &&
importSource->accessLevel < AccessLevel::Public)
return DisallowedOriginKind::NonPublicImport;
return DisallowedOriginKind::None;
}
@@ -2352,19 +2336,13 @@ public:
}
void checkConstrainedExtensionRequirements(ExtensionDecl *ED,
bool hasExportedPublicMembers,
bool hasExportedPackageMembers,
bool hasPackageInheritance) {
bool hasExportedMembers) {
if (!ED->getTrailingWhereClause())
return;
ExportabilityReason reason = ExportabilityReason::ExtensionWithConditionalConformances;
if (hasExportedPublicMembers)
reason = ExportabilityReason::ExtensionWithPublicMembers;
else if (hasExportedPackageMembers)
reason = ExportabilityReason::ExtensionWithPackageMembers;
else if (hasPackageInheritance)
reason = ExportabilityReason::ExtensionWithPackageConditionalConformances;
ExportabilityReason reason =
hasExportedMembers ? ExportabilityReason::ExtensionWithPublicMembers
: ExportabilityReason::ExtensionWithConditionalConformances;
forAllRequirementTypes(ED, [&](Type type, TypeRepr *typeRepr) {
checkType(type, typeRepr, ED, reason);
@@ -2391,61 +2369,23 @@ public:
// 2) If the extension contains exported members, the as-written
// extended type should be exportable.
bool hasExportedPublicMembers = llvm::any_of(ED->getMembers(),
bool hasExportedMembers = llvm::any_of(ED->getMembers(),
[](const Decl *member) -> bool {
auto *valueMember = dyn_cast<ValueDecl>(member);
if (!valueMember)
return false;
return isExported(valueMember) &&
!valueMember->getFormalAccessScope(nullptr, true).isPackage();
});
// Keep track of package (exported) members separately from public
// members for diags purposes.
bool hasExportedPackageMembers = llvm::any_of(ED->getMembers(),
[](const Decl *member) -> bool {
auto *valueMember = dyn_cast<ValueDecl>(member);
if (!valueMember)
return false;
return isExported(valueMember) &&
valueMember->getFormalAccessScope(nullptr, true).isPackage();
});
bool hasExportedMembers = hasExportedPublicMembers || hasExportedPackageMembers;
// Keep track of inheritance with package access level for diags purposes.
bool hasPackageInheritance = llvm::any_of(ED->getInherited().getEntries(),
[](const InheritedEntry entry) -> bool {
if (!entry.wasValidated())
return false;
auto enType = entry.getType();
if (enType) {
if (const auto *ProtoD = dyn_cast_or_null<ProtocolDecl>(enType->getAnyNominal())) {
if (ProtoD && isExported(ProtoD) &&
ProtoD->getFormalAccessScope(nullptr, true).isPackage())
return true;
}
}
return false;
return isExported(valueMember);
});
Where = wasWhere.withExported(hasExportedMembers);
ExportabilityReason reason = ExportabilityReason::ExtensionWithPublicMembers;
if (!hasExportedPublicMembers && hasExportedPackageMembers)
reason = ExportabilityReason::ExtensionWithPackageMembers;
checkType(ED->getExtendedType(), ED->getExtendedTypeRepr(),
ED, reason);
checkType(ED->getExtendedType(), ED->getExtendedTypeRepr(), ED,
ExportabilityReason::ExtensionWithPublicMembers);
// 3) If the extension contains exported members or defines conformances,
// the 'where' clause must only name exported types.
Where = wasWhere.withExported(hasExportedMembers ||
!ED->getInherited().empty());
checkConstrainedExtensionRequirements(ED, hasExportedPublicMembers,
hasExportedPackageMembers,
hasPackageInheritance);
checkConstrainedExtensionRequirements(ED, hasExportedMembers);
if (!hasExportedMembers &&
!ED->getInherited().empty()) {
@@ -2457,11 +2397,10 @@ public:
ImportAccessLevel import = extendedType->getImportAccessFrom(DC);
if (import.has_value()) {
auto SF = DC->getParentSourceFile();
if (SF) {
if (SF->isMaxAccessLevelUsingImportInternal(import.value()))
SF->registerAccessLevelUsingImport(import.value(),
AccessLevel::Public);
}
if (SF)
SF->registerAccessLevelUsingImport(import.value(),
AccessLevel::Public);
auto &ctx = DC->getASTContext();
if (ctx.LangOpts.EnableModuleApiImportRemarks) {
ModuleDecl *importedVia = import->module.importedModule,
@@ -2611,6 +2550,49 @@ void swift::diagnoseUnnecessaryPublicImports(SourceFile &SF) {
}
}
/// Register the type extended by \p ED as being used in a package decl if
/// any member is a package decl. This patches a hole in the warnings on
/// superfluously public imports which usually relies on exportability checking
/// that is not currently executed for package decls.
void registerPackageAccessForPackageExtendedType(ExtensionDecl *ED) {
auto extendedType = ED->getExtendedNominal();
if (!extendedType)
return;
bool hasPackageMembers = llvm::any_of(ED->getMembers(),
[](const Decl *member) -> bool {
auto *VD = dyn_cast<ValueDecl>(member);
if (!VD)
return false;
AccessScope accessScope =
VD->getFormalAccessScope(nullptr,
/*treatUsableFromInlineAsPublic*/true);
return accessScope.isPackage();
});
if (!hasPackageMembers)
return;
DeclContext *DC = ED->getDeclContext();
ImportAccessLevel import = extendedType->getImportAccessFrom(DC);
if (import.has_value()) {
auto SF = DC->getParentSourceFile();
if (SF)
SF->registerAccessLevelUsingImport(import.value(),
AccessLevel::Package);
auto &ctx = DC->getASTContext();
if (ctx.LangOpts.EnableModuleApiImportRemarks) {
ModuleDecl *importedVia = import->module.importedModule,
*sourceModule = ED->getModuleContext();
ED->diagnose(diag::module_api_import,
ED, importedVia, sourceModule,
importedVia == sourceModule,
/*isImplicit*/false);
}
}
}
void swift::checkAccessControl(Decl *D) {
if (isa<ValueDecl>(D) || isa<PatternBindingDecl>(D)) {
bool allowInlineable =
@@ -2619,6 +2601,7 @@ void swift::checkAccessControl(Decl *D) {
UsableFromInlineChecker().visit(D);
} else if (auto *ED = dyn_cast<ExtensionDecl>(D)) {
checkExtensionGenericParamAccess(ED);
registerPackageAccessForPackageExtendedType(ED);
}
if (isa<AccessorDecl>(D))

View File

@@ -47,8 +47,7 @@ enum class DisallowedOriginKind : uint8_t {
SPIOnly,
MissingImport,
FragileCxxAPI,
InternalOrLessImport,
PackageImport,
NonPublicImport,
None
};

View File

@@ -44,12 +44,10 @@ using namespace swift;
ExportContext::ExportContext(
DeclContext *DC, AvailabilityContext runningOSVersion,
FragileFunctionKind kind, bool spi, bool isPackage,
bool exported, bool implicit, bool deprecated,
std::optional<PlatformKind> unavailablePlatformKind)
FragileFunctionKind kind, bool spi, bool exported, bool implicit,
bool deprecated, std::optional<PlatformKind> unavailablePlatformKind)
: DC(DC), RunningOSVersion(runningOSVersion), FragileKind(kind) {
SPI = spi;
IsPackage = isPackage;
Exported = exported;
Implicit = implicit;
Deprecated = deprecated;
@@ -74,7 +72,7 @@ bool swift::isExported(const ValueDecl *VD) {
AccessScope accessScope =
VD->getFormalAccessScope(nullptr,
/*treatUsableFromInlineAsPublic*/true);
if (accessScope.isPublicOrPackage())
if (accessScope.isPublic())
return true;
// Is this a stored property in a @frozen struct or class?
@@ -85,13 +83,13 @@ bool swift::isExported(const ValueDecl *VD) {
return false;
}
static bool hasConformancesToPublicOrPackageProtocols(const ExtensionDecl *ED) {
static bool hasConformancesToPublicProtocols(const ExtensionDecl *ED) {
auto protocols = ED->getLocalProtocols(ConformanceLookupKind::OnlyExplicit);
for (const ProtocolDecl *PD : protocols) {
AccessScope scope =
PD->getFormalAccessScope(/*useDC*/ nullptr,
/*treatUsableFromInlineAsPublic*/ true);
if (scope.isPublicOrPackage())
if (scope.isPublic())
return true;
}
@@ -113,7 +111,7 @@ bool swift::isExported(const ExtensionDecl *ED) {
// If the extension declares a conformance to a public protocol then the
// extension is exported.
if (hasConformancesToPublicOrPackageProtocols(ED))
if (hasConformancesToPublicProtocols(ED))
return true;
return false;
@@ -186,20 +184,13 @@ static void forEachOuterDecl(DeclContext *DC, Fn fn) {
}
static void
computeExportContextBits(ASTContext &Ctx, Decl *D,
bool *spi, bool *isPackage,
bool *implicit, bool *deprecated,
computeExportContextBits(ASTContext &Ctx, Decl *D, bool *spi, bool *implicit,
bool *deprecated,
std::optional<PlatformKind> *unavailablePlatformKind) {
if (D->isSPI() ||
D->isAvailableAsSPI())
*spi = true;
if (auto VD = dyn_cast<ValueDecl>(D)) {
*isPackage = VD->getFormalAccessScope(nullptr, true).isPackage();
} else if (auto ED = dyn_cast<ExtensionDecl>(D)) {
*isPackage = ED->getDefaultAccessLevel() == AccessLevel::Package;
}
// Defer bodies are desugared to an implicit closure expression. We need to
// dilute the meaning of "implicit" to make sure we're still checking
// availability inside of defer statements.
@@ -217,8 +208,8 @@ computeExportContextBits(ASTContext &Ctx, Decl *D,
if (auto *PBD = dyn_cast<PatternBindingDecl>(D)) {
for (unsigned i = 0, e = PBD->getNumPatternEntries(); i < e; ++i) {
if (auto *VD = PBD->getAnchoringVarDecl(i))
computeExportContextBits(Ctx, VD, spi, isPackage, implicit,
deprecated, unavailablePlatformKind);
computeExportContextBits(Ctx, VD, spi, implicit, deprecated,
unavailablePlatformKind);
}
}
}
@@ -233,25 +224,23 @@ ExportContext ExportContext::forDeclSignature(Decl *D) {
? AvailabilityContext::alwaysAvailable()
: TypeChecker::overApproximateAvailabilityAtLocation(D->getLoc(), DC));
bool spi = Ctx.LangOpts.LibraryLevel == LibraryLevel::SPI;
bool isPackage = false;
bool implicit = false;
bool deprecated = false;
std::optional<PlatformKind> unavailablePlatformKind;
computeExportContextBits(Ctx, D, &spi, &isPackage, &implicit,
&deprecated, &unavailablePlatformKind);
computeExportContextBits(Ctx, D, &spi, &implicit, &deprecated,
&unavailablePlatformKind);
forEachOuterDecl(D->getDeclContext(),
[&](Decl *D) {
computeExportContextBits(Ctx, D,
&spi, &isPackage, &implicit,
&deprecated, &unavailablePlatformKind);
&spi, &implicit, &deprecated,
&unavailablePlatformKind);
});
bool exported = ::isExported(D);
return ExportContext(DC, runningOSVersion, fragileKind,
spi, isPackage, exported, implicit,
deprecated, unavailablePlatformKind);
spi, exported, implicit, deprecated,
unavailablePlatformKind);
}
ExportContext ExportContext::forFunctionBody(DeclContext *DC, SourceLoc loc) {
@@ -266,20 +255,19 @@ ExportContext ExportContext::forFunctionBody(DeclContext *DC, SourceLoc loc) {
bool spi = Ctx.LangOpts.LibraryLevel == LibraryLevel::SPI;
bool implicit = false;
bool deprecated = false;
bool isPackage = false;
std::optional<PlatformKind> unavailablePlatformKind;
forEachOuterDecl(DC,
[&](Decl *D) {
computeExportContextBits(Ctx, D,
&spi, &isPackage, &implicit,
&deprecated, &unavailablePlatformKind);
&spi, &implicit, &deprecated,
&unavailablePlatformKind);
});
bool exported = false;
return ExportContext(DC, runningOSVersion, fragileKind,
spi, isPackage, exported, implicit,
deprecated, unavailablePlatformKind);
spi, exported, implicit, deprecated,
unavailablePlatformKind);
}
ExportContext ExportContext::forConformance(DeclContext *DC,
@@ -288,7 +276,7 @@ ExportContext ExportContext::forConformance(DeclContext *DC,
auto where = forDeclSignature(DC->getInnermostDeclarationDeclContext());
where.Exported &= proto->getFormalAccessScope(
DC, /*usableFromInlineAsPublic*/true).isPublicOrPackage();
DC, /*usableFromInlineAsPublic*/true).isPublic();
return where;
}
@@ -4487,7 +4475,7 @@ void swift::checkExplicitAvailability(Decl *decl) {
return false;
});
auto hasProtocols = hasConformancesToPublicOrPackageProtocols(extension);
auto hasProtocols = hasConformancesToPublicProtocols(extension);
if (!hasMembers && !hasProtocols) return;

View File

@@ -72,11 +72,7 @@ enum class ExportabilityReason : unsigned {
PropertyWrapper,
ResultBuilder,
ExtensionWithPublicMembers,
ExtensionWithConditionalConformances,
// Exported members of extension can be `package`.
ExtensionWithPackageMembers,
// Exported inheritance type can be `package`.
ExtensionWithPackageConditionalConformances
ExtensionWithConditionalConformances
};
/// A description of the restrictions on what declarations can be referenced
@@ -84,12 +80,9 @@ enum class ExportabilityReason : unsigned {
///
/// We say a declaration is "exported" if all of the following holds:
///
/// - the declaration is `public` or `@usableFromInline`
/// - the declaration is `public` or `@usableFromInline`
/// - the declaration is not `@_spi`
/// - the declaration was not imported from an `@_implementationOnly` import
/// - the declaration is `package`; while treated as exported, the
/// scope is limited compared to `public` or `@usableFromInline`;
/// the `IsPackage` bit is set to track the scope.
///
/// The "signature" of a declaration is the set of all types written in the
/// declaration (such as function parameter and return types), but not
@@ -112,7 +105,6 @@ class ExportContext {
AvailabilityContext RunningOSVersion;
FragileFunctionKind FragileKind;
unsigned SPI : 1;
unsigned IsPackage : 1;
unsigned Exported : 1;
unsigned Deprecated : 1;
unsigned Implicit : 1;
@@ -121,7 +113,7 @@ class ExportContext {
unsigned Reason : 3;
ExportContext(DeclContext *DC, AvailabilityContext runningOSVersion,
FragileFunctionKind kind, bool spi, bool isPackage, bool exported,
FragileFunctionKind kind, bool spi, bool exported,
bool implicit, bool deprecated,
std::optional<PlatformKind> unavailablePlatformKind);
@@ -176,9 +168,6 @@ public:
/// If true, the context is SPI and can reference SPI declarations.
bool isSPI() const { return SPI; }
/// If true, the context has a package access scope.
bool isPackage() const { return IsPackage; }
/// If true, the context is exported and cannot reference SPI declarations
/// or declarations from `@_implementationOnly` imports.
bool isExported() const { return Exported; }

View File

@@ -52,9 +52,9 @@ public struct PrivateImportType {
//--- Client.swift
public import PublicLib
package import PackageLib // expected-note 2 {{struct 'PackageImportType' imported as 'package' from 'PackageLib' here}}
internal import InternalLib // expected-note 4 {{struct 'InternalImportType' imported as 'internal' from 'InternalLib' here}}
fileprivate import FileprivateLib // expected-note 4 {{struct 'FileprivateImportType' imported as 'fileprivate' from 'FileprivateLib' here}}
private import PrivateLib // expected-note 4 {{struct 'PrivateImportType' imported as 'private' from 'PrivateLib' here}}
internal import InternalLib // expected-note 2 {{struct 'InternalImportType' imported as 'internal' from 'InternalLib' here}}
fileprivate import FileprivateLib // expected-note 2 {{struct 'FileprivateImportType' imported as 'fileprivate' from 'FileprivateLib' here}}
private import PrivateLib // expected-note 2 {{struct 'PrivateImportType' imported as 'private' from 'PrivateLib' here}}
public protocol PublicConstrainedExtensionProto {}
extension Array: PublicConstrainedExtensionProto where Element == PublicImportType {}
@@ -87,8 +87,8 @@ extension PublicImportType {
}
public protocol PackageConstrainedExtensionProto {}
extension Array: PackageConstrainedExtensionProto where Element == PackageImportType {} // expected-error {{cannot use struct 'PackageImportType' in an extension with conditional conformances; 'PackageLib' was imported as package}}
extension PackageImportType { // expected-error {{cannot use struct 'PackageImportType' in an extension with public or '@usableFromInline' members; 'PackageLib' was imported as package}}
extension Array: PackageConstrainedExtensionProto where Element == PackageImportType {} // expected-error {{cannot use struct 'PackageImportType' in an extension with conditional conformances; 'PackageLib' was not imported publicly}}
extension PackageImportType { // expected-error {{cannot use struct 'PackageImportType' in an extension with public or '@usableFromInline' members; 'PackageLib' was not imported publicly}}
public func publicMethod() {}
}
@@ -123,8 +123,8 @@ extension InternalImportType { // expected-error {{cannot use struct 'InternalIm
}
package protocol InternalConstrainedExtensionProtoInPackage {}
extension Array: InternalConstrainedExtensionProtoInPackage where Element == InternalImportType {} // expected-error {{cannot use struct 'InternalImportType' in an extension with conditional conformances; 'InternalLib' was not imported publicly or as package}}
extension InternalImportType { // expected-error {{cannot use struct 'InternalImportType' in an extension with public, package, or '@usableFromInline' members; 'InternalLib' was not imported publicly or as package}}
extension Array: InternalConstrainedExtensionProtoInPackage where Element == InternalImportType {}
extension InternalImportType {
package func packageMethod() {}
}
@@ -153,8 +153,8 @@ extension FileprivateImportType { // expected-error {{cannot use struct 'Filepri
}
package protocol FileprivateConstrainedExtensionProtoInPackage {}
extension Array: FileprivateConstrainedExtensionProtoInPackage where Element == FileprivateImportType {} // expected-error {{cannot use struct 'FileprivateImportType' in an extension with conditional conformances; 'FileprivateLib' was not imported publicly or as package}}
extension FileprivateImportType { // expected-error {{cannot use struct 'FileprivateImportType' in an extension with public, package, or '@usableFromInline' members; 'FileprivateLib' was not imported publicly or as package}}
extension Array: FileprivateConstrainedExtensionProtoInPackage where Element == FileprivateImportType {}
extension FileprivateImportType {
package func packageMethod() {}
}
@@ -183,8 +183,8 @@ extension PrivateImportType { // expected-error {{cannot use struct 'PrivateImpo
}
package protocol PrivateConstrainedExtensionProtoInPackage {}
extension Array: PrivateConstrainedExtensionProtoInPackage where Element == PrivateImportType {} // expected-error {{cannot use struct 'PrivateImportType' in an extension with conditional conformances; 'PrivateLib' was not imported publicly or as package}}
extension PrivateImportType { // expected-error {{cannot use struct 'PrivateImportType' in an extension with public, package, or '@usableFromInline' members; 'PrivateLib' was not imported publicly or as package}}
extension Array: PrivateConstrainedExtensionProtoInPackage where Element == PrivateImportType {}
extension PrivateImportType {
package func packageMethod() {}
}

View File

@@ -2,82 +2,29 @@
// RUN: split-file --leading-lines %s %t
/// Build the libraries.
// RUN: %target-swift-frontend -emit-module %t/ConformanceBaseTypes.swift -o %t -package-name pkg
// RUN: %target-swift-frontend -emit-module %t/ConformanceDefinition1.swift -o %t -I %t -package-name pkg
// RUN: %target-swift-frontend -emit-module %t/ConformanceDefinition2.swift -o %t -I %t -package-name pkg
// RUN: %target-swift-frontend -emit-module %t/ConformanceBaseTypes.swift -o %t
// RUN: %target-swift-frontend -emit-module %t/ConformanceDefinition.swift -o %t -I %t
/// Check diagnostics.
// RUN: %target-swift-frontend -typecheck -verify %t/ClientA.swift -I %t -package-name pkg
// RUN: %target-swift-frontend -typecheck -verify %t/ClientB.swift -I %t -package-name pkg
// RUN: %target-swift-frontend -typecheck -verify %t/Client.swift -I %t
//--- ConformanceBaseTypes.swift
public protocol Proto {}
public struct ConformingType {
public init () {}
public init () {}
}
package protocol PkgProto {} // expected-note 2 {{protocol 'PkgProto' is not '@usableFromInline' or public}}
package struct PkgConformingType { // expected-note 4 {{struct 'PkgConformingType' is not '@usableFromInline' or public}}
package init () {} // expected-note 4 {{initializer 'init()' is not '@usableFromInline' or public}}
}
//--- ConformanceDefinition1.swift
//--- ConformanceDefinition.swift
import ConformanceBaseTypes
extension ConformingType : Proto {}
//--- ConformanceDefinition2.swift
import ConformanceBaseTypes
extension PkgConformingType : PkgProto {}
//--- ClientA.swift
//--- Client.swift
public import ConformanceBaseTypes
internal import ConformanceDefinition1 // expected-note 2 {{extension of struct 'ConformingType' imported as 'internal' from 'ConformanceDefinition1' here}}
internal import ConformanceDefinition2 // expected-note 3 {{extension of struct 'PkgConformingType' imported as 'internal' from 'ConformanceDefinition2' here}}
internal import ConformanceDefinition // expected-note 2 {{extension of struct 'ConformingType' imported as 'internal' from 'ConformanceDefinition' here}}
public func useInAPI(a: any Proto = ConformingType()) { // expected-error {{cannot use conformance of 'ConformingType' to 'Proto' here; 'ConformanceDefinition1' was not imported publicly}}
}
public func useInAPI(b: any PkgProto = PkgConformingType()) {
// expected-error@-1 {{cannot use conformance of 'PkgConformingType' to 'PkgProto' here; 'ConformanceDefinition2' was not imported publicly}}
// expected-error@-2 {{function cannot be declared public because its parameter uses a package type}}
// expected-error@-3 {{struct 'PkgConformingType' is package and cannot be referenced from a default argument value}}
// expected-error@-4 {{initializer 'init()' is package and cannot be referenced from a default argument value}}
}
package func useInPkgAPI(a: any PkgProto = PkgConformingType()) {
// expected-error@-1 {{cannot use conformance of 'PkgConformingType' to 'PkgProto' here; 'ConformanceDefinition2' was not imported publicly}}
public func useInAPI(a: any Proto = ConformingType()) { // expected-error {{cannot use conformance of 'ConformingType' to 'Proto' here; 'ConformanceDefinition' was not imported publicly}}
}
@inlinable public func inlinableFunc() {
let _: any Proto = ConformingType() // expected-error {{cannot use conformance of 'ConformingType' to 'Proto' here; 'ConformanceDefinition1' was not imported publicly}}
let _: any PkgProto = PkgConformingType()
// expected-error@-1 {{cannot use conformance of 'PkgConformingType' to 'PkgProto' here; 'ConformanceDefinition2' was not imported publicly}}
// expected-error@-2 {{protocol 'PkgProto' is package and cannot be referenced from an '@inlinable' function}}
// expected-error@-3 {{struct 'PkgConformingType' is package and cannot be referenced from an '@inlinable' function}}
// expected-error@-4 {{initializer 'init()' is package and cannot be referenced from an '@inlinable' function}}
}
//--- ClientB.swift
public import ConformanceBaseTypes
package import ConformanceDefinition1 // expected-note 2 {{extension of struct 'ConformingType' imported as 'package' from 'ConformanceDefinition1' here}}
package import ConformanceDefinition2 // expected-note 2 {{extension of struct 'PkgConformingType' imported as 'package' from 'ConformanceDefinition2' here}}
public func useInAPI(a: any Proto = ConformingType()) { // expected-error {{cannot use conformance of 'ConformingType' to 'Proto' here; 'ConformanceDefinition1' was imported as package}}
}
public func useInAPI(b: any PkgProto = PkgConformingType()) {
// expected-error@-1 {{cannot use conformance of 'PkgConformingType' to 'PkgProto' here; 'ConformanceDefinition2' was imported as package}}
// expected-error@-2 {{function cannot be declared public because its parameter uses a package type}}
// expected-error@-3 {{struct 'PkgConformingType' is package and cannot be referenced from a default argument value}}
// expected-error@-4 {{initializer 'init()' is package and cannot be referenced from a default argument value}}
}
package func useInPkgAPI(a: any PkgProto = PkgConformingType()) { // no-error
}
@inlinable public func inlinableFunc() {
let _: any Proto = ConformingType() // expected-error {{cannot use conformance of 'ConformingType' to 'Proto' here; 'ConformanceDefinition1' was imported as package}}
let _: any PkgProto = PkgConformingType()
// expected-error@-1 {{cannot use conformance of 'PkgConformingType' to 'PkgProto' here; 'ConformanceDefinition2' was imported as package}}
// expected-error@-2 {{protocol 'PkgProto' is package and cannot be referenced from an '@inlinable' function}}
// expected-error@-3 {{struct 'PkgConformingType' is package and cannot be referenced from an '@inlinable' function}}
// expected-error@-4 {{initializer 'init()' is package and cannot be referenced from an '@inlinable' function}}
let _: any Proto = ConformingType() // expected-error {{cannot use conformance of 'ConformingType' to 'Proto' here; 'ConformanceDefinition' was not imported publicly}}
}

View File

@@ -43,20 +43,6 @@ public struct PackageImportType {
public init() {}
}
public protocol PackageImportProto {
associatedtype T
}
public func PackageFunc() {}
@propertyWrapper
public struct PackageImportWrapper<T> {
public var wrappedValue: T
public init(wrappedValue: T) {
self.wrappedValue = wrappedValue
}
}
//--- InternalLib.swift
public protocol InternalImportProto {
associatedtype T
@@ -90,12 +76,7 @@ public struct PrivateImportType {
public import PublicLib
package import PackageLib
// expected-note@-1 9 {{struct 'PackageImportType' imported as 'package' from 'PackageLib' here}}
// expected-note@-2 2 {{global function 'PackageFunc()' imported as 'package' from 'PackageLib' here}}
// expected-note@-3 2 {{protocol 'PackageImportProto' imported as 'package' from 'PackageLib' here}}
// expected-note@-4 2 {{initializer 'init()' imported as 'package' from 'PackageLib' here}}
// expected-note@-5 2 {{generic struct 'PackageImportWrapper' imported as 'package' from 'PackageLib' here}}
// expected-note@-6 2 {{initializer 'init(wrappedValue:)' imported as 'package' from 'PackageLib' here}}
// expected-note@-1 4 {{struct 'PackageImportType' imported as 'package' from 'PackageLib' here}}
internal import InternalLib
// expected-note@-1 9 {{struct 'InternalImportType' imported as 'internal' from 'InternalLib' here}}
@@ -109,29 +90,24 @@ fileprivate import FileprivateLib
// expected-note@-3 2 {{protocol 'FileprivateImportProto' imported as 'fileprivate' from 'FileprivateLib' here}}
private import PrivateLib
// expected-note@-1 12 {{struct 'PrivateImportType' imported as 'private' from 'PrivateLib' here}}
// expected-note@-2 2 {{initializer 'init()' imported as 'private' from 'PrivateLib' here}}
// expected-note@-1 10 {{struct 'PrivateImportType' imported as 'private' from 'PrivateLib' here}}
// expected-note@-2 2 {{initializer 'init()' imported as 'private' from 'PrivateLib' here}}
public struct GenericType<T, U> {}
@inlinable public func inlinable() {
PublicFunc()
PackageFunc() // expected-error {{global function 'PackageFunc()' is package and cannot be referenced from an '@inlinable' function}}
InternalFunc() // expected-error {{global function 'InternalFunc()' is internal and cannot be referenced from an '@inlinable' function}}
let _: PublicImportType
let _: PackageImportType // expected-error {{struct 'PackageImportType' is package and cannot be referenced from an '@inlinable' function}}
let _: InternalImportType // expected-error {{struct 'InternalImportType' is internal and cannot be referenced from an '@inlinable' function}}
let _ = PublicImportType()
let _ = PackageImportType() // expected-error {{struct 'PackageImportType' is package and cannot be referenced from an '@inlinable' function}}
// expected-error @-1 {{initializer 'init()' is package and cannot be referenced from an '@inlinable' function}}
let _ = PrivateImportType() // expected-error {{struct 'PrivateImportType' is private and cannot be referenced from an '@inlinable' function}}
// expected-error @-1 {{initializer 'init()' is private and cannot be referenced from an '@inlinable' function}}
let _: any PublicImportProto
let _: any PackageImportProto // expected-error {{protocol 'PackageImportProto' is package and cannot be referenced from an '@inlinable' function}}
let _: any InternalImportProto // expected-error {{protocol 'InternalImportProto' is internal and cannot be referenced from an '@inlinable' function}}
let _: any FileprivateImportProto & InternalImportProto // expected-error {{protocol 'FileprivateImportProto' is fileprivate and cannot be referenced from an '@inlinable' function}}
@@ -150,10 +126,6 @@ public struct GenericType<T, U> {}
@PublicImportWrapper
var wrappedPublic: PublicImportType
@PackageImportWrapper // expected-error {{initializer 'init(wrappedValue:)' is package and cannot be referenced from an '@inlinable' function}}
// expected-error @-1 {{generic struct 'PackageImportWrapper' is package and cannot be referenced from an '@inlinable' function}}
var wrappedPackage: PublicImportType
@FileprivateImportWrapper // expected-error {{initializer 'init(wrappedValue:)' is fileprivate and cannot be referenced from an '@inlinable' function}}
// expected-error @-1 {{generic struct 'FileprivateImportWrapper' is fileprivate and cannot be referenced from an '@inlinable' function}}
var wrappedFileprivate: PublicImportType
@@ -166,21 +138,16 @@ public struct GenericType<T, U> {}
@_alwaysEmitIntoClient public func alwaysEmitIntoClient() {
PublicFunc()
PackageFunc() // expected-error {{global function 'PackageFunc()' is package and cannot be referenced from an '@_alwaysEmitIntoClient' function}}
InternalFunc() // expected-error {{global function 'InternalFunc()' is internal and cannot be referenced from an '@_alwaysEmitIntoClient' function}}
let _: PublicImportType
let _: PackageImportType // expected-error {{struct 'PackageImportType' is package and cannot be referenced from an '@_alwaysEmitIntoClient' function}}
let _: InternalImportType // expected-error {{struct 'InternalImportType' is internal and cannot be referenced from an '@_alwaysEmitIntoClient' function}}
let _ = PublicImportType()
let _ = PackageImportType() // expected-error {{struct 'PackageImportType' is package and cannot be referenced from an '@_alwaysEmitIntoClient' function}}
// expected-error @-1 {{initializer 'init()' is package and cannot be referenced from an '@_alwaysEmitIntoClient' function}}
let _ = PrivateImportType() // expected-error {{struct 'PrivateImportType' is private and cannot be referenced from an '@_alwaysEmitIntoClient' function}}
// expected-error @-1 {{initializer 'init()' is private and cannot be referenced from an '@_alwaysEmitIntoClient' function}}
let _: any PublicImportProto
let _: any PackageImportProto // expected-error {{protocol 'PackageImportProto' is package and cannot be referenced from an '@_alwaysEmitIntoClient' function}}
let _: any InternalImportProto // expected-error {{protocol 'InternalImportProto' is internal and cannot be referenced from an '@_alwaysEmitIntoClient' function}}
let _: any FileprivateImportProto & InternalImportProto // expected-error {{protocol 'FileprivateImportProto' is fileprivate and cannot be referenced from an '@_alwaysEmitIntoClient' function}}
@@ -199,10 +166,6 @@ public struct GenericType<T, U> {}
@PublicImportWrapper
var wrappedPublic: PublicImportType
@PackageImportWrapper // expected-error {{initializer 'init(wrappedValue:)' is package and cannot be referenced from an '@_alwaysEmitIntoClient' function}}
// expected-error @-1 {{generic struct 'PackageImportWrapper' is package and cannot be referenced from an '@_alwaysEmitIntoClient' function}}
var wrappedPackage: PublicImportType
@FileprivateImportWrapper // expected-error {{initializer 'init(wrappedValue:)' is fileprivate and cannot be referenced from an '@_alwaysEmitIntoClient' function}}
// expected-error @-1 {{generic struct 'FileprivateImportWrapper' is fileprivate and cannot be referenced from an '@_alwaysEmitIntoClient' function}}
var wrappedFileprivate: PublicImportType
@@ -217,23 +180,12 @@ public struct GenericType<T, U> {}
// expected-note @-1 {{struct 'PrivateImportType' is imported by this file as 'private' from 'PrivateLib'}}
}
@frozen package struct PkgBadFields1 {
private var field: PrivateImportType // expected-error {{type referenced from a stored property in a '@frozen package' struct must be '@usableFromInline', public, or package}}
// expected-note @-1 {{struct 'PrivateImportType' is imported by this file as 'private' from 'PrivateLib'}}
}
@_fixed_layout public struct FixedBadFields1 {
// expected-warning@-1 {{'@frozen' attribute is now used for fixed-layout structs}}
private var field: PrivateImportType // expected-error {{type referenced from a stored property in a '@frozen' struct must be '@usableFromInline' or public}}
// expected-note @-1 {{struct 'PrivateImportType' is imported by this file as 'private' from 'PrivateLib'}}
}
@_fixed_layout package struct PkgFixedBadFields1 {
// expected-warning@-1 {{'@frozen' attribute is now used for fixed-layout structs}}
private var field: PrivateImportType // expected-error {{type referenced from a stored property in a '@frozen package' struct must be '@usableFromInline', public, or package}}
// expected-note @-1 {{struct 'PrivateImportType' is imported by this file as 'private' from 'PrivateLib'}}
}
@frozen public struct BadFields2 {
private var field: PrivateImportType? // expected-error {{type referenced from a stored property in a '@frozen' struct must be '@usableFromInline' or public}}
// expected-note @-1 {{struct 'PrivateImportType' is imported by this file as 'private' from 'PrivateLib'}}
@@ -297,17 +249,6 @@ public struct GenericType<T, U> {}
}
}
// expected-error@+1 {{the result of a '@usableFromInline' function must be '@usableFromInline' or public}}
@usableFromInline func notReallyUsableFromInlinePkg() -> PackageImportType? { return nil }
// expected-note @-1 {{struct 'PackageImportType' is imported by this file as 'package' from 'PackageLib'}}
@frozen public struct BadFieldsPkg7 {
private var field = notReallyUsableFromInlinePkg() // expected-error {{type referenced from a stored property with inferred type 'PackageImportType?' in a '@frozen' struct must be '@usableFromInline' or public}}
}
@_fixed_layout public struct FrozenBadFieldsPkg7 {
// expected-warning@-1 {{'@frozen' attribute is now used for fixed-layout structs}}
private var field = notReallyUsableFromInlinePkg() // expected-error {{type referenced from a stored property with inferred type 'PackageImportType?' in a '@frozen' struct must be '@usableFromInline' or public}}
}
// expected-error@+1 {{the result of a '@usableFromInline' function must be '@usableFromInline' or public}}
@usableFromInline func notReallyUsableFromInline() -> InternalImportType? { return nil }
// expected-note @-1 {{struct 'InternalImportType' is imported by this file as 'internal' from 'InternalLib'}}
@@ -320,36 +261,13 @@ public struct GenericType<T, U> {}
private var field = notReallyUsableFromInline() // expected-error {{type referenced from a stored property with inferred type 'InternalImportType?' in a '@frozen' struct must be '@usableFromInline' or public}}
}
@frozen package struct PkgBadFields7 {
private var field = notReallyUsableFromInline() // expected-error {{type referenced from a stored property with inferred type 'InternalImportType?' in a '@frozen package' struct must be '@usableFromInline', public, or package}}
}
@_fixed_layout package struct PkgFrozenBadFields7 {
// expected-warning@-1 {{'@frozen' attribute is now used for fixed-layout structs}}
private var field = notReallyUsableFromInline() // expected-error {{type referenced from a stored property with inferred type 'InternalImportType?' in a '@frozen package' struct must be '@usableFromInline', public, or package}}
}
@frozen public struct OKFields {
public var field: PublicImportType
internal static var staticProp: InternalImportType?
private var computed: PrivateImportType? { return nil }
}
@_fixed_layout public struct FixedOKFields {
// expected-warning@-1 {{'@frozen' attribute is now used for fixed-layout structs}}
public var field: PublicImportType
internal static var staticProp: InternalImportType?
private var computed: PrivateImportType? { return nil }
}
@frozen package struct PkgOKFields {
package var field: PackageImportType
internal static var staticProp: InternalImportType?
private var computed: PrivateImportType? { return nil }
}
@_fixed_layout package struct PkgFixedOKFields {
// expected-warning@-1 {{'@frozen' attribute is now used for fixed-layout structs}}
package var field: PackageImportType
internal static var staticProp: InternalImportType?
private var computed: PrivateImportType? { return nil }
}

View File

@@ -1,108 +0,0 @@
// RUN: %empty-directory(%t)
// RUN: split-file %s %t
// RUN: %target-swift-frontend -emit-module %t/Lib.swift \
// RUN: -module-name Lib -swift-version 6 -I %t \
// RUN: -package-name mypkg \
// RUN: -enable-library-evolution \
// RUN: -emit-module -emit-module-path %t/Lib.swiftmodule
// RUN: %target-swift-frontend -typecheck %t/ClientA.swift -I %t -swift-version 6 -package-name mypkg -enable-library-evolution -verify
// RUN: %target-swift-frontend -typecheck %t/ClientB.swift -I %t -swift-version 6 -package-name mypkg -enable-library-evolution -verify
// RUN: %target-swift-frontend -typecheck %t/ClientC.swift -I %t -swift-version 6 -package-name mypkg -enable-library-evolution -verify
// RUN: %target-swift-frontend -typecheck %t/ClientD.swift -I %t -swift-version 6 -package-name mypkg -enable-library-evolution -verify
// RUN: %target-swift-frontend -typecheck %t/ClientE.swift -I %t -swift-version 6 -package-name mypkg -enable-library-evolution -verify
// RUN: %target-swift-frontend -typecheck %t/ClientF.swift -I %t -swift-version 6 -package-name mypkg -enable-library-evolution -verify
//--- ClientA.swift
@_implementationOnly import Lib // expected-warning {{'@_implementationOnly' is deprecated, use 'internal import' instead}}
public func f() -> PubProto? { // expected-error {{cannot use protocol 'PubProto' here; 'Lib' has been imported as implementation-only}}
return nil
}
package func g() -> PkgProto? { // expected-error {{cannot use protocol 'PkgProto' here; 'Lib' has been imported as implementation-only}}
return nil
}
//--- ClientB.swift
package import Lib // no-warning
extension PkgStruct {
package static var v: Self {
fatalError()
}
}
//--- ClientC.swift
package import Lib // no-warning
extension PkgStruct {
package func f() {}
}
//--- ClientD.swift
package import Lib // no-warning
package extension PubStruct {
func f() {}
}
//--- ClientE.swift
package import Lib
package enum FeatureFlag: PubProto { // no-warning
case myFeatureFlag
package var domain: StaticString { "MyDomain" }
package var feature: StaticString { "MyFeature" }
package var someVar: String { "" }
}
package struct MyStruct: PubProto { // no-warning
package var someVar: String { "" }
}
//--- ClientF.swift
package struct PkgStruct {}
public protocol PubProto {
associatedtype CodeUnit
}
extension PkgStruct {
@frozen
package enum ASCII {}
}
extension PkgStruct.ASCII: PubProto {
package typealias CodeUnit = UInt8
}
//--- Lib.swift
// expected-note@+1 1{{type declared here}}
public protocol PubProto {
var someVar: String { get }
}
// expected-note@+1 1{{type declared here}}
package protocol PkgProto {
var someVar: String { get }
}
public struct PubStruct {
public init() {}
}
package struct PkgStruct {
package init() {}
}
public class PubKlass {
public init() {}
}
package class PkgKlass {
package init() {}
}

View File

@@ -13,22 +13,6 @@
// RUN: -swift-version 5 -enable-library-evolution \
// RUN: -enable-upcoming-feature InternalImportsByDefault
// RUN: %target-swift-frontend -emit-module %t/Original.swift -o %t \
// RUN: -swift-version 6 -enable-library-evolution -package-name pkg
// RUN: %target-swift-frontend -emit-module %t/AliasesPkg.swift -o %t \
// RUN: -swift-version 6 -enable-library-evolution -I %t -package-name pkg
// RUN: %target-swift-frontend -typecheck -verify %t/UsesAliasesPkg1.swift -I %t \
// RUN: -swift-version 5 -enable-library-evolution -package-name pkg
// RUN: %target-swift-frontend -typecheck -verify %t/UsesAliasesPkg1.swift -I %t \
// RUN: -swift-version 6 -enable-library-evolution -package-name pkg
// RUN: %target-swift-frontend -typecheck -verify %t/UsesAliasesPkg2.swift -I %t \
// RUN: -swift-version 5 -enable-library-evolution -package-name pkg
// RUN: %target-swift-frontend -typecheck -verify %t/UsesAliasesPkg2.swift -I %t \
// RUN: -swift-version 6 -enable-library-evolution -package-name pkg
//--- Original.swift
open class Clazz {}
@@ -48,46 +32,3 @@ public class InheritsFromClazzAlias: ClazzAlias {}
_ = ClazzAlias.self
}
//--- AliasesPkg.swift
public import Original // expected-warning {{public import of 'Original' was not used in public declarations or inlinable code}}
package typealias PkgClazzAlias = Clazz // expected-note 2 {{type alias 'PkgClazzAlias' is not '@usableFromInline' or public}}
//--- UsesAliasesPkg1.swift
public import AliasesPkg // expected-warning {{public import of 'AliasesPkg' was not used in public declarations or inlinable code}}
internal import Original // expected-note 1 {{class 'Clazz' imported as 'internal' from 'Original' here}}
// expected-error@+1 {{'PkgClazzAlias' aliases 'Original.Clazz' and cannot be used here because 'Original' was not imported publicly}}
package class InheritsFromPkgClazzAlias: PkgClazzAlias {}
@inlinable public func inlinableFunc() {
// expected-error@+1 {{type alias 'PkgClazzAlias' is package and cannot be referenced from an '@inlinable' function}}
_ = PkgClazzAlias.self
}
@inlinable package func inlinableFuncPkg() {
// expected-error@+1 {{type alias 'PkgClazzAlias' is package and cannot be referenced from an '@inlinable' function}}
_ = PkgClazzAlias.self
}
//--- UsesAliasesPkg2.swift
public import AliasesPkg // expected-warning {{public import of 'AliasesPkg' was not used in public declarations or inlinable code}}
package import Original
package class InheritsFromPkgClazzAlias: PkgClazzAlias {} // no-error
package func usePkgClazzAlias() {
_ = PkgClazzAlias.self // no-error
}
@inlinable public func inlinableFunc() {
// expected-error@+1 {{type alias 'PkgClazzAlias' is package and cannot be referenced from an '@inlinable' function}}
_ = PkgClazzAlias.self
}
@inlinable package func inlinableFuncPkg() {
// expected-error@+1 {{type alias 'PkgClazzAlias' is package and cannot be referenced from an '@inlinable' function}}
_ = PkgClazzAlias.self
}

View File

@@ -235,9 +235,7 @@ internal func internalFunc(a: NotAnAPIType = notAnAPIFunc()) {}
func implicitlyInternalFunc(a: NotAnAPIType = notAnAPIFunc()) {}
// For package decls we only remark on types used in signatures, not for inlinable code.
package func packageFunc(a: PackageType = packageFunc()) {}
// expected-remark@-1 {{struct 'PackageType' is imported via 'ImportUsedInPackage'}}
// expected-remark@-2 {{global function 'packageFunc()' is imported via 'ImportUsedInPackage'}}
package func packageFunc(a: PackageType = packageFunc()) {} // expected-remark {{struct 'PackageType' is imported via 'ImportUsedInPackage'}}
@_spi(X)
public func spiFunc(a: ToUseFromSPI) {} // expected-remark {{struct 'ToUseFromSPI' is imported via 'SPIOnlyUsedInSPI'}}
@@ -249,7 +247,7 @@ public protocol Countable {
extension Extended: Countable { // expected-remark {{struct 'Extended' is imported via 'RetroactiveConformance'}}
}
extension ExtendedPackageType { // expected-remark 2 {{struct 'ExtendedPackageType' is imported via 'ExtendedPackageTypeImport'}}
extension ExtendedPackageType { // expected-remark {{struct 'ExtendedPackageType' is imported via 'ExtendedPackageTypeImport'}}
package func useExtendedPackageType() { }
}

View File

@@ -1,9 +1,8 @@
// RUN: %target-typecheck-verify-swift -swift-version 5 -package-name myPkg
private class PrivateType {}
// expected-note@-1 2 {{class 'PrivateType' is not '@usableFromInline' or public}}
// expected-note@-2 2 {{initializer 'init()' is not '@usableFromInline' or public}}
// expected-note@-3 2 {{type declared here}}
private class PrivateType {} // expected-note {{class 'PrivateType' is not '@usableFromInline' or public}}
// expected-note@-1 {{initializer 'init()' is not '@usableFromInline' or public}}
// expected-note@-2 {{type declared here}}
package class PackageType {
// expected-note@-1 {{class 'PackageType' is not '@usableFromInline' or public}}
@@ -45,20 +44,3 @@ public struct Wrapper<T> {
@Wrapper private var z1: PackageTypeForInline
@Wrapper private var z2 = PackageTypeForInline()
}
@frozen package struct FrozenPackageStruct {
@Wrapper private var p1: PrivateType
// expected-error@-1 {{type referenced from a stored property in a '@frozen package' struct must be '@usableFromInline', public, or package}}
@Wrapper private var p2 = PrivateType()
// expected-error@-1 {{class 'PrivateType' is private and cannot be referenced from a property initializer in a '@frozen' type}}
// expected-error@-2 {{initializer 'init()' is private and cannot be referenced from a property initializer in a '@frozen' type}}
// expected-error@-3 {{type referenced from a stored property with inferred type 'PrivateType' in a '@frozen package' struct must be '@usableFromInline', public, or package}}
// no-errors below
@Wrapper private var q1: PackageType
@Wrapper private var q2 = PackageType()
@Wrapper private var r1: PackageTypeForInline
@Wrapper private var r2 = PackageTypeForInline()
}