Skip to content

Commit 73ade1d

Browse files
authored
Merge pull request #76180 from slavapestov/fix-issue-76164
AST: Simplify ProtocolCompositionType::getMinimalCanonicalType() and remove bogus assert
2 parents f2e57d8 + 21905af commit 73ade1d

File tree

2 files changed

+17
-82
lines changed

2 files changed

+17
-82
lines changed

lib/AST/Type.cpp

Lines changed: 10 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -3808,91 +3808,19 @@ Type ProtocolCompositionType::get(const ASTContext &C,
38083808

38093809
CanType ProtocolCompositionType::getMinimalCanonicalType(
38103810
const DeclContext *useDC) const {
3811-
const CanType CanTy = getCanonicalType();
3812-
3813-
// If the canonical type is not a composition, it's minimal.
3814-
const auto Composition = dyn_cast<ProtocolCompositionType>(CanTy);
3815-
if (!Composition) {
3816-
return CanTy;
3817-
}
3818-
3819-
// Nothing to minimize.
3820-
if (Composition->getMembers().empty()) {
3821-
return CanTy;
3822-
}
3823-
3824-
// The only cases we're missing out on proper minimization is when a
3825-
// composition has an explicit superclass or AnyObject constraint.
3826-
if (!Composition->hasExplicitAnyObject() &&
3827-
!Composition->getMembers().front()->getClassOrBoundGenericClass()) {
3828-
// Already minimal.
3829-
return CanTy;
3830-
}
3831-
3832-
auto &Ctx = CanTy->getASTContext();
3811+
auto &Ctx = getASTContext();
38333812

38343813
// Use generic signature minimization: the requirements of the signature will
38353814
// represent the minimal composition.
3836-
auto sig = useDC->getGenericSignatureOfContext();
3837-
const auto Sig = Ctx.getOpenedExistentialSignature(CanTy, sig);
3838-
SmallVector<Requirement, 2> Reqs;
3839-
SmallVector<InverseRequirement, 2> Inverses;
3840-
Sig->getRequirementsWithInverses(Reqs, Inverses);
3841-
3842-
if (Reqs.size() == 1) {
3843-
return Reqs.front().getSecondType()->getCanonicalType();
3844-
}
3845-
3846-
// The set of inverses is already minimal.
3847-
auto MinimalInverses = Composition->getInverses();
3848-
3849-
#ifndef NDEBUG
3850-
// Check that the generic signature's inverses matches.
3851-
InvertibleProtocolSet genSigInverses;
3852-
for (InverseRequirement ireq : Inverses)
3853-
genSigInverses.insert(ireq.getKind());
3854-
assert(genSigInverses == MinimalInverses);
3855-
#endif
3856-
3857-
llvm::SmallVector<Type, 2> MinimalMembers;
3858-
bool MinimalHasExplicitAnyObject = false;
3859-
auto ifaceTy = Sig.getGenericParams().back();
3860-
for (const auto &Req : Reqs) {
3861-
if (!Req.getFirstType()->isEqual(ifaceTy)) {
3862-
continue;
3863-
}
3864-
3865-
switch (Req.getKind()) {
3866-
case RequirementKind::SameShape:
3867-
llvm_unreachable("Same-shape requirement not supported here");
3868-
case RequirementKind::Superclass:
3869-
case RequirementKind::Conformance:
3870-
MinimalMembers.push_back(Req.getSecondType());
3871-
break;
3872-
case RequirementKind::Layout:
3873-
MinimalHasExplicitAnyObject = true;
3874-
break;
3875-
case RequirementKind::SameType:
3876-
llvm_unreachable("");
3877-
}
3878-
}
3879-
3880-
// A superclass constraint is always retained and must appear first in the
3881-
// members list.
3882-
assert(Composition->getMembers().front()->getClassOrBoundGenericClass() ==
3883-
MinimalMembers.front()->getClassOrBoundGenericClass());
3884-
3885-
// If we are left with a single member and no layout constraint, the member
3886-
// is the minimal type. Also, note that a protocol composition cannot be
3887-
// constructed with a single member unless there is a layout constraint.
3888-
if (MinimalMembers.size() == 1
3889-
&& !MinimalHasExplicitAnyObject
3890-
&& MinimalInverses.empty())
3891-
return CanType(MinimalMembers.front());
3892-
3893-
// The resulting composition is necessarily canonical.
3894-
return CanType(build(Ctx, MinimalMembers, MinimalInverses,
3895-
MinimalHasExplicitAnyObject));
3815+
auto parentSig = useDC->getGenericSignatureOfContext();
3816+
auto existentialSig =
3817+
Ctx.getOpenedExistentialSignature(getCanonicalType(), parentSig);
3818+
auto selfTy =
3819+
OpenedArchetypeType::getSelfInterfaceTypeFromContext(parentSig, Ctx);
3820+
return existentialSig->getUpperBound(selfTy,
3821+
/*forExistentialSelf=*/true,
3822+
/*includeParameterizedProtocols=*/true)
3823+
->getCanonicalType();
38963824
}
38973825

38983826
ClangTypeInfo AnyFunctionType::getClangTypeInfo() const {

test/type/subclass_composition.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,3 +577,10 @@ struct Generic<T> {
577577
}
578578
}
579579
}
580+
581+
// https://github.com/swiftlang/swift/issues/76164
582+
protocol P5 where Self: Other {}
583+
protocol P6 {}
584+
585+
func invalidOverload(_: P5 & P6 & Other) {} // expected-note {{'invalidOverload' previously declared here}}
586+
func invalidOverload(_: P5 & P6) {} // expected-error {{invalid redeclaration of 'invalidOverload'}}

0 commit comments

Comments
 (0)