Skip to content

Commit 0ecf982

Browse files
committed
Demangler: fix demangling any ~Copyable
1 parent b604488 commit 0ecf982

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
@@ -755,47 +755,54 @@ 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());
783784
}
784-
args.push_back(argTy->getSecond());
785-
}
786-
787-
Type constrainedBase;
788785

789-
// We may not have any arguments because the constrained existential is a
790-
// plain protocol with an inverse requirement.
791-
if (args.empty()) {
792-
constrainedBase =
793-
ProtocolType::get(baseDecl, baseTy, base->getASTContext());
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);
794+
}
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;
794800
} else {
795-
constrainedBase =
796-
ParameterizedProtocolType::get(base->getASTContext(), baseTy, args);
801+
return Type();
797802
}
798803

804+
assert(constrainedBase);
805+
799806
// Handle inverse requirements.
800807
if (!inverseRequirements.empty()) {
801808
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)