Skip to content

Commit f2c13a6

Browse files
authored
Merge pull request #74437 from kavon/6.0-demangling-rdar128695929
[6.0🍒] Demangler: edge case in existential demangling
2 parents 9090471 + f7c2e16 commit f2c13a6

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
@@ -732,36 +732,53 @@ 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());
761+
}
762+
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);
760771
}
761-
args.push_back(argTy->getSecond());
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;
777+
} else {
778+
return Type();
762779
}
763-
Type constrainedBase =
764-
ParameterizedProtocolType::get(base->getASTContext(), baseTy, args);
780+
781+
assert(constrainedBase);
765782

766783
// Handle inverse requirements.
767784
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)