Files
swift-mirror/test/NameLookup/protocol_extension_where_clause.swift
Slava Pestov e46a0c56a8 AST: Refine name lookup rule for protocol extension 'where' clauses
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.
2024-03-16 08:34:42 -04:00

31 lines
426 B
Swift

// RUN: %target-typecheck-verify-swift
protocol P1 {
typealias A = P2
}
protocol P2 {
associatedtype B
typealias A1 = Int
func f1()
}
extension P2 {
typealias A2 = String
func f2() {}
}
extension P1 where Self: A {
typealias B1 = A1
typealias B2 = A2
func g() {
f1()
f2()
}
}
// This is terrible and we should ban it some day
extension P1 where Self: A, B: Hashable {
func h(_: Set<B>) {}
}