Skip to content

Commit d925bc4

Browse files
authored
Merge pull request swiftlang#85918 from hamishknight/retraction-6.3
[6.3] [Demangler] Handle invertible reqs for extensions in `findDeclContext`
2 parents 8f8dc15 + 82c1e6a commit d925bc4

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

lib/AST/ASTDemangler.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,6 +1550,17 @@ ASTBuilder::findDeclContext(NodePointer node) {
15501550
}
15511551
}
15521552

1553+
// FIXME: We shouldn't be attempting to find an exact extension match,
1554+
// clients only need the nominal for qualified lookup. Additionally, the
1555+
// module in which the extension resides is currently used to filter the
1556+
// lookup results. This means when we have multiple matches, the particular
1557+
// extension we choose matters.
1558+
//
1559+
// We ought to refactor things such that we return a module ABI name +
1560+
// nominal decl which downstream logic can use to lookup and limit results
1561+
// to only those that appear in the ABI module. Then we can delete all this
1562+
// logic.
1563+
SmallVector<ExtensionDecl *, 4> genericExts;
15531564
for (auto *ext : nominalDecl->getExtensions()) {
15541565
bool found = false;
15551566
for (ModuleDecl *module : moduleDecls) {
@@ -1588,6 +1599,39 @@ ASTBuilder::findDeclContext(NodePointer node) {
15881599
if (requirements.empty())
15891600
return ext;
15901601
}
1602+
genericExts.push_back(ext);
1603+
}
1604+
if (!genericSig)
1605+
return nullptr;
1606+
1607+
SmallVector<Requirement, 2> requirements;
1608+
SmallVector<InverseRequirement, 2> inverses;
1609+
genericSig->getRequirementsWithInverses(requirements, inverses);
1610+
1611+
// If we didn't find a result yet, try again without invertible requirements
1612+
// since `demangleGenericSignature` won't include them, e.g won't include
1613+
// Copyable for:
1614+
//
1615+
// struct S<T: ~Copyable> {}
1616+
// protocol P: ~Copyable {}
1617+
// extension S where T: P/*, T: Copyable*/ {}
1618+
//
1619+
// We do this as a separate loop to avoid disturbing existing lookup
1620+
// behavior for cases where there's an extension with matching inverses,
1621+
// since the choice of extension matters (see above FIXME).
1622+
//
1623+
// FIXME: This is a complete hack, we ought to delete all this logic and
1624+
// just return the nominal + module ABI name.
1625+
for (auto *ext : genericExts) {
1626+
auto extSig = ext->getGenericSignature().getCanonicalSignature();
1627+
if (extSig.getGenericParams() != genericSig.getGenericParams())
1628+
continue;
1629+
1630+
SmallVector<Requirement, 2> extReqs;
1631+
SmallVector<InverseRequirement, 2> extInvs;
1632+
extSig->getRequirementsWithInverses(extReqs, extInvs);
1633+
if (extReqs == requirements)
1634+
return ext;
15911635
}
15921636

15931637
return nullptr;

test/IDE/rdar165639044.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %batch-code-completion
2+
3+
struct S<T: ~Copyable> {}
4+
protocol P: ~Copyable {}
5+
6+
extension S where T: P {
7+
var bar: Int { 0 }
8+
}
9+
struct R: P {}
10+
11+
// Make sure USR round-tripping works here.
12+
func foo(_ x: S<R>) {
13+
x.#^COMPLETE^#
14+
// COMPLETE: Decl[InstanceVar]/CurrNominal: bar[#Int#]; name=bar
15+
}

test/TypeDecoder/extensions.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,19 @@ extension Generic where T: AnyObject {
5858
// DEMANGLE-DECL: $s10extensions7GenericVAARlzClE18NestedViaAnyObjectV
5959
// CHECK-DECL: extensions.(file).Generic extension.NestedViaAnyObject
6060

61+
// Invertible Constraints
62+
63+
struct GenericNonCopyable<T: ~Copyable> {}
64+
protocol ProtoNonCopyable: ~Copyable {}
65+
66+
extension GenericNonCopyable where T: ProtoNonCopyable/*, T: Copyable*/ {
67+
struct Nested {}
68+
}
69+
70+
struct NonCopyableType: ProtoNonCopyable {}
71+
72+
// DEMANGLE-DECL: $s10extensions18GenericNonCopyableVA2A05ProtocD0RzlE6NestedV
73+
// CHECK-DECL: extensions.(file).GenericNonCopyable extension.Nested
74+
75+
// DEMANGLE-TYPE: $s10extensions18GenericNonCopyableVA2A05ProtocD0RzlE6NestedVyAA0cD4TypeV_GD
76+
// CHECK-TYPE: GenericNonCopyable<NonCopyableType>.Nested

0 commit comments

Comments
 (0)