Skip to content

Commit b1a6f45

Browse files
authored
reduce usage of fatalError (#3107)
* reduce usage of fatalError motivation: less crashes changes: * make InternalError assert on construction * replace fatalError with InternalError where possible * reduce usage of forded `try!` * adjust downstream code to newly throwing functions * backwards compatibility for APIs used by libSwiftPM clients
1 parent 04a83a0 commit b1a6f45

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+596
-514
lines changed

Sources/Basics/Errors.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
public struct InternalError: Error {
1212
private let description: String
1313
public init(_ description: String) {
14-
self.description = description
14+
assertionFailure(description)
15+
self.description = "Internal error. Please file a bug at https://bugs.swift.org with this info. \(description)"
1516
}
1617
}

Sources/Build/BuildPlan.swift

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
99
*/
1010

11+
import Basics
1112
import TSCBasic
1213
import TSCUtility
1314
import PackageModel
@@ -679,7 +680,7 @@ public final class SwiftTargetBuildDescription {
679680
return args
680681
}
681682

682-
public func emitCommandLine() -> [String] {
683+
public func emitCommandLine() throws -> [String] {
683684
var result: [String] = []
684685
result.append(buildParameters.toolchain.swiftCompiler.pathString)
685686

@@ -695,7 +696,7 @@ public final class SwiftTargetBuildDescription {
695696

696697
result.append("-output-file-map")
697698
// FIXME: Eliminate side effect.
698-
result.append(try! writeOutputFileMap().pathString)
699+
result.append(try writeOutputFileMap().pathString)
699700

700701
switch target.type {
701702
case .library, .test:
@@ -719,7 +720,7 @@ public final class SwiftTargetBuildDescription {
719720
result.append("-I")
720721
result.append(buildParameters.buildPath.pathString)
721722

722-
result += compileArguments()
723+
result += self.compileArguments()
723724
return result
724725
}
725726

@@ -773,7 +774,7 @@ public final class SwiftTargetBuildDescription {
773774
/// Command-line for emitting the object files.
774775
///
775776
/// Note: This doesn't emit the module.
776-
public func emitObjectsCommandLine() -> [String] {
777+
public func emitObjectsCommandLine() throws -> [String] {
777778
assert(buildParameters.emitSwiftModuleSeparately)
778779

779780
var result: [String] = []
@@ -786,7 +787,7 @@ public final class SwiftTargetBuildDescription {
786787

787788
result.append("-output-file-map")
788789
// FIXME: Eliminate side effect.
789-
result.append(try! writeOutputFileMap().pathString)
790+
result.append(try writeOutputFileMap().pathString)
790791

791792
if target.type == .library || target.type == .test {
792793
result.append("-parse-as-library")
@@ -1056,7 +1057,7 @@ public final class ProductBuildDescription {
10561057
}
10571058

10581059
/// The arguments to link and create this product.
1059-
public func linkArguments() -> [String] {
1060+
public func linkArguments() throws -> [String] {
10601061
var args = [buildParameters.toolchain.swiftCompiler.pathString]
10611062
args += buildParameters.toolchain.extraSwiftCFlags
10621063
args += buildParameters.sanitizers.linkSwiftFlags()
@@ -1439,9 +1440,9 @@ public class BuildPlan {
14391440
for buildTarget in targets {
14401441
switch buildTarget {
14411442
case .swift(let target):
1442-
try plan(swiftTarget: target)
1443+
try self.plan(swiftTarget: target)
14431444
case .clang(let target):
1444-
plan(clangTarget: target)
1445+
try self.plan(clangTarget: target)
14451446
}
14461447
}
14471448

@@ -1457,7 +1458,7 @@ public class BuildPlan {
14571458
/// Plan a product.
14581459
private func plan(_ buildProduct: ProductBuildDescription) throws {
14591460
// Compute the product's dependency.
1460-
let dependencies = computeDependencies(of: buildProduct.product)
1461+
let dependencies = try computeDependencies(of: buildProduct.product)
14611462

14621463
// Add flags for system targets.
14631464
for systemModule in dependencies.systemModules {
@@ -1525,7 +1526,7 @@ public class BuildPlan {
15251526
/// Computes the dependencies of a product.
15261527
private func computeDependencies(
15271528
of product: ResolvedProduct
1528-
) -> (
1529+
) throws -> (
15291530
dylibs: [ResolvedProduct],
15301531
staticTargets: [ResolvedTarget],
15311532
systemModules: [ResolvedTarget],
@@ -1534,7 +1535,7 @@ public class BuildPlan {
15341535

15351536
// Sort the product targets in topological order.
15361537
let nodes: [ResolvedTarget.Dependency] = product.targets.map { .target($0, conditions: []) }
1537-
let allTargets = try! topologicalSort(nodes, successors: { dependency in
1538+
let allTargets = try topologicalSort(nodes, successors: { dependency in
15381539
switch dependency {
15391540
// Include all the depenencies of a target.
15401541
case .target(let target, _):
@@ -1603,8 +1604,8 @@ public class BuildPlan {
16031604
}
16041605

16051606
/// Plan a Clang target.
1606-
private func plan(clangTarget: ClangTargetBuildDescription) {
1607-
for case .target(let dependency, _) in clangTarget.target.recursiveDependencies(satisfying: buildEnvironment) {
1607+
private func plan(clangTarget: ClangTargetBuildDescription) throws {
1608+
for case .target(let dependency, _) in try clangTarget.target.recursiveDependencies(satisfying: buildEnvironment) {
16081609
switch dependency.underlyingTarget {
16091610
case is SwiftTarget:
16101611
if case let .swift(dependencyTargetDescription)? = targetMap[dependency] {
@@ -1642,7 +1643,7 @@ public class BuildPlan {
16421643
private func plan(swiftTarget: SwiftTargetBuildDescription) throws {
16431644
// We need to iterate recursive dependencies because Swift compiler needs to see all the targets a target
16441645
// depends on.
1645-
for case .target(let dependency, _) in swiftTarget.target.recursiveDependencies(satisfying: buildEnvironment) {
1646+
for case .target(let dependency, _) in try swiftTarget.target.recursiveDependencies(satisfying: buildEnvironment) {
16461647
switch dependency.underlyingTarget {
16471648
case let underlyingTarget as ClangTarget where underlyingTarget.type == .library:
16481649
guard case let .clang(target)? = targetMap[dependency] else {

Sources/Build/ManifestBuilder.swift

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import LLBuildManifest
1212

13+
import Basics
1314
import TSCBasic
1415
import TSCUtility
1516

@@ -67,9 +68,9 @@ public class LLBuildManifestBuilder {
6768
for (_, description) in plan.targetMap {
6869
switch description {
6970
case .swift(let desc):
70-
try createSwiftCompileCommand(desc)
71+
try self.createSwiftCompileCommand(desc)
7172
case .clang(let desc):
72-
createClangCompileCommand(desc)
73+
try self.createClangCompileCommand(desc)
7374
}
7475
}
7576
}
@@ -78,7 +79,7 @@ public class LLBuildManifestBuilder {
7879

7980
// Create command for all products in the plan.
8081
for (_, description) in plan.productMap {
81-
createProductCommand(description)
82+
try self.createProductCommand(description)
8283
}
8384

8485
// Output a dot graph
@@ -188,23 +189,23 @@ extension LLBuildManifestBuilder {
188189
_ target: SwiftTargetBuildDescription
189190
) throws {
190191
// Inputs.
191-
let inputs = computeSwiftCompileCmdInputs(target)
192+
let inputs = try self.computeSwiftCompileCmdInputs(target)
192193

193194
// Outputs.
194195
let objectNodes = target.objects.map(Node.file)
195196
let moduleNode = Node.file(target.moduleOutputPath)
196197
let cmdOutputs = objectNodes + [moduleNode]
197198

198199
if buildParameters.useIntegratedSwiftDriver {
199-
try addSwiftCmdsViaIntegratedDriver(target, inputs: inputs, objectNodes: objectNodes, moduleNode: moduleNode)
200+
try self.addSwiftCmdsViaIntegratedDriver(target, inputs: inputs, objectNodes: objectNodes, moduleNode: moduleNode)
200201
} else if buildParameters.emitSwiftModuleSeparately {
201-
addSwiftCmdsEmitSwiftModuleSeparately(target, inputs: inputs, objectNodes: objectNodes, moduleNode: moduleNode)
202+
try self.addSwiftCmdsEmitSwiftModuleSeparately(target, inputs: inputs, objectNodes: objectNodes, moduleNode: moduleNode)
202203
} else {
203-
addCmdWithBuiltinSwiftTool(target, inputs: inputs, cmdOutputs: cmdOutputs)
204+
self.addCmdWithBuiltinSwiftTool(target, inputs: inputs, cmdOutputs: cmdOutputs)
204205
}
205206

206-
addTargetCmd(target, cmdOutputs: cmdOutputs)
207-
addModuleWrapCmd(target)
207+
self.addTargetCmd(target, cmdOutputs: cmdOutputs)
208+
self.addModuleWrapCmd(target)
208209
}
209210

210211
private func addSwiftCmdsViaIntegratedDriver(
@@ -215,7 +216,7 @@ extension LLBuildManifestBuilder {
215216
) throws {
216217
// Use the integrated Swift driver to compute the set of frontend
217218
// jobs needed to build this Swift target.
218-
var commandLine = target.emitCommandLine();
219+
var commandLine = try target.emitCommandLine();
219220
commandLine.append("-driver-use-frontend-path")
220221
commandLine.append(buildParameters.toolchain.swiftCompiler.pathString)
221222
// FIXME: At some point SwiftPM should provide its own executor for
@@ -243,8 +244,8 @@ extension LLBuildManifestBuilder {
243244
let commandLine = try job.commandLine.map{ try resolver.resolve($0) }
244245
let arguments = [tool] + commandLine
245246

246-
let jobInputs = job.inputs.map { $0.resolveToNode() }
247-
let jobOutputs = job.outputs.map { $0.resolveToNode() }
247+
let jobInputs = try job.inputs.map { try $0.resolveToNode() }
248+
let jobOutputs = try job.outputs.map { try $0.resolveToNode() }
248249

249250
// Add target dependencies as inputs to the main module build command.
250251
//
@@ -310,7 +311,7 @@ extension LLBuildManifestBuilder {
310311
let nodes: [ResolvedTarget.Dependency] = plan.targetMap.keys.map {
311312
ResolvedTarget.Dependency.target($0, conditions: [])
312313
}
313-
let allPackageDependencies = try! topologicalSort(nodes, successors: { $0.dependencies })
314+
let allPackageDependencies = try topologicalSort(nodes, successors: { $0.dependencies })
314315

315316
// All modules discovered so far as a part of this package manifest.
316317
// This includes modules that correspond to the package's own targets, package dependency
@@ -339,14 +340,14 @@ extension LLBuildManifestBuilder {
339340
continue
340341
}
341342
guard let description = plan.targetMap[target] else {
342-
fatalError("Expected description for target \(target)")
343+
throw InternalError("Expected description for target \(target)")
343344
}
344345
switch description {
345346
case .swift(let desc):
346-
try createExplicitSwiftTargetCompileCommand(description: desc,
347-
discoveredModulesMap: &discoveredModulesMap)
347+
try self.createExplicitSwiftTargetCompileCommand(description: desc,
348+
discoveredModulesMap: &discoveredModulesMap)
348349
case .clang(let desc):
349-
createClangCompileCommand(desc)
350+
try self.createClangCompileCommand(desc)
350351
}
351352
}
352353
}
@@ -356,7 +357,7 @@ extension LLBuildManifestBuilder {
356357
discoveredModulesMap: inout SwiftDriver.ModuleInfoMap
357358
) throws {
358359
// Inputs.
359-
let inputs = computeSwiftCompileCmdInputs(description)
360+
let inputs = try self.computeSwiftCompileCmdInputs(description)
360361

361362
// Outputs.
362363
let objectNodes = description.objects.map(Node.file)
@@ -367,8 +368,8 @@ extension LLBuildManifestBuilder {
367368
try addExplicitBuildSwiftCmds(description, inputs: inputs,
368369
discoveredModulesMap: &discoveredModulesMap)
369370

370-
addTargetCmd(description, cmdOutputs: cmdOutputs)
371-
addModuleWrapCmd(description)
371+
self.addTargetCmd(description, cmdOutputs: cmdOutputs)
372+
self.addModuleWrapCmd(description)
372373
}
373374

374375
private func addExplicitBuildSwiftCmds(
@@ -379,12 +380,12 @@ extension LLBuildManifestBuilder {
379380
// Pass the driver its external dependencies (target dependencies)
380381
var dependencyModulePathMap: SwiftDriver.ExternalTargetModulePathMap = [:]
381382
// Collect paths for target dependencies of this target (direct and transitive)
382-
collectTargetDependencyModulePaths(for: targetDescription.target,
383-
dependencyModulePathMap: &dependencyModulePathMap)
383+
self.collectTargetDependencyModulePaths(for: targetDescription.target,
384+
dependencyModulePathMap: &dependencyModulePathMap)
384385

385386
// Compute the set of frontend
386387
// jobs needed to build this Swift target.
387-
var commandLine = targetDescription.emitCommandLine();
388+
var commandLine = try targetDescription.emitCommandLine();
388389
commandLine.append("-driver-use-frontend-path")
389390
commandLine.append(buildParameters.toolchain.swiftCompiler.pathString)
390391
commandLine.append("-experimental-explicit-module-build")
@@ -401,7 +402,7 @@ extension LLBuildManifestBuilder {
401402
// Save the path to the target's module to be used by its dependents
402403
// Save the dependency graph of this target to be used by its dependents
403404
guard let dependencyGraph = driver.interModuleDependencyGraph else {
404-
fatalError("Expected module dependency graph for target: \(targetDescription)")
405+
throw InternalError("Expected module dependency graph for target: \(targetDescription)")
405406
}
406407
try InterModuleDependencyGraph.mergeModules(from: dependencyGraph,
407408
into: &discoveredModulesMap)
@@ -450,7 +451,7 @@ extension LLBuildManifestBuilder {
450451
inputs: [Node],
451452
objectNodes: [Node],
452453
moduleNode: Node
453-
) {
454+
) throws {
454455
// FIXME: We need to ingest the emitted dependencies.
455456

456457
manifest.addShellCmd(
@@ -467,7 +468,7 @@ extension LLBuildManifestBuilder {
467468
description: "Compiling module \(target.target.name)",
468469
inputs: inputs,
469470
outputs: objectNodes,
470-
args: target.emitObjectsCommandLine()
471+
args: try target.emitObjectsCommandLine()
471472
)
472473
}
473474

@@ -498,7 +499,7 @@ extension LLBuildManifestBuilder {
498499

499500
private func computeSwiftCompileCmdInputs(
500501
_ target: SwiftTargetBuildDescription
501-
) -> [Node] {
502+
) throws -> [Node] {
502503
var inputs = target.sources.map(Node.file)
503504

504505
// Add resources node as the input to the target. This isn't great because we
@@ -509,7 +510,7 @@ extension LLBuildManifestBuilder {
509510
inputs.append(resourcesNode)
510511
}
511512

512-
func addStaticTargetInputs(_ target: ResolvedTarget) {
513+
func addStaticTargetInputs(_ target: ResolvedTarget) throws {
513514
// Ignore C Modules.
514515
if target.underlyingTarget is SystemLibraryTarget { return }
515516
// Ignore Binary Modules.
@@ -535,14 +536,14 @@ extension LLBuildManifestBuilder {
535536
inputs.append(file: object)
536537
}
537538
case nil:
538-
fatalError("unexpected: target \(target) not in target map \(plan.targetMap)")
539+
throw InternalError("unexpected: target \(target) not in target map \(plan.targetMap)")
539540
}
540541
}
541542

542543
for dependency in target.target.dependencies(satisfying: buildEnvironment) {
543544
switch dependency {
544545
case .target(let target, _):
545-
addStaticTargetInputs(target)
546+
try addStaticTargetInputs(target)
546547

547548
case .product(let product, _):
548549
switch product.type {
@@ -553,7 +554,7 @@ extension LLBuildManifestBuilder {
553554
// For automatic and static libraries, add their targets as static input.
554555
case .library(.automatic), .library(.static):
555556
for target in product.targets {
556-
addStaticTargetInputs(target)
557+
try addStaticTargetInputs(target)
557558
}
558559

559560
case .test:
@@ -618,7 +619,7 @@ extension LLBuildManifestBuilder {
618619
/// Create a llbuild target for a Clang target description.
619620
private func createClangCompileCommand(
620621
_ target: ClangTargetBuildDescription
621-
) {
622+
) throws {
622623
let standards = [
623624
(target.clangTarget.cxxLanguageStandard, SupportedLanguageExtension.cppExtensions),
624625
(target.clangTarget.cLanguageStandard, SupportedLanguageExtension.cExtensions),
@@ -688,7 +689,7 @@ extension LLBuildManifestBuilder {
688689

689690
args += ["-c", path.source.pathString, "-o", path.object.pathString]
690691

691-
let clangCompiler = try! buildParameters.toolchain.getClangCompiler().pathString
692+
let clangCompiler = try buildParameters.toolchain.getClangCompiler().pathString
692693
args.insert(clangCompiler, at: 0)
693694

694695
let objectFileNode: Node = .file(path.object)
@@ -753,7 +754,7 @@ extension LLBuildManifestBuilder {
753754
// MARK:- Product Command
754755

755756
extension LLBuildManifestBuilder {
756-
private func createProductCommand(_ buildProduct: ProductBuildDescription) {
757+
private func createProductCommand(_ buildProduct: ProductBuildDescription) throws {
757758
let cmdName = buildProduct.product.getCommandName(config: buildConfig)
758759

759760
// Create archive tool for static library and shell tool for rest of the products.
@@ -771,7 +772,7 @@ extension LLBuildManifestBuilder {
771772
description: "Linking \(buildProduct.binary.prettyPath())",
772773
inputs: inputs.map(Node.file),
773774
outputs: [.file(buildProduct.binary)],
774-
args: buildProduct.linkArguments()
775+
args: try buildProduct.linkArguments()
775776
)
776777
}
777778

@@ -854,15 +855,15 @@ extension LLBuildManifestBuilder {
854855
extension TypedVirtualPath {
855856
/// Resolve a typed virtual path provided by the Swift driver to
856857
/// a node in the build graph.
857-
func resolveToNode() -> Node {
858+
func resolveToNode() throws -> Node {
858859
if let absolutePath = file.absolutePath {
859860
return Node.file(absolutePath)
860861
} else if let relativePath = file.relativePath {
861862
return Node.file(localFileSystem.currentWorkingDirectory!.appending(relativePath))
862863
} else if let temporaryFileName = file.temporaryFileName {
863864
return Node.virtual(temporaryFileName.pathString)
864865
} else {
865-
fatalError("Cannot resolve VirtualPath: \(file)")
866+
throw InternalError("Cannot resolve VirtualPath: \(file)")
866867
}
867868
}
868869
}

0 commit comments

Comments
 (0)