Skip to content

Commit 04db12f

Browse files
authored
Merge pull request #74248 from hamishknight/macrotype
[Completion] Fix macro argument and protocol static member completion
2 parents 12f402f + 98ba978 commit 04db12f

File tree

3 files changed

+63
-14
lines changed

3 files changed

+63
-14
lines changed

lib/IDE/CodeCompletion.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,14 +1431,14 @@ void CodeCompletionCallbacksImpl::typeCheckWithLookup(
14311431
/// decl it could be attached to. Type check it standalone.
14321432

14331433
// First try to check it as an attached macro.
1434-
auto resolvedMacro = evaluateOrDefault(
1434+
(void)evaluateOrDefault(
14351435
CurDeclContext->getASTContext().evaluator,
14361436
ResolveMacroRequest{AttrWithCompletion, CurDeclContext},
14371437
ConcreteDeclRef());
14381438

14391439
// If that fails, type check as a call to the attribute's type. This is
14401440
// how, e.g., property wrappers are modelled.
1441-
if (!resolvedMacro) {
1441+
if (!Lookup.gotCallback()) {
14421442
ASTNode Call = CallExpr::create(
14431443
CurDeclContext->getASTContext(), AttrWithCompletion->getTypeExpr(),
14441444
AttrWithCompletion->getArgs(), /*implicit=*/true);

lib/Sema/IDETypeCheckingRequests.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -116,29 +116,29 @@ class ContainsSpecializableArchetype : public TypeWalker {
116116
}
117117
};
118118

119-
/// Returns `true` if `ED` is an extension of `PD` that binds `Self` to a
120-
/// concrete type, like `extension MyProto where Self == MyStruct {}`.
119+
/// Returns `true` if `ED` is an extension that binds `Self` to a
120+
/// concrete type, like `extension MyProto where Self == MyStruct {}`. The
121+
/// protocol being extended must either be `PD`, or `Self` must be a type
122+
/// that conforms to `PD`.
121123
///
122124
/// In these cases, it is possible to access static members defined in the
123125
/// extension when perfoming unresolved member lookup in a type context of
124126
/// `PD`.
125127
static bool isExtensionWithSelfBound(const ExtensionDecl *ED,
126128
ProtocolDecl *PD) {
127-
if (!ED || !PD) {
129+
if (!ED || !PD)
128130
return false;
129-
}
130-
if (ED->getExtendedNominal() != PD) {
131-
return false;
132-
}
131+
133132
GenericSignature genericSig = ED->getGenericSignature();
134133
Type selfType = genericSig->getConcreteType(ED->getSelfInterfaceType());
135-
if (!selfType) {
134+
if (!selfType)
136135
return false;
137-
}
138-
if (selfType->is<ExistentialType>()) {
136+
137+
if (selfType->is<ExistentialType>())
139138
return false;
140-
}
141-
return true;
139+
140+
auto *M = ED->getParentModule();
141+
return ED->getExtendedNominal() == PD || M->checkConformance(selfType, PD);
142142
}
143143

144144
static bool isExtensionAppliedInternal(const DeclContext *DC, Type BaseTy,

test/IDE/complete_rdar129024996.swift

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// RUN: %batch-code-completion
2+
3+
protocol P {}
4+
protocol Q : P {}
5+
6+
// Applicable, S conforms to Q.
7+
struct S : Q {}
8+
extension P where Self == S {
9+
static func foo() -> S { S() }
10+
}
11+
12+
// Not applicable, Q does not inherit from K.
13+
protocol K {}
14+
extension S : K {}
15+
extension K where Self == S {
16+
static func bar() -> S { S() }
17+
}
18+
19+
// Make sure we don't try and complete for this type's init.
20+
struct R {
21+
init(a: Int) {}
22+
}
23+
24+
// Not applicable, A does not conform to Q.
25+
struct A: P {}
26+
extension P where Self == A {
27+
static func baz() -> A { A() }
28+
}
29+
30+
struct B<T>: P {}
31+
extension B: Q where T: Q {}
32+
33+
// Applicable, B<S> conforms to Q.
34+
extension P where Self == B<S> {
35+
static func qux() -> Self { .init() }
36+
}
37+
38+
// Not applicable, B<A> does not conform to Q.
39+
extension P where Self == B<A> {
40+
static func flim() -> Self { .init() }
41+
}
42+
43+
@attached(peer) macro R(_: any Q) = #externalMacro(module: "", type: "")
44+
45+
@R(.#^COMPLETE^#)
46+
func bar() {}
47+
// COMPLETE: Begin completions, 2 items
48+
// COMPLETE-DAG: Decl[StaticMethod]/Super/TypeRelation[Convertible]: foo()[#S#]; name=foo()
49+
// COMPLETE-DAG: Decl[StaticMethod]/Super/TypeRelation[Convertible]: qux()[#B<S>#]; name=qux()

0 commit comments

Comments
 (0)