Skip to content

Commit 9121b26

Browse files
authored
Merge pull request #74436 from kavon/demangling-rdar128695929
Demangler: edge case in existential demangling
2 parents e50a6c4 + 0ecf982 commit 9121b26

File tree

3 files changed

+58
-27
lines changed

3 files changed

+58
-27
lines changed

lib/AST/ASTDemangler.cpp

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -755,36 +755,53 @@ Type ASTBuilder::createExistentialMetatypeType(
755755
Type ASTBuilder::createConstrainedExistentialType(
756756
Type base, ArrayRef<BuiltRequirement> constraints,
757757
ArrayRef<BuiltInverseRequirement> inverseRequirements) {
758-
// FIXME: Generalize to other kinds of bases.
759-
if (!base->getAs<ProtocolType>())
760-
return Type();
761-
auto baseTy = base->castTo<ProtocolType>();
762-
auto baseDecl = baseTy->getDecl();
763-
llvm::SmallDenseMap<Identifier, Type> cmap;
764-
for (const auto &req : constraints) {
765-
switch (req.getKind()) {
766-
case RequirementKind::SameShape:
767-
llvm_unreachable("Same-shape requirement not supported here");
768-
case RequirementKind::Conformance:
769-
case RequirementKind::Superclass:
770-
case RequirementKind::Layout:
771-
continue;
758+
Type constrainedBase;
759+
760+
if (auto baseTy = base->getAs<ProtocolType>()) {
761+
auto baseDecl = baseTy->getDecl();
762+
llvm::SmallDenseMap<Identifier, Type> cmap;
763+
for (const auto &req : constraints) {
764+
switch (req.getKind()) {
765+
case RequirementKind::SameShape:
766+
llvm_unreachable("Same-shape requirement not supported here");
767+
case RequirementKind::Conformance:
768+
case RequirementKind::Superclass:
769+
case RequirementKind::Layout:
770+
continue;
772771

773-
case RequirementKind::SameType:
774-
if (auto *DMT = req.getFirstType()->getAs<DependentMemberType>())
775-
cmap[DMT->getName()] = req.getSecondType();
772+
case RequirementKind::SameType:
773+
if (auto *DMT = req.getFirstType()->getAs<DependentMemberType>())
774+
cmap[DMT->getName()] = req.getSecondType();
775+
}
776776
}
777-
}
778-
llvm::SmallVector<Type, 4> args;
779-
for (auto *assocTy : baseDecl->getPrimaryAssociatedTypes()) {
780-
auto argTy = cmap.find(assocTy->getName());
781-
if (argTy == cmap.end()) {
782-
return Type();
777+
llvm::SmallVector<Type, 4> args;
778+
for (auto *assocTy : baseDecl->getPrimaryAssociatedTypes()) {
779+
auto argTy = cmap.find(assocTy->getName());
780+
if (argTy == cmap.end()) {
781+
return Type();
782+
}
783+
args.push_back(argTy->getSecond());
784+
}
785+
786+
// We may not have any arguments because the constrained existential is a
787+
// plain protocol with an inverse requirement.
788+
if (args.empty()) {
789+
constrainedBase =
790+
ProtocolType::get(baseDecl, baseTy, base->getASTContext());
791+
} else {
792+
constrainedBase =
793+
ParameterizedProtocolType::get(base->getASTContext(), baseTy, args);
783794
}
784-
args.push_back(argTy->getSecond());
795+
} else if (base->isAny()) {
796+
// The only other case should be that we got an empty PCT, which is equal to
797+
// the Any type. The other constraints should have been encoded in the
798+
// existential's generic signature (and arrive as BuiltInverseRequirement).
799+
constrainedBase = base;
800+
} else {
801+
return Type();
785802
}
786-
Type constrainedBase =
787-
ParameterizedProtocolType::get(base->getASTContext(), baseTy, args);
803+
804+
assert(constrainedBase);
788805

789806
// Handle inverse requirements.
790807
if (!inverseRequirements.empty()) {

test/Interpreter/moveonly_existentials.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-build-swift %s -o %t/bin
2+
// RUN: %target-build-swift -g %s -o %t/bin
33
// RUN: %target-codesign %t/bin
44
// RUN: %target-run %t/bin | %FileCheck %s
55

test/TypeDecoder/constrained_existentials.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// RUN: %lldb-moduleimport-test %t/constrained_existentials -type-from-mangled=%t/input | %FileCheck %s --match-full-lines
66

77
func blackHole(_: Any...) {}
8+
func blackHole_noncopyable(_: consuming any ~Copyable) {}
89

910
protocol BaseProto<A, B> {
1011
associatedtype A
@@ -43,3 +44,16 @@ do {
4344

4445
blackHole(e0, e1, e2)
4546
}
47+
48+
protocol NCProto: ~Copyable {}
49+
struct NC: ~Copyable {}
50+
struct GenNC<T: ~Copyable>: ~Copyable, NCProto {}
51+
52+
do {
53+
let e0: any NCProto & ~Copyable = GenNC<NC>()
54+
let e1: any NCProto & ~Copyable = GenNC<String>()
55+
56+
// FIXME: breaks the MoveChecker (rdar://129885532)
57+
// blackHole_noncopyable(consume e0)
58+
// blackHole_noncopyable(consume e1)
59+
}

0 commit comments

Comments
 (0)