Skip to content

Commit 8a0dcbf

Browse files
author
David Ungar
authored
Merge pull request #586 from davidungar/only-warn-on-prior-write-error
[Incremental] Only warn if cannot write prior module dependencies, and print more error info
2 parents 7bae787 + 6fa330b commit 8a0dcbf

File tree

5 files changed

+52
-29
lines changed

5 files changed

+52
-29
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -988,10 +988,7 @@ extension Driver {
988988
if !childJobs.isEmpty {
989989
do {
990990
defer {
991-
self.incrementalCompilationState?.writeDependencyGraph()
992-
buildRecordInfo?.writeBuildRecord(
993-
jobs,
994-
incrementalCompilationState?.skippedCompilationInputs)
991+
writeIncrementalBuildInformation(jobs)
995992
}
996993
try performTheBuild(allJobs: childJobs,
997994
jobExecutionDelegate: toolExecutionDelegate,
@@ -1055,6 +1052,27 @@ extension Driver {
10551052
recordedInputModificationDates: recordedInputModificationDates)
10561053
}
10571054

1055+
private func writeIncrementalBuildInformation(_ jobs: [Job]) {
1056+
// In case the write fails, don't crash the build.
1057+
// A mitigation to rdar://76359678.
1058+
// If the write fails, import incrementality is lost, but it is not a fatal error.
1059+
if let incrementalCompilationState = self.incrementalCompilationState {
1060+
do {
1061+
try incrementalCompilationState.writeDependencyGraph()
1062+
}
1063+
catch {
1064+
diagnosticEngine.emit(
1065+
.warning("next compile won't be incremental; could not write dependency graph: \(error.localizedDescription)"))
1066+
/// Ensure that a bogus dependency graph is not used next time.
1067+
buildRecordInfo?.removeBuildRecord()
1068+
return
1069+
}
1070+
}
1071+
buildRecordInfo?.writeBuildRecord(
1072+
jobs,
1073+
incrementalCompilationState?.skippedCompilationInputs)
1074+
}
1075+
10581076
private func printBindings(_ job: Job) {
10591077
stdoutStream <<< #"# ""# <<< targetTriple.triple
10601078
stdoutStream <<< #"" - ""# <<< job.tool.basename

Sources/SwiftDriver/IncrementalCompilation/BuildRecordInfo.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,13 @@ import SwiftOptions
184184
}
185185
}
186186

187+
func removeBuildRecord() {
188+
guard let absPath = buildRecordPath.absolutePath else {
189+
return
190+
}
191+
try? fileSystem.removeFileTree(absPath)
192+
}
193+
187194
/// Before writing to the dependencies file path, preserve any previous file
188195
/// that may have been there. No error handling -- this is just a nicety, it
189196
/// doesn't matter if it fails.

Sources/SwiftDriver/IncrementalCompilation/IncrementalCompilationState.swift

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,6 @@ extension Diagnostic.Message {
223223
fileprivate static func remark_incremental_compilation(because why: String) -> Diagnostic.Message {
224224
.remark("Incremental compilation: \(why)")
225225
}
226-
227-
fileprivate static var warning_could_not_write_dependency_graph: Diagnostic.Message {
228-
.warning("next compile won't be incremental; could not write dependency graph")
229-
}
230226
}
231227

232228
// MARK: - Scheduling the 2nd wave
@@ -496,23 +492,32 @@ extension IncrementalCompilationState {
496492
// MARK: - Serialization
497493

498494
extension IncrementalCompilationState {
499-
@_spi(Testing) public func writeDependencyGraph() {
495+
enum WriteDependencyGraphError: LocalizedError {
496+
case noBuildRecordInfo,
497+
couldNotWrite(path: VirtualPath, error: Error)
498+
var errorDescription: String? {
499+
switch self {
500+
case .noBuildRecordInfo:
501+
return "No build record information"
502+
case let .couldNotWrite(path, error):
503+
return "Could not write to \(path), error: \(error.localizedDescription)"
504+
}
505+
}
506+
}
507+
@_spi(Testing) public func writeDependencyGraph() throws {
500508
// If the cross-module build is not enabled, the status quo dictates we
501509
// not emit this file.
502510
guard moduleDependencyGraph.info.isCrossModuleIncrementalBuildEnabled else {
503511
return
504512
}
505-
506513
guard
507514
let recordInfo = self.driver.buildRecordInfo
508515
else {
509-
self.driver.diagnosticEngine.emit(
510-
.warning_could_not_write_dependency_graph)
511-
return
516+
throw WriteDependencyGraphError.noBuildRecordInfo
512517
}
513-
self.moduleDependencyGraph.write(to: recordInfo.dependencyGraphPath,
514-
on: self.driver.fileSystem,
515-
compilerVersion: recordInfo.actualSwiftVersion)
518+
try self.moduleDependencyGraph.write(to: recordInfo.dependencyGraphPath,
519+
on: self.driver.fileSystem,
520+
compilerVersion: recordInfo.actualSwiftVersion)
516521
}
517522
}
518523

Sources/SwiftDriver/IncrementalCompilation/ModuleDependencyGraph.swift

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -663,19 +663,21 @@ extension ModuleDependencyGraph {
663663
/// - fileSystem: The file system for this location.
664664
/// - compilerVersion: A string containing version information for the
665665
/// driver used to create this file.
666+
/// - Returns: true if had error
666667
@_spi(Testing) public func write(
667668
to path: VirtualPath,
668669
on fileSystem: FileSystem,
669670
compilerVersion: String
670-
) {
671+
) throws {
671672
let data = ModuleDependencyGraph.Serializer.serialize(self, compilerVersion)
672673

673674
do {
674675
try fileSystem.writeFileContents(path,
675676
bytes: data,
676677
atomically: true)
677-
} catch let e {
678-
info.diagnosticEngine.emit(.error_could_not_write_dep_graph(to: path, error: e))
678+
} catch {
679+
throw IncrementalCompilationState.WriteDependencyGraphError.couldNotWrite(
680+
path: path, error: error)
679681
}
680682
}
681683

@@ -1034,15 +1036,6 @@ fileprivate extension DependencyKey.Designator {
10341036
}
10351037
}
10361038

1037-
extension Diagnostic.Message {
1038-
fileprivate static func error_could_not_write_dep_graph(
1039-
to path: VirtualPath,
1040-
error: Swift.Error
1041-
) -> Diagnostic.Message {
1042-
.error("could not write driver dependency graph to \(path). Returned error was: \(error)")
1043-
}
1044-
}
1045-
10461039
// MARK: - Checking Serialization
10471040

10481041
extension ModuleDependencyGraph {

Tests/SwiftDriverTests/DependencyGraphSerializationTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class DependencyGraphSerializationTests: XCTestCase {
1818
func roundTrip(_ graph: ModuleDependencyGraph) throws {
1919
let mockPath = VirtualPath.absolute(AbsolutePath("/module-dependency-graph"))
2020
let fs = InMemoryFileSystem()
21-
graph.write(to: mockPath, on: fs, compilerVersion: "Swift 99")
21+
try graph.write(to: mockPath, on: fs, compilerVersion: "Swift 99")
2222

2323
let deserializedGraph = try ModuleDependencyGraph.read(from: mockPath,
2424
info: .mock(fileSystem: fs))!

0 commit comments

Comments
 (0)