@@ -360,6 +360,35 @@ extension IncrementalCompilationTests {
360360 XCTAssertFalse ( mandatoryJobInputs. contains ( " other.swift " ) )
361361 }
362362
363+ // Source file timestamps updated but contents are the same, with file-hashing emit-module job should be skipped
364+ func testNullBuildNoEmitModuleWithHashing( ) throws {
365+ let extraArguments = [ " -experimental-emit-module-separately " , " -emit-module " , " -enable-incremental-file-hashing " ]
366+ try buildInitialState ( extraArguments: extraArguments)
367+ touch ( " main " )
368+ touch ( " other " )
369+ touch ( try AbsolutePath ( validating: explicitSwiftDependenciesPath. appending ( component: " E.swiftinterface " ) . pathString) )
370+ let driver = try doABuildWithoutExpectations ( arguments: commonArgs + extraArguments + ( try XCTUnwrap ( Driver . sdkArgumentsForTesting ( ) ) ) )
371+ let mandatoryJobs = try XCTUnwrap ( driver. incrementalCompilationState? . mandatoryJobsInOrder)
372+ let mandatoryJobInputs = mandatoryJobs. flatMap { $0. inputs } . map { $0. file. basename }
373+ XCTAssertFalse ( mandatoryJobs. contains { $0. kind == . emitModule } , " emit-module should be skipped when using hashes and content unchanged " )
374+ XCTAssertFalse ( mandatoryJobInputs. contains ( " main.swift " ) )
375+ XCTAssertFalse ( mandatoryJobInputs. contains ( " other.swift " ) )
376+ }
377+
378+ // Source file updated, emit-module job should not be skipped regardless of file-hashing
379+ func testEmitModuleWithHashingWhenContentChanges( ) throws {
380+ let extraArguments = [ " -experimental-emit-module-separately " , " -emit-module " , " -enable-incremental-file-hashing " ]
381+ try buildInitialState ( extraArguments: extraArguments)
382+ replace ( contentsOf: " main " , with: " let foo = 2 " )
383+ let driver = try doABuildWithoutExpectations ( arguments: commonArgs + extraArguments + ( try XCTUnwrap ( Driver . sdkArgumentsForTesting ( ) ) ) )
384+ let mandatoryJobs = try XCTUnwrap ( driver. incrementalCompilationState? . mandatoryJobsInOrder)
385+ let mandatoryJobInputs = mandatoryJobs. flatMap { $0. inputs } . map { $0. file. basename }
386+ XCTAssertTrue ( mandatoryJobs. contains { $0. kind == . emitModule } , " emit-module should run when using hashes and content has changed " )
387+ XCTAssertTrue ( mandatoryJobInputs. contains ( " main.swift " ) )
388+ }
389+
390+
391+
363392 // External deps timestamp updated but contents are the same, and file-hashing is explicitly disabled
364393 func testExplicitIncrementalBuildExternalDepsWithoutHashing( ) throws {
365394 replace ( contentsOf: " other " , with: " import E;let bar = foo " )
0 commit comments