Skip to content

Commit 2a746da

Browse files
author
Nathan Hawes
committed
[ParseableInterface] Fix failing to build a module when the importing file has errors.
We were checking the parent invocation's DiagnosticEnginer rather than the subinstance's to determine if there were any errors building the module, which meant we would fail to load the module if there were errors prior to the import statement in the importing file. This also meant code completion would fail to load the module, because it always emits a bogus error in order to mark the AST as erroneous so that different parts of the compiler (e.g. the verifier) have less strict assumptions. rdar://problem/43906499
1 parent 1e7fba7 commit 2a746da

File tree

6 files changed

+80
-1
lines changed

6 files changed

+80
-1
lines changed

lib/Frontend/ParseableInterfaceSupport.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ bool ParseableInterfaceModuleLoader::buildSwiftModuleFromSwiftInterface(
452452
return;
453453
}
454454

455-
SubError = Diags.hadAnyError();
455+
SubError = SubInstance.getDiags().hadAnyError();
456456
});
457457
return !RunSuccess || SubError;
458458
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/modulecache)
3+
//
4+
// Setup builds a parseable interface for a module SomeModule (built from some-module.swift).
5+
// This test checks we still build and load its corresponding .swiftmodule when the file that imports it contains an error prior to the import statement.
6+
7+
// Setup phase 1: Write the input file.
8+
//
9+
// RUN: echo 'public func SomeFunc() -> Int { return 42; }' >>%t/some-module.swift
10+
11+
// Setup phase 2: build the module.
12+
//
13+
// RUN: %target-swift-frontend -I %t -emit-parseable-module-interface-path %t/SomeModule.swiftinterface -module-name SomeModule %t/some-module.swift -emit-module -o /dev/null
14+
15+
// Actual test: compile and verify the import succeeds (i.e. we only report the error in this file)
16+
//
17+
// RUN: %target-swift-frontend -typecheck -verify -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface %s
18+
19+
unresolved // expected-error {{use of unresolved identifier 'unresolved'}}
20+
21+
import SomeModule
22+
23+
print(SomeFunc())
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
public struct MyPoint {
2+
public let x: Double
3+
public let y: Double
4+
5+
public init(x: Double, y: Double) {
6+
self.x = x
7+
self.y = y
8+
}
9+
10+
public var magnitudeSquared: Double {
11+
return x*x + y*y
12+
}
13+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import MyPoint
2+
3+
public extension MyPoint {
4+
var magnitude: Double {
5+
return magnitudeSquared.squareRoot()
6+
}
7+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/modulecache)
3+
4+
// 1) Build .swiftinterface files for MyPoint and MyExtensions
5+
// RUN: %target-swift-frontend -emit-parseable-module-interface-path %t/MyPoint.swiftinterface -module-name MyPoint -emit-module -o /dev/null %S/Inputs/parseable-interface/MyPoint.swift
6+
// RUN: %target-swift-frontend -emit-parseable-module-interface-path %t/MyPointExtensions.swiftinterface -module-name MyPointExtensions -emit-module -o /dev/null -enable-parseable-module-interface -module-cache-path %t/modulecache -I %t %S/Inputs/parseable-interface/MyPointExtensions.swift
7+
8+
// 2) Check completion with a warm module cache from above
9+
// RUN: %swift-ide-test_plain -code-completion -code-completion-token=MEMBER -source-filename %s -I %t -module-cache-path %t/modulecache | %FileCheck %s
10+
11+
// 3) Check completion with a cold module cache
12+
// RUN: %empty-directory(%t/modulecache)
13+
// RUN: %swift-ide-test_plain -code-completion -code-completion-token=MEMBER -source-filename %s -I %t -module-cache-path %t/modulecache | %FileCheck %s
14+
15+
import MyPoint
16+
import MyPointExtensions
17+
18+
let x = MyPoint(x: 1, y: 10.5)
19+
20+
print(x.#^MEMBER^#)
21+
22+
// CHECK: Begin completions, 5 items
23+
// CHECK: Keyword[self]/CurrNominal: self[#MyPoint#]; name=self
24+
// CHECK: Decl[InstanceVar]/CurrNominal: x[#Double#]; name=x
25+
// CHECK: Decl[InstanceVar]/CurrNominal: y[#Double#]; name=y
26+
// CHECK: Decl[InstanceVar]/CurrNominal: magnitudeSquared[#Double#]; name=magnitudeSquared
27+
// CHECK: Decl[InstanceVar]/CurrNominal: magnitude[#Double#]; name=magnitude
28+
// CHECK: End completions

tools/swift-ide-test/swift-ide-test.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,12 @@ static llvm::cl::opt<std::string>
258258
ModuleCachePath("module-cache-path", llvm::cl::desc("Clang module cache path"),
259259
llvm::cl::cat(Category));
260260

261+
static llvm::cl::opt<bool>
262+
EnableParseableModuleInterface("enable-parseable-module-interface",
263+
llvm::cl::desc("Enable loading .swiftinterface files when available"),
264+
llvm::cl::cat(Category),
265+
llvm::cl::init(true));
266+
261267
static llvm::cl::opt<std::string>
262268
PCHOutputDir("pch-output-dir",
263269
llvm::cl::desc("place autogenerated PCH files in this directory"),
@@ -3127,6 +3133,8 @@ int main(int argc, char *argv[]) {
31273133
InitInvok.getLangOptions().EffectiveLanguageVersion = actual.getValue();
31283134
}
31293135
}
3136+
InitInvok.getFrontendOptions().EnableParseableModuleInterface =
3137+
options::EnableParseableModuleInterface;
31303138
InitInvok.getClangImporterOptions().ModuleCachePath =
31313139
options::ModuleCachePath;
31323140
InitInvok.getClangImporterOptions().PrecompiledHeaderOutputDir =

0 commit comments

Comments
 (0)