Skip to content

Commit a4e848f

Browse files
committed
RequirementMachine: New way of modeling layout requirement implied by superclass requirement
A superclass requirement implies a layout requirement. We don't want the layout requirement to be present in the minimal signature, so instead of adding a pair of requirements: T.[superclass: C<X, Y>] => T T.[layout: _NativeClass] => T Add this pair of requirements: T.[superclass: C<X, Y>] => T [superclass: C<X, Y>].[layout: _NativeClass] => [superclass: C<X, Y>] [permanent] Completion then derives the rule as a consequence: T.[layout: _NativeClass] => T Since this rule is a consequence of the other two rules, homotopy reduction will mark it redundant.
1 parent ba0fe6d commit a4e848f

File tree

5 files changed

+50
-16
lines changed

5 files changed

+50
-16
lines changed

lib/AST/RequirementMachine/RequirementMachine.cpp

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -197,29 +197,51 @@ void RewriteSystemBuilder::addRequirement(const Requirement &req,
197197
//
198198
// Together with a rewrite rule
199199
//
200-
// T.[layout: L] => T
200+
// [superclass: C<X, Y>].[layout: L] => [superclass: C<X, Y>]
201201
//
202202
// Where 'L' is either AnyObject or _NativeObject, depending on the
203203
// ancestry of C.
204+
//
205+
// The second rule is marked permanent. Completion will derive a new
206+
// rule as a consequence of these two rules:
207+
//
208+
// T.[layout: L] => T
209+
//
210+
// The new rule will be marked redundant by homotopy reduction since
211+
// it is a consequence of the other two rules.
204212
auto otherType = CanType(req.getSecondType());
205213

214+
// Build the symbol [superclass: C<X, Y>].
206215
SmallVector<Term, 1> substitutions;
207216
otherType = getConcreteSubstitutionSchema(otherType, proto,
208217
substitutions);
218+
auto superclassSymbol = Symbol::forSuperclass(otherType, substitutions,
219+
Context);
220+
221+
{
222+
// Build the symbol [layout: L].
223+
auto layout =
224+
LayoutConstraint::getLayoutConstraint(
225+
otherType->getClassOrBoundGenericClass()->usesObjCObjectModel()
226+
? LayoutConstraintKind::Class
227+
: LayoutConstraintKind::NativeClass,
228+
Context.getASTContext());
229+
auto layoutSymbol = Symbol::forLayout(layout, Context);
230+
231+
MutableTerm layoutSubjectTerm;
232+
layoutSubjectTerm.add(superclassSymbol);
233+
234+
MutableTerm layoutConstraintTerm = layoutSubjectTerm;
235+
layoutConstraintTerm.add(layoutSymbol);
236+
237+
// Add the rule [superclass: C<X, Y>].[layout: L] => [superclass: C<X, Y>].
238+
PermanentRules.emplace_back(layoutConstraintTerm,
239+
layoutSubjectTerm);
240+
}
209241

242+
// Build the term T.[superclass: C<X, Y>].
210243
constraintTerm = subjectTerm;
211-
constraintTerm.add(Symbol::forSuperclass(otherType, substitutions,
212-
Context));
213-
RequirementRules.emplace_back(subjectTerm, constraintTerm);
214-
215-
constraintTerm = subjectTerm;
216-
auto layout =
217-
LayoutConstraint::getLayoutConstraint(
218-
otherType->getClassOrBoundGenericClass()->usesObjCObjectModel()
219-
? LayoutConstraintKind::Class
220-
: LayoutConstraintKind::NativeClass,
221-
Context.getASTContext());
222-
constraintTerm.add(Symbol::forLayout(layout, Context));
244+
constraintTerm.add(superclassSymbol);
223245
break;
224246
}
225247

lib/AST/RequirementMachine/RewriteSystem.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ void RewriteSystem::verifyRewriteRules(ValidityPolicy policy) const {
521521
}
522522

523523
for (const auto &rule : Rules) {
524-
if (rule.isSimplified())
524+
if (rule.isSimplified() || rule.isPermanent())
525525
continue;
526526

527527
const auto &lhs = rule.getLHS();

test/Generics/generic_objc_superclass.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ 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: - [superclass: Generic<τ_0_0> with <τ_0_1>].[layout: AnyObject] => [superclass: Generic<τ_0_0> with <τ_0_1>] [permanent]
1617
// CHECK-NEXT: - τ_0_0.[superclass: Generic<τ_0_0> with <τ_0_1>] => τ_0_0
1718
// CHECK-NEXT: - τ_0_0.[layout: AnyObject] => τ_0_0
1819
// CHECK-NEXT: }
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=on 2>&1 | %FileCheck %s
2+
3+
class C {}
4+
5+
// CHECK: superclass_and_layout_requirement.(file).P@
6+
// CHECK: Requirement signature: <Self where Self.T : C>
7+
protocol P {
8+
associatedtype T : C
9+
}

test/Generics/unify_superclass_types_1.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ extension P where Self : Derived {
1616
// CHECK-LABEL: Requirement machine for <τ_0_0 where τ_0_0 : Derived, τ_0_0 : P>
1717
// CHECK-NEXT: Rewrite system: {
1818
// CHECK-NEXT: - [P].[P] => [P] [permanent]
19+
// CHECK-NEXT: - [superclass: Base].[layout: _NativeClass] => [superclass: Base] [permanent]
20+
// CHECK-NEXT: - [superclass: Derived].[layout: _NativeClass] => [superclass: Derived] [permanent]
1921
// CHECK-NEXT: - [P].[superclass: Base] => [P]
20-
// CHECK-NEXT: - [P].[layout: _NativeClass] => [P]
2122
// CHECK-NEXT: - τ_0_0.[superclass: Derived] => τ_0_0
22-
// CHECK-NEXT: - τ_0_0.[layout: _NativeClass] => τ_0_0
2323
// CHECK-NEXT: - τ_0_0.[P] => τ_0_0
24+
// CHECK-NEXT: - [P].[layout: _NativeClass] => [P]
25+
// CHECK-NEXT: - τ_0_0.[layout: _NativeClass] => τ_0_0
2426
// CHECK-NEXT: - τ_0_0.[superclass: Base] => τ_0_0
2527
// CHECK-NEXT: }
2628
// CHECK-NEXT: Rewrite loops: {

0 commit comments

Comments
 (0)