Skip to content

Commit af87fce

Browse files
author
David Ungar
committed
When tracing uses, include the implicit use of implementation when interface changes
1 parent 9080611 commit af87fce

File tree

5 files changed

+22
-23
lines changed

5 files changed

+22
-23
lines changed

Sources/SwiftDriver/Incremental Compilation/DependencyKey.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,10 @@ public struct DependencyKey: Hashable, CustomStringConvertible {
9494
}
9595

9696

97-
var correspondingImplementation: Self {
98-
assert(aspect == .interface)
97+
var correspondingImplementation: Self? {
98+
guard aspect == .interface else {
99+
return nil
100+
}
99101
return Self(aspect: .implementation, designator: designator)
100102
}
101103

Sources/SwiftDriver/Incremental Compilation/ModuleDependencyGraph Parts/NodeFinder.swift

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ extension ModuleDependencyGraph.NodeFinder {
4747
func findNode(_ mapKey: (Graph.SwiftDeps?, DependencyKey)) -> Graph.Node? {
4848
nodeMap[mapKey]
4949
}
50+
func findCorrespondingImplementation(of n: Graph.Node) -> Graph.Node? {
51+
n.dependencyKey.correspondingImplementation
52+
.flatMap {findNode((n.swiftDeps, $0))}
53+
}
5054

5155
func findNodes(for swiftDeps: Graph.SwiftDeps?) -> [DependencyKey: Graph.Node]? {
5256
nodeMap[swiftDeps]
@@ -55,21 +59,18 @@ extension ModuleDependencyGraph.NodeFinder {
5559
nodeMap[key]
5660
}
5761

58-
/// Since uses must be somewhere, pass inthe swiftDeps to the function here
59-
func forEachUse(_ fn: (DependencyKey, Graph.Node, Graph.SwiftDeps) -> Void) {
60-
usesByDef.forEach {
61-
def, use in
62-
fn(def, use, useMustHaveSwiftDeps(use))
62+
func forEachUse(of def: Graph.Node, _ fn: (Graph.Node, Graph.SwiftDeps) -> Void) {
63+
func fnVerifyingSwiftDeps(_ use: Graph.Node) {
64+
fn(use, useMustHaveSwiftDeps(use))
6365
}
64-
}
65-
func forEachUse(of def: DependencyKey, _ fn: (Graph.Node, Graph.SwiftDeps) -> Void) {
66-
usesByDef[def].map {
67-
$0.values.forEach { use in
68-
fn(use, useMustHaveSwiftDeps(use))
69-
}
66+
usesByDef[def.dependencyKey].map {
67+
$0.values.forEach(fnVerifyingSwiftDeps)
7068
}
69+
// Add in implicit interface->implementation dependency
70+
findCorrespondingImplementation(of: def)
71+
.map(fnVerifyingSwiftDeps)
7172
}
72-
73+
7374
func mappings(of n: Graph.Node) -> [(Graph.SwiftDeps?, DependencyKey)]
7475
{
7576
nodeMap.compactMap {

Sources/SwiftDriver/Incremental Compilation/ModuleDependencyGraph Parts/Tracer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ extension ModuleDependencyGraph.Tracer {
8383
let pathLengthAfterArrival = traceArrival(at: definition);
8484

8585
// If this use also provides something, follow it
86-
graph.nodeFinder.forEachUse(of: definition.dependencyKey) { use, _ in
86+
graph.nodeFinder.forEachUse(of: definition) { use, _ in
8787
findNextPreviouslyUntracedDependent(of: use)
8888
}
8989
traceDeparture(pathLengthAfterArrival);

Sources/SwiftDriver/Incremental Compilation/ModuleDependencyGraph.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ extension ModuleDependencyGraph {
171171
) {
172172
// These nodes will depend on the *interface* of the external Decl.
173173
let key = DependencyKey(interfaceFor: externalSwiftDeps)
174-
nodeFinder.forEachUse(of: key) { use, useSwiftDeps in
174+
let node = Node(key: key, fingerprint: nil, swiftDeps: nil)
175+
nodeFinder.forEachUse(of: node) { use, useSwiftDeps in
175176
if isUntraced(use) {
176177
fn(useSwiftDeps)
177178
}

Tests/SwiftDriverTests/ModuleDependencyGraphTests.swift

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,7 @@ class ModuleDependencyGraphTests: XCTestCase {
136136
}
137137
XCTAssertTrue(graph.haveAnyNodesBeenTraversed(inMock: 0))
138138
XCTAssertTrue(graph.haveAnyNodesBeenTraversed(inMock: 1))
139-
do {
140-
let swiftDeps = graph.findSwiftDepsToRecompileWhenWholeSwiftDepsChanges(0)
141-
XCTAssertEqual(1, swiftDeps.count)
142-
XCTAssertTrue(swiftDeps.contains(0))
143-
}
139+
144140
XCTAssertEqual(0, graph.findSwiftDepsToRecompileWhenWholeSwiftDepsChanges(0).count)
145141
XCTAssertTrue(graph.haveAnyNodesBeenTraversed(inMock: 0))
146142
XCTAssertTrue(graph.haveAnyNodesBeenTraversed(inMock: 1))
@@ -1058,8 +1054,7 @@ fileprivate struct SourceFileDependencyGraphMocker {
10581054
if case .sourceFileProvide = interfaceKey.designator, !allNodes.isEmpty {
10591055
return getSourceFileNodePair()
10601056
}
1061-
assert(interfaceKey.aspect == .interface)
1062-
let implementationKey = interfaceKey.correspondingImplementation
1057+
let implementationKey = try! XCTUnwrap(interfaceKey.correspondingImplementation)
10631058
let nodePair = NodePair(
10641059
interface: findExistingNodeOrCreateIfNew(interfaceKey, fingerprint,
10651060
isProvides: true),

0 commit comments

Comments
 (0)