Skip to content

Commit cca936e

Browse files
committed
RequirementMachine: Don't consider protocol typealiases with UnboundGenericType
These are stealth generic typealiases and should not participate in the rewrite system.
1 parent c255f84 commit cca936e

File tree

3 files changed

+31
-15
lines changed

3 files changed

+31
-15
lines changed

lib/AST/RequirementMachine/RequirementLowering.cpp

+23-15
Original file line numberDiff line numberDiff line change
@@ -705,14 +705,16 @@ StructuralRequirementsRequest::evaluate(Evaluator &evaluator,
705705
// underlying type of the typealias.
706706
if (auto *typeAliasDecl = dyn_cast<TypeAliasDecl>(decl)) {
707707
if (!typeAliasDecl->isGeneric()) {
708-
// Ignore the typealias if we have an associated type with the same anme
708+
// Ignore the typealias if we have an associated type with the same name
709709
// in the same protocol. This is invalid anyway, but it's just here to
710710
// ensure that we produce the same requirement signature on some tests
711711
// with -requirement-machine-protocol-signatures=verify.
712712
if (assocTypes.contains(typeAliasDecl->getName()))
713713
continue;
714714

715715
auto underlyingType = typeAliasDecl->getStructuralType();
716+
if (underlyingType->is<UnboundGenericType>())
717+
continue;
716718

717719
auto subjectType = DependentMemberType::get(
718720
selfTy, typeAliasDecl->getName());
@@ -752,6 +754,20 @@ TypeAliasRequirementsRequest::evaluate(Evaluator &evaluator,
752754
(ctx.LangOpts.RequirementMachineProtocolSignatures ==
753755
RequirementMachineMode::Enabled);
754756

757+
auto getStructuralType = [](TypeDecl *typeDecl) -> Type {
758+
if (auto typealias = dyn_cast<TypeAliasDecl>(typeDecl)) {
759+
if (typealias->getUnderlyingTypeRepr() != nullptr) {
760+
auto type = typealias->getStructuralType();
761+
if (auto *aliasTy = cast<TypeAliasType>(type.getPointer()))
762+
return aliasTy->getSinglyDesugaredType();
763+
return type;
764+
}
765+
return typealias->getUnderlyingType();
766+
}
767+
768+
return typeDecl->getDeclaredInterfaceType();
769+
};
770+
755771
// Collect all typealiases from inherited protocols recursively.
756772
llvm::MapVector<Identifier, TinyPtrVector<TypeDecl *>> inheritedTypeDecls;
757773
for (auto *inheritedProto : ctx.getRewriteContext().getInheritedProtocols(proto)) {
@@ -762,25 +778,17 @@ TypeAliasRequirementsRequest::evaluate(Evaluator &evaluator,
762778
if (genReq->getGenericParams())
763779
continue;
764780

781+
// Ignore typealiases with UnboundGenericType, since they
782+
// are like generic typealiases.
783+
if (auto *typeAlias = dyn_cast<TypeAliasDecl>(req))
784+
if (getStructuralType(typeAlias)->is<UnboundGenericType>())
785+
continue;
786+
765787
inheritedTypeDecls[typeReq->getName()].push_back(typeReq);
766788
}
767789
}
768790
}
769791

770-
auto getStructuralType = [](TypeDecl *typeDecl) -> Type {
771-
if (auto typealias = dyn_cast<TypeAliasDecl>(typeDecl)) {
772-
if (typealias->getUnderlyingTypeRepr() != nullptr) {
773-
auto type = typealias->getStructuralType();
774-
if (auto *aliasTy = cast<TypeAliasType>(type.getPointer()))
775-
return aliasTy->getSinglyDesugaredType();
776-
return type;
777-
}
778-
return typealias->getUnderlyingType();
779-
}
780-
781-
return typeDecl->getDeclaredInterfaceType();
782-
};
783-
784792
// An inferred same-type requirement between the two type declarations
785793
// within this protocol or a protocol it inherits.
786794
auto recordInheritedTypeRequirement = [&](TypeDecl *first, TypeDecl *second) {

lib/AST/RequirementMachine/Symbol.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ struct Symbol::Storage final
7878
Storage(Symbol::Kind kind, CanType type, ArrayRef<Term> substitutions) {
7979
assert(kind == Symbol::Kind::Superclass ||
8080
kind == Symbol::Kind::ConcreteType);
81+
assert(!type->hasUnboundGenericType());
8182
assert(!type->hasTypeVariable());
8283
assert(type->hasTypeParameter() != substitutions.empty());
8384

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
protocol P {
4+
typealias A = Array
5+
6+
associatedtype X where X == A // expected-error {{reference to generic type 'Self.A' (aka 'Array') requires arguments in <...>}}
7+
}

0 commit comments

Comments
 (0)