Skip to content

AST: Refine name lookup rule for protocol extension 'where' clauses #72364

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 16, 2024

Conversation

slavapestov
Copy link
Contributor

@slavapestov slavapestov commented Mar 15, 2024

We have two "levels" of name lookup, and the more primitive level is
used by name lookup itself to avoid certain cycles. For example,
extension binding, resolution of inheritance clauses, etc.

One interesting case is that a protocol extension can impose additional
requiremnts on Self, and members of the right-hand side type are
visible to unqualified lookup.

The right-hand side of a Self requirement in this case is always a
protocol type or class type canonically, but it might be written to
refer to a protocol type alias.

Before some changes for noncopyable generics, the primitive name
lookup mechanism, implemented in directReferencesForTypeRepr() and
such, would check if the TypeRepr had already been resolved by
resolveType(). If so, it would immediately return the decl.

This masked an issue, where the right-hand side of a Self requirement
was resolved in the parent DeclContext. A more subtle rule is needed;
for a protocol extension, we must resolve the right-hand side in the
protocol, but disregard the protocol extension's Self requirements,
because doing so would recursively trigger the same lookup again.

Fixes rdar://problem/124498054.

@slavapestov
Copy link
Contributor Author

@swift-ci Please smoke test

@slavapestov
Copy link
Contributor Author

@swift-ci Please test source compatibility

We have two "levels" of name lookup, and the more primitive level is
used by name lookup itself to avoid certain cycles. For example,
extension binding, resolution of inheritance clauses, etc.

One interesting case is that a protocol extension can impose additional
requiremnts on `Self`, and members of the right-hand side type are
visible to unqualified lookup.

The right-hand side of a `Self` requirement in this case is always a
protocol type or class type canonically, but it might be written to
refer to a protocol type alias.

Before some changes for noncopyable generics, the primitive name
lookup mechanism, implemented in directReferencesForTypeRepr() and
such, would check if the TypeRepr had already been resolved by
resolveType(). If so, it would immediately return the decl.

This masked an issue, where the right-hand side of a `Self` requirement
was resolved in the parent DeclContext. A more subtle rule is needed;
for a protocol extension, we must resolve the right-hand side in the
protocol, but disregard the protocol extension's `Self` requirements,
because doing so would recursively trigger the same lookup again.

Fixes rdar://problem/124498054.
@slavapestov
Copy link
Contributor Author

@swift-ci Please smoke test

@slavapestov slavapestov enabled auto-merge March 16, 2024 15:17
@slavapestov slavapestov merged commit b57db86 into swiftlang:main Mar 16, 2024
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.

1 participant