Skip to content

Commit f7c2e16

Browse files
committed
Demangler: fix demangling any ~Copyable
(cherry picked from commit 0ecf982)
1 parent 4cd8313 commit f7c2e16

File tree

2 files changed

+55
-34
lines changed

2 files changed

+55
-34
lines changed

lib/AST/ASTDemangler.cpp

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -732,47 +732,54 @@ Type ASTBuilder::createExistentialMetatypeType(
732732
Type ASTBuilder::createConstrainedExistentialType(
733733
Type base, ArrayRef<BuiltRequirement> constraints,
734734
ArrayRef<BuiltInverseRequirement> inverseRequirements) {
735-
// FIXME: Generalize to other kinds of bases.
736-
if (!base->getAs<ProtocolType>())
737-
return Type();
738-
auto baseTy = base->castTo<ProtocolType>();
739-
auto baseDecl = baseTy->getDecl();
740-
llvm::SmallDenseMap<Identifier, Type> cmap;
741-
for (const auto &req : constraints) {
742-
switch (req.getKind()) {
743-
case RequirementKind::SameShape:
744-
llvm_unreachable("Same-shape requirement not supported here");
745-
case RequirementKind::Conformance:
746-
case RequirementKind::Superclass:
747-
case RequirementKind::Layout:
748-
continue;
735+
Type constrainedBase;
736+
737+
if (auto baseTy = base->getAs<ProtocolType>()) {
738+
auto baseDecl = baseTy->getDecl();
739+
llvm::SmallDenseMap<Identifier, Type> cmap;
740+
for (const auto &req : constraints) {
741+
switch (req.getKind()) {
742+
case RequirementKind::SameShape:
743+
llvm_unreachable("Same-shape requirement not supported here");
744+
case RequirementKind::Conformance:
745+
case RequirementKind::Superclass:
746+
case RequirementKind::Layout:
747+
continue;
749748

750-
case RequirementKind::SameType:
751-
if (auto *DMT = req.getFirstType()->getAs<DependentMemberType>())
752-
cmap[DMT->getName()] = req.getSecondType();
749+
case RequirementKind::SameType:
750+
if (auto *DMT = req.getFirstType()->getAs<DependentMemberType>())
751+
cmap[DMT->getName()] = req.getSecondType();
752+
}
753753
}
754-
}
755-
llvm::SmallVector<Type, 4> args;
756-
for (auto *assocTy : baseDecl->getPrimaryAssociatedTypes()) {
757-
auto argTy = cmap.find(assocTy->getName());
758-
if (argTy == cmap.end()) {
759-
return Type();
754+
llvm::SmallVector<Type, 4> args;
755+
for (auto *assocTy : baseDecl->getPrimaryAssociatedTypes()) {
756+
auto argTy = cmap.find(assocTy->getName());
757+
if (argTy == cmap.end()) {
758+
return Type();
759+
}
760+
args.push_back(argTy->getSecond());
760761
}
761-
args.push_back(argTy->getSecond());
762-
}
763-
764-
Type constrainedBase;
765762

766-
// We may not have any arguments because the constrained existential is a
767-
// plain protocol with an inverse requirement.
768-
if (args.empty()) {
769-
constrainedBase =
770-
ProtocolType::get(baseDecl, baseTy, base->getASTContext());
763+
// We may not have any arguments because the constrained existential is a
764+
// plain protocol with an inverse requirement.
765+
if (args.empty()) {
766+
constrainedBase =
767+
ProtocolType::get(baseDecl, baseTy, base->getASTContext());
768+
} else {
769+
constrainedBase =
770+
ParameterizedProtocolType::get(base->getASTContext(), baseTy, args);
771+
}
772+
} else if (base->isAny()) {
773+
// The only other case should be that we got an empty PCT, which is equal to
774+
// the Any type. The other constraints should have been encoded in the
775+
// existential's generic signature (and arrive as BuiltInverseRequirement).
776+
constrainedBase = base;
771777
} else {
772-
constrainedBase =
773-
ParameterizedProtocolType::get(base->getASTContext(), baseTy, args);
778+
return Type();
774779
}
775780

781+
assert(constrainedBase);
782+
776783
// Handle inverse requirements.
777784
if (!inverseRequirements.empty()) {
778785
InvertibleProtocolSet inverseSet;

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)