Skip to content

Conversation

@sepy97
Copy link
Contributor

@sepy97 sepy97 commented Dec 4, 2025

Private member witnessing a public constraint should be deprecated. Previously existing workaround is checked and compiler emits a warning when strict access check is not passed. Test files were fixed to expect the corresponding warning.
rdar://74904373

@sepy97
Copy link
Contributor Author

sepy97 commented Dec 4, 2025

There is still work to be done here (since a draft PR). This change breaks 18 tests, most of them due to the warning that is generated. One approach is to introduce a new UPCOMING_FEATURE flag and hide the diagnose behind it.

@sepy97
Copy link
Contributor Author

sepy97 commented Dec 4, 2025

These fail due to the warning:
Swift(macosx-arm64) :: Compatibility/accessibility.swift
Swift(macosx-arm64) :: Compatibility/optional_visibility.swift
Swift(macosx-arm64) :: Distributed/distributed_actor_system_missing_adhoc_requirement_impls.swift
Swift(macosx-arm64) :: Generics/rdar123013710.swift
Swift(macosx-arm64) :: Interop/Cxx/class/access/access-inversion-typechecker.swift
Swift(macosx-arm64) :: NameLookup/accessibility.swift
Swift(macosx-arm64) :: SILGen/internal_protocol_refines_public_protocol_with_public_default_implementation.swift
Swift(macosx-arm64) :: Sema/accessibility.swift
Swift(macosx-arm64) :: Sema/accessibility_private.swift
Swift(macosx-arm64) :: attr/accessibility_proto.swift
Swift(macosx-arm64) :: attr/global_actor.swift
Swift(macosx-arm64) :: decl/protocol/conforms/access_corner_case.swift
Swift(macosx-arm64) :: decl/protocol/req/optional_visibility.swift

These fail due to the error:
Swift(macosx-arm64) :: Profiler/samplepgo.swift
Swift(macosx-arm64) :: Interop/Cxx/function/default-arguments-multifile.swift
Swift(macosx-arm64) :: embedded/synchronization.swift
Swift(macosx-arm64) :: SILGen/protocol_resilience.swift
Swift(macosx-arm64) :: IRGen/mangle-opaque-return-type.swift

if (!witness->isAccessibleFrom(actualScopeToCheck.getDeclContext())) {
if (dc->getParentModule()->isResilient()) {
// This module was built with -enable-library-evolution
dc->getASTContext().Diags.diagnose(witness->getLoc(), diag::err_private_member_witness_public_protocol,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

witness->diagnose(...)

return 42
}
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too many blank lines

protocol InternalProtocol: PublicProtocol {}

extension InternalProtocol {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

ERROR(err_private_member_witness_public_protocol,none,
"%0 is private and should not witness public protocol %1",
(const ValueDecl *,const ProtocolDecl *))
WARNING(warn_private_member_witness_public_protocol,none,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's already a mechanism to emit something as a warning or error, with warnUntilFutureSwiftVersionIf()

@sepy97 sepy97 force-pushed the public-decl-internal-protocol branch 4 times, most recently from 3340009 to b2a7b32 Compare December 8, 2025 18:40
auto actualScopeToCheck = requiredAccessScope.first;

// without StrictTextualInterfaceChecking feature forConformance is set true
bool forConformance = not dc->getASTContext().LangOpts.hasFeature(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Please use ! instead of not
  • Can you extract a local variable for dc->getASTContext()


auto actualScopeToCheck = requiredAccessScope.first;

// without StrictTextualInterfaceChecking feature forConformance is set true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is unnecessary in my opinion

diagKind, getProtocolRequirementKind(requirement),
witness, isSetter, requiredAccess,
protoAccessScope.accessLevelForDiagnostics(), proto)
.warnUntilFutureSwiftVersionIf(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this change, all access control errors from conformance checking now become warnings, we don't want that

@sepy97 sepy97 force-pushed the public-decl-internal-protocol branch 2 times, most recently from dee5723 to 40e5c52 Compare December 10, 2025 22:14
@sepy97 sepy97 requested a review from slavapestov December 10, 2025 22:14
@sepy97 sepy97 force-pushed the public-decl-internal-protocol branch from 40e5c52 to 5d9d8b6 Compare December 10, 2025 23:55
@sepy97 sepy97 marked this pull request as ready for review December 10, 2025 23:55
@sepy97
Copy link
Contributor Author

sepy97 commented Dec 11, 2025

@swift-ci please smoke test

@nkcsgexi
Copy link
Contributor

@swift-ci please smoke test Windows

ASSERT(kind != CheckKind::Availability);
}

RequirementCheck(AccessScope requiredAccessScope, bool forSetter)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can probably remove the old overload then

// Exists specifically for AccessStrict
RequirementCheck(CheckKind accessKind, AccessScope requiredAccessScope,
bool forSetter)
: Kind(accessKind), Access{requiredAccessScope, forSetter} {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ASSERT() here that the kind is either Access or AccessStrict

if (match.Witness->isAccessibleFrom(requiredAccessLevel.getDeclContext(),
true) &&
!match.Witness->isAccessibleFrom(requiredAccessLevel.getDeclContext(),
false)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We write /*forConformance=*/true and /*forConformance=*/false to make this clearer

return RequirementCheck(CheckKind::AccessStrict, requiredAccessLevel,
isSetter);
}
if (checkWitnessAccess(DC, requirement, match.Witness, &isSetter))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could sink your new check down into checkWitnessAccess() if you change the return type of checkWitnessAccess(). That would avoid repeating the /*forConformance=*/true check twice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be better to keep checkWitnessAccess() as is? Since the end goal is to get rid of forConformance altogether (then the check will only occur once).

@@ -0,0 +1,30 @@
// RUN: %empty-directory(%t)
// RUN: %target-typecheck-verify-swift -enable-library-evolution
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is -enable-library-evolution required for the test?

func privateRequirement()
func privateRequirementCannotWork()
// expected-note@-1 {{protocol requires function 'privateRequirementCannotWork()' with type '() -> ()'}}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this file already covers this behavior, so it probably suffices to just update the expectations here as you did. Maybe you can add some new test cases here instead of adding a new file to test/Sema?

Private member witnessing a public constraint should be deprecated.
Previously existing workaround is checked and compiler emits a warning
when strict access check is not passed. Test files were fixed to expect
the corresponding warning.

rdar://74904373
@sepy97 sepy97 force-pushed the public-decl-internal-protocol branch from 5d9d8b6 to 6280a70 Compare December 16, 2025 00:23
@sepy97
Copy link
Contributor Author

sepy97 commented Dec 16, 2025

@swift-ci please smoke test

@sepy97
Copy link
Contributor Author

sepy97 commented Dec 16, 2025

@swift-ci please test windows

@sepy97 sepy97 requested a review from slavapestov December 16, 2025 17:36
@nkcsgexi
Copy link
Contributor

cc: @slavapestov to take another round of review🙏

@nkcsgexi nkcsgexi merged commit 4a6badd into swiftlang:main Dec 17, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants