Skip to content

Commit 413da3a

Browse files
committed
RequirementMachine: Skip protocol type aliases that contain unbound dependent member types
In the below, 'Self.A.A' is not a type parameter; rather, since 'Self.A' is concretely known to be 'S', we resolve it as 'S.A', which performs a name lookup and finds the concrete type alias 'A': public struct S { public typealias A = Int } public protocol P { typealias A = S } public struct G<T> {} public protocol Q: P { typealias B = G<Self.A.A> } This is fine, but such a type alias should not participate in the rewrite system. Let's exclude them like any other invalid requirement. The type alias itself is not an error; however, it is an error to use it from a 'where' clause requirement. This is not diagnosed yet, though. Fixes rdar://136686001.
1 parent 5af7e0d commit 413da3a

File tree

4 files changed

+53
-12
lines changed

4 files changed

+53
-12
lines changed

lib/AST/RequirementMachine/HomotopyReduction.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -611,10 +611,11 @@ GenericSignatureErrors RewriteSystem::getErrors() const {
611611
if (!isInMinimizationDomain(rule.getLHS().getRootProtocol()))
612612
continue;
613613

614-
if (!rule.isRedundant() &&
615-
!rule.isProtocolTypeAliasRule() &&
616-
rule.containsNameSymbols())
617-
result |= GenericSignatureErrorFlags::HasInvalidRequirements;
614+
if (!rule.isRedundant()) {
615+
if (!rule.isProtocolTypeAliasRule() &&
616+
rule.containsNameSymbols())
617+
result |= GenericSignatureErrorFlags::HasInvalidRequirements;
618+
}
618619

619620
if (rule.isRecursive())
620621
result |= GenericSignatureErrorFlags::HasInvalidRequirements;
@@ -624,12 +625,9 @@ GenericSignatureErrors RewriteSystem::getErrors() const {
624625
if (property->getKind() == Symbol::Kind::ConcreteConformance)
625626
result |= GenericSignatureErrorFlags::HasConcreteConformances;
626627

627-
if (property->hasSubstitutions()) {
628-
for (auto t : property->getSubstitutions()) {
629-
if (t.containsNameSymbols())
630-
result |= GenericSignatureErrorFlags::HasInvalidRequirements;
631-
}
632-
}
628+
if (property->hasSubstitutions() &&
629+
property->containsNameSymbols())
630+
result |= GenericSignatureErrorFlags::HasInvalidRequirements;
633631
}
634632
}
635633
}
@@ -661,10 +659,20 @@ RewriteSystem::getMinimizedProtocolRules() const {
661659
if (!isInMinimizationDomain(proto))
662660
continue;
663661

664-
if (rule.isProtocolTypeAliasRule())
662+
if (rule.isProtocolTypeAliasRule()) {
663+
if (auto property = rule.isPropertyRule()) {
664+
if (property->containsNameSymbols())
665+
continue;
666+
} else if (rule.getRHS().containsNameSymbols()) {
667+
continue;
668+
}
665669
rules[proto].TypeAliases.push_back(ruleID);
666-
else if (!rule.containsNameSymbols())
670+
} else {
671+
if (rule.containsNameSymbols())
672+
continue;
673+
667674
rules[proto].Requirements.push_back(ruleID);
675+
}
668676
}
669677

670678
return rules;

lib/AST/RequirementMachine/Symbol.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,15 @@ Symbol Symbol::transformConcreteSubstitutions(
686686
return withConcreteSubstitutions(substitutions, ctx);
687687
}
688688

689+
bool Symbol::containsNameSymbols() const {
690+
for (auto t : getSubstitutions()) {
691+
if (t.containsNameSymbols())
692+
return true;
693+
}
694+
695+
return false;
696+
}
697+
689698
/// Print the symbol using our mnemonic representation.
690699
void Symbol::dump(llvm::raw_ostream &out) const {
691700
llvm::DenseMap<CanType, Identifier> substitutionNames;

lib/AST/RequirementMachine/Symbol.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,8 @@ class Symbol final {
242242
const MutableTerm &prefix,
243243
RewriteContext &ctx) const;
244244

245+
bool containsNameSymbols() const;
246+
245247
void dump(llvm::raw_ostream &out) const;
246248

247249
friend bool operator==(Symbol lhs, Symbol rhs) {

test/Generics/rdar136686001.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %target-typecheck-verify-swift
2+
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures 2>&1 | %FileCheck %s
3+
4+
public struct S {
5+
public typealias A = Int
6+
}
7+
8+
public protocol P {
9+
typealias A = S
10+
}
11+
12+
public struct G<T> {}
13+
14+
public protocol Q: P {
15+
typealias B = G<Self.A.A>
16+
}
17+
18+
// FIXME: This should be diagnosed as an error.
19+
20+
// CHECK-LABEL: rdar136686001.(file).f@
21+
// CHECK-NEXT: Generic signature: <T, U where T : Q>
22+
public func f<T: Q, U>(_: T, _: U) where T.B == U {}

0 commit comments

Comments
 (0)