Skip to content

Commit 5404754

Browse files
committed
RequirementMachine: More concise printed output for concrete type and superclass symbols
Types cannot contain Terms, so the Symbol representation uses GenericTypeParameterTypes whose index refers to an array of "substitution" Terms. We can (ab)use the PrintOptions.AlternateTypeNames mechanism to print those GenericTypeParamTypes as if they were Terms.
1 parent e7f3381 commit 5404754

10 files changed

+51
-49
lines changed

lib/AST/RequirementMachine/Symbol.cpp

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -637,23 +637,25 @@ Symbol Symbol::transformConcreteSubstitutions(
637637

638638
/// Print the symbol using our mnemonic representation.
639639
void Symbol::dump(llvm::raw_ostream &out) const {
640-
auto dumpSubstitutions = [&]() {
641-
if (getSubstitutions().size() > 0) {
642-
out << " with <";
643-
644-
bool first = true;
645-
for (auto substitution : getSubstitutions()) {
646-
if (first) {
647-
first = false;
648-
} else {
649-
out << ", ";
650-
}
651-
substitution.dump(out);
652-
}
640+
llvm::DenseMap<CanType, Identifier> substitutionNames;
641+
if (hasSubstitutions()) {
642+
auto &ctx = getConcreteType()->getASTContext();
643+
644+
for (unsigned index : indices(getSubstitutions())) {
645+
Term substitution = getSubstitutions()[index];
646+
647+
std::string s;
648+
llvm::raw_string_ostream os(s);
649+
os << substitution;
653650

654-
out << ">";
651+
auto key = CanType(GenericTypeParamType::get(
652+
/*isTypeSequence=*/false, 0, index, ctx));
653+
substitutionNames[key] = ctx.getIdentifier(s);
655654
}
656-
};
655+
}
656+
657+
PrintOptions opts;
658+
opts.AlternativeTypeNames = &substitutionNames;
657659

658660
switch (getKind()) {
659661
case Kind::Name:
@@ -680,20 +682,20 @@ void Symbol::dump(llvm::raw_ostream &out) const {
680682
return;
681683

682684
case Kind::Superclass:
683-
out << "[superclass: " << getConcreteType();
684-
dumpSubstitutions();
685+
out << "[superclass: ";
686+
getConcreteType().print(out, opts);
685687
out << "]";
686688
return;
687689

688690
case Kind::ConcreteType:
689-
out << "[concrete: " << getConcreteType();
690-
dumpSubstitutions();
691+
out << "[concrete: ";
692+
getConcreteType().print(out, opts);
691693
out << "]";
692694
return;
693695

694696
case Kind::ConcreteConformance:
695-
out << "[concrete: " << getConcreteType();
696-
dumpSubstitutions();
697+
out << "[concrete: ";
698+
getConcreteType().print(out, opts);
697699
out << " : ";
698700
out << getProtocol()->getName();
699701
out << "]";

test/Generics/generic_objc_superclass.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ func foo<T : Generic<U>, U>(_: T, _: U) {
1313

1414
// CHECK-LABEL: Requirement machine for <τ_0_0, τ_0_1 where τ_0_0 : Generic<τ_0_1>>
1515
// CHECK-NEXT: Rewrite system: {
16-
// CHECK-NEXT: - τ_0_0.[superclass: Generic<τ_0_0> with <τ_0_1>] => τ_0_0
16+
// CHECK-NEXT: - τ_0_0.[superclass: Generic<τ_0_1>] => τ_0_0
1717
// CHECK-NEXT: - τ_0_0.[layout: AnyObject] => τ_0_0
1818
// CHECK-NEXT: }
1919
// CHECK: Property map: {
20-
// CHECK-NEXT: τ_0_0 => { layout: AnyObject superclass: [superclass: Generic<τ_0_0> with <τ_0_1>] }
20+
// CHECK-NEXT: τ_0_0 => { layout: AnyObject superclass: [superclass: Generic<τ_0_1>] }
2121
// CHECK-NEXT: }

test/Generics/infinite_concrete_type.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
class G<T> {}
44

55
protocol P1 { // expected-error {{cannot build rewrite system for protocol; concrete nesting limit exceeded}}
6-
// expected-note@-1 {{failed rewrite rule is [P1:A].[concrete: G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<τ_0_0>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> with <[P1:A]>] => [P1:A]}}
6+
// expected-note@-1 {{failed rewrite rule is [P1:A].[concrete: G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<G<[P1:A]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] => [P1:A]}}
77
associatedtype A where A == G<B>
88
associatedtype B where B == G<A>
99
}

test/Generics/non_confluent.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ struct S<U : P1> : P1 {
4545

4646
protocol P3 {
4747
// expected-error@-1 {{cannot build rewrite system for protocol; rule length limit exceeded}}
48-
// expected-note@-2 {{failed rewrite rule is [P3:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[concrete: S<S<S<S<S<S<S<S<S<S<S<S<τ_0_0>>>>>>>>>>>> with <[P3:U]>] => [P3:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T]}}
48+
// expected-note@-2 {{failed rewrite rule is [P3:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[concrete: S<S<S<S<S<S<S<S<S<S<S<S<[P3:U]>>>>>>>>>>>>] => [P3:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T].[P1:T]}}
4949

5050
associatedtype T : P1 where T == S<U>
5151
// expected-error@-1 {{type 'Self.U' does not conform to protocol 'P1'}}

test/Generics/unify_concrete_types_1.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct MergeTest<G : P1 & P2> {
2525
// CHECK: - τ_0_0.[P2:Z2] => τ_0_0.[P1:Z1]
2626
// CHECK: }
2727
// CHECK-LABEL: Property map: {
28-
// CHECK: [P1:X] => { concrete_type: [concrete: Foo<τ_0_0, τ_0_1> with <[P1:Y1], [P1:Z1]>] }
29-
// CHECK: [P2:X] => { concrete_type: [concrete: Foo<τ_0_0, τ_0_1> with <[P2:Y2], [P2:Z2]>] }
28+
// CHECK: [P1:X] => { concrete_type: [concrete: Foo<[P1:Y1], [P1:Z1]>] }
29+
// CHECK: [P2:X] => { concrete_type: [concrete: Foo<[P2:Y2], [P2:Z2]>] }
3030
// CHECK: τ_0_0 => { conforms_to: [P1 P2] }
3131
// CHECK: }

test/Generics/unify_nested_types_2.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct G<T : P1 & P2> {}
2525
// CHECK-LABEL: Adding generic signature <τ_0_0 where τ_0_0 : P1, τ_0_0 : P2> {
2626
// CHECK-LABEL: Rewrite system: {
2727
// CHECK: - [P1:T].T => [P1:T].[P1:T]
28-
// CHECK: - τ_0_0.[P1:T].[concrete: X<τ_0_0> with <τ_0_0.[P2:U]>] => τ_0_0.[P1:T]
28+
// CHECK: - τ_0_0.[P1:T].[concrete: X<τ_0_0.[P2:U]>] => τ_0_0.[P1:T]
2929
// CHECK: - τ_0_0.[P1:T].[P1:T] => τ_0_0.[P1:T]
3030
// CHECK: }
3131
// CHECK: }

test/Generics/unify_nested_types_3.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ struct G<T : P2a & P3a> {}
2828

2929
// CHECK-LABEL: Requirement machine for <τ_0_0 where τ_0_0 : P2a, τ_0_0 : P3a>
3030
// CHECK-LABEL: Rewrite system: {
31-
// CHECK: - τ_0_0.[P2a:T].[concrete: X<τ_0_0> with <τ_0_0.[P3a:U]>] => τ_0_0.[P2a:T]
32-
// CHECK: - τ_0_0.[P2a:T].[P2:T].[concrete: X<τ_0_0> with <τ_0_0.[P3a:U].[P1:T]>] => τ_0_0.[P2a:T].[P2:T]
31+
// CHECK: - τ_0_0.[P2a:T].[concrete: X<τ_0_0.[P3a:U]>] => τ_0_0.[P2a:T]
32+
// CHECK: - τ_0_0.[P2a:T].[P2:T].[concrete: X<τ_0_0.[P3a:U].[P1:T]>] => τ_0_0.[P2a:T].[P2:T]
3333
// CHECK: }
3434
// CHECK-LABEL: Property map: {
35-
// CHECK: τ_0_0.[P2a:T] => { conforms_to: [P2] concrete_type: [concrete: X<τ_0_0> with <τ_0_0.[P3a:U]>] }
36-
// CHECK: τ_0_0.[P2a:T].[P2:T] => { concrete_type: [concrete: X<τ_0_0> with <τ_0_0.[P3a:U].[P1:T]>] }
35+
// CHECK: τ_0_0.[P2a:T] => { conforms_to: [P2] concrete_type: [concrete: X<τ_0_0.[P3a:U]>] }
36+
// CHECK: τ_0_0.[P2a:T].[P2:T] => { concrete_type: [concrete: X<τ_0_0.[P3a:U].[P1:T]>] }
3737
// CHECK: }
3838
// CHECK: }

test/Generics/unify_superclass_types_2.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ func unifySuperclassTest<T : P1 & P2>(_: T) {
3131
// CHECK-LABEL: Requirement machine for <τ_0_0 where τ_0_0 : P1, τ_0_0 : P2>
3232
// CHECK-NEXT: Rewrite system: {
3333
// CHECK: - τ_0_0.[P2:X] => τ_0_0.[P1:X]
34-
// CHECK: - τ_0_0.[P1:X].[superclass: Generic<τ_0_0, String, τ_0_1> with <τ_0_0.[P2:A2], τ_0_0.[P2:B2]>] => τ_0_0.[P1:X]
35-
// CHECK: - τ_0_0.[P1:X].[superclass: Generic<Int, String, τ_0_0> with <τ_0_0.[P1:B1]>] => τ_0_0.[P1:X]
34+
// CHECK: - τ_0_0.[P1:X].[superclass: Generic<τ_0_0.[P2:A2], String, τ_0_0.[P2:B2]>] => τ_0_0.[P1:X]
35+
// CHECK: - τ_0_0.[P1:X].[superclass: Generic<Int, String, τ_0_0.[P1:B1]>] => τ_0_0.[P1:X]
3636
// CHECK: - τ_0_0.[P1:A1].[concrete: String] => τ_0_0.[P1:A1]
3737
// CHECK: - τ_0_0.[P2:A2].[concrete: Int] => τ_0_0.[P2:A2]
3838
// CHECK: - τ_0_0.[P2:B2] => τ_0_0.[P1:B1]
@@ -41,10 +41,10 @@ func unifySuperclassTest<T : P1 & P2>(_: T) {
4141
// CHECK: Property map: {
4242
// CHECK-NEXT: [P1] => { conforms_to: [P1] }
4343
// CHECK-NEXT: [P2] => { conforms_to: [P2] }
44-
// CHECK-NEXT: [P1:X] => { layout: _NativeClass superclass: [superclass: Generic<Int, τ_0_0, τ_0_1> with <[P1:A1], [P1:B1]>] }
45-
// CHECK-NEXT: [P2:X] => { layout: _NativeClass superclass: [superclass: Generic<τ_0_0, String, τ_0_1> with <[P2:A2], [P2:B2]>] }
44+
// CHECK-NEXT: [P1:X] => { layout: _NativeClass superclass: [superclass: Generic<Int, [P1:A1], [P1:B1]>] }
45+
// CHECK-NEXT: [P2:X] => { layout: _NativeClass superclass: [superclass: Generic<[P2:A2], String, [P2:B2]>] }
4646
// CHECK-NEXT: τ_0_0 => { conforms_to: [P1 P2] }
47-
// CHECK-NEXT: τ_0_0.[P1:X] => { layout: _NativeClass superclass: [superclass: Generic<Int, String, τ_0_0> with <τ_0_0.[P1:B1]>] }
47+
// CHECK-NEXT: τ_0_0.[P1:X] => { layout: _NativeClass superclass: [superclass: Generic<Int, String, τ_0_0.[P1:B1]>] }
4848
// CHECK-NEXT: τ_0_0.[P1:A1] => { concrete_type: [concrete: String] }
4949
// CHECK-NEXT: τ_0_0.[P2:A2] => { concrete_type: [concrete: Int] }
5050
// CHECK-NEXT: }

test/Generics/unify_superclass_types_3.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ func unifySuperclassTest<T : P1 & P2>(_: T) {
3535
// CHECK: - τ_0_0.[P2:X] => τ_0_0.[P1:X]
3636
// CHECK: - [P1:X].[layout: _NativeClass] => [P1:X]
3737
// CHECK: - [P2:X].[layout: _NativeClass] => [P2:X]
38-
// CHECK: - τ_0_0.[P1:X].[superclass: Generic<Int, τ_0_0, τ_0_1> with <τ_0_0.[P1:A1], τ_0_0.[P1:B1]>] => τ_0_0.[P1:X]
39-
// CHECK: - τ_0_0.[P1:X].[superclass: Generic<Int, String, τ_0_0> with <τ_0_0.[P1:B1]>] => τ_0_0.[P1:X]
38+
// CHECK: - τ_0_0.[P1:X].[superclass: Generic<Int, τ_0_0.[P1:A1], τ_0_0.[P1:B1]>] => τ_0_0.[P1:X]
39+
// CHECK: - τ_0_0.[P1:X].[superclass: Generic<Int, String, τ_0_0.[P1:B1]>] => τ_0_0.[P1:X]
4040
// CHECK: - τ_0_0.[P2:A2].[concrete: Int] => τ_0_0.[P2:A2]
4141
// CHECK: - τ_0_0.[P2:B2] => τ_0_0.[P1:B1]
4242
// CHECK: - τ_0_0.[P1:A1].[concrete: String] => τ_0_0.[P1:A1]
@@ -45,10 +45,10 @@ func unifySuperclassTest<T : P1 & P2>(_: T) {
4545
// CHECK: Property map: {
4646
// CHECK-NEXT: [P1] => { conforms_to: [P1] }
4747
// CHECK-NEXT: [P2] => { conforms_to: [P2] }
48-
// CHECK-NEXT: [P1:X] => { layout: _NativeClass superclass: [superclass: Derived<τ_0_0, τ_0_1> with <[P1:A1], [P1:B1]>] }
49-
// CHECK-NEXT: [P2:X] => { layout: _NativeClass superclass: [superclass: Generic<τ_0_0, String, τ_0_1> with <[P2:A2], [P2:B2]>] }
48+
// CHECK-NEXT: [P1:X] => { layout: _NativeClass superclass: [superclass: Derived<[P1:A1], [P1:B1]>] }
49+
// CHECK-NEXT: [P2:X] => { layout: _NativeClass superclass: [superclass: Generic<[P2:A2], String, [P2:B2]>] }
5050
// CHECK-NEXT: τ_0_0 => { conforms_to: [P1 P2] }
51-
// CHECK-NEXT: τ_0_0.[P1:X] => { layout: _NativeClass superclass: [superclass: Derived<τ_0_0, τ_0_1> with <τ_0_0.[P1:A1], τ_0_0.[P1:B1]>] }
51+
// CHECK-NEXT: τ_0_0.[P1:X] => { layout: _NativeClass superclass: [superclass: Derived<τ_0_0.[P1:A1], τ_0_0.[P1:B1]>] }
5252
// CHECK-NEXT: τ_0_0.[P2:A2] => { concrete_type: [concrete: Int] }
5353
// CHECK-NEXT: τ_0_0.[P1:A1] => { concrete_type: [concrete: String] }
5454
// CHECK-NEXT: }

test/Generics/unify_superclass_types_4.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,22 @@ func unifySuperclassTest<T : P1 & P2>(_: T) {
3535

3636
// CHECK-LABEL: Requirement machine for <τ_0_0 where τ_0_0 : P1, τ_0_0 : P2>
3737
// CHECK-NEXT: Rewrite system: {
38-
// CHECK: - [P1:X].[superclass: Base<τ_0_0> with <[P1:A1]>] => [P1:X] [explicit]
39-
// CHECK: - [P2:X].[superclass: Derived<τ_0_0> with <[P2:A2]>] => [P2:X] [explicit]
38+
// CHECK: - [P1:X].[superclass: Base<[P1:A1]>] => [P1:X] [explicit]
39+
// CHECK: - [P2:X].[superclass: Derived<[P2:A2]>] => [P2:X] [explicit]
4040
// CHECK: - τ_0_0.[P2:X] => τ_0_0.[P1:X]
41-
// CHECK: - τ_0_0.[P1:X].[superclass: Derived<τ_0_0> with <τ_0_0.[P2:A2]>] => τ_0_0.[P1:X]
41+
// CHECK: - τ_0_0.[P1:X].[superclass: Derived<τ_0_0.[P2:A2]>] => τ_0_0.[P1:X]
4242
// CHECK: - [P1:X].[layout: _NativeClass] => [P1:X]
4343
// CHECK: - [P2:X].[layout: _NativeClass] => [P2:X]
44-
// CHECK: - τ_0_0.[P1:X].[superclass: Base<τ_0_0> with <τ_0_0.[P2:A2].[Q:T]>] => τ_0_0.[P1:X]
44+
// CHECK: - τ_0_0.[P1:X].[superclass: Base<τ_0_0.[P2:A2].[Q:T]>] => τ_0_0.[P1:X]
4545
// CHECK: - τ_0_0.[P2:A2].[Q:T] => τ_0_0.[P1:A1]
4646
// CHECK-NEXT: }
4747
// CHECK: Property map: {
4848
// CHECK-NEXT: [P1] => { conforms_to: [P1] }
4949
// CHECK-NEXT: [P2] => { conforms_to: [P2] }
5050
// CHECK-NEXT: [Q] => { conforms_to: [Q] }
51-
// CHECK-NEXT: [P1:X] => { layout: _NativeClass superclass: [superclass: Base<τ_0_0> with <[P1:A1]>] }
51+
// CHECK-NEXT: [P1:X] => { layout: _NativeClass superclass: [superclass: Base<[P1:A1]>] }
5252
// CHECK-NEXT: [P2:A2] => { conforms_to: [Q] }
53-
// CHECK-NEXT: [P2:X] => { layout: _NativeClass superclass: [superclass: Derived<τ_0_0> with <[P2:A2]>] }
53+
// CHECK-NEXT: [P2:X] => { layout: _NativeClass superclass: [superclass: Derived<[P2:A2]>] }
5454
// CHECK-NEXT: τ_0_0 => { conforms_to: [P1 P2] }
55-
// CHECK-NEXT: τ_0_0.[P1:X] => { layout: _NativeClass superclass: [superclass: Derived<τ_0_0> with <τ_0_0.[P2:A2]>] }
55+
// CHECK-NEXT: τ_0_0.[P1:X] => { layout: _NativeClass superclass: [superclass: Derived<τ_0_0.[P2:A2]>] }
5656
// CHECK-NEXT: }

0 commit comments

Comments
 (0)