Skip to content

Commit 7ee772b

Browse files
authored
Merge pull request #64323 from tshortli/avoid-adding-implicit-import-during-override-checking
Sema: Only add implicit imports to module interface during resilience typechecking
2 parents d637362 + b36b946 commit 7ee772b

File tree

3 files changed

+92
-24
lines changed

3 files changed

+92
-24
lines changed

lib/AST/Module.cpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3115,21 +3115,6 @@ RestrictedImportKind SourceFile::getRestrictedImportKind(const ModuleDecl *modul
31153115
if (imports.isImportedBy(module, getParentModule()))
31163116
return RestrictedImportKind::None;
31173117

3118-
if (importKind == RestrictedImportKind::MissingImport &&
3119-
(module->getLibraryLevel() == LibraryLevel::API ||
3120-
getParentModule()->getLibraryLevel() != LibraryLevel::API)) {
3121-
// Hack to fix swiftinterfaces in case of missing imports.
3122-
// We can get rid of this logic when we don't leak the use of non-locally
3123-
// imported things in API.
3124-
ImportPath::Element pathElement = {module->getName(), SourceLoc()};
3125-
auto pathArray = getASTContext().AllocateCopy(
3126-
llvm::makeArrayRef(pathElement));
3127-
auto missingImport = ImportedModule(
3128-
ImportPath::Access(pathArray),
3129-
const_cast<ModuleDecl *>(module));
3130-
addMissingImportedModule(missingImport);
3131-
}
3132-
31333118
return importKind;
31343119
}
31353120

lib/Sema/ResilienceDiagnostics.cpp

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,27 @@
2828

2929
using namespace swift;
3030

31+
static bool addMissingImport(SourceLoc loc, const Decl *D,
32+
const ExportContext &where) {
33+
ASTContext &ctx = where.getDeclContext()->getASTContext();
34+
ModuleDecl *M = D->getModuleContext();
35+
auto *SF = where.getDeclContext()->getParentSourceFile();
36+
37+
// Only add imports of API level modules if this is an API level module.
38+
if (M->getLibraryLevel() != LibraryLevel::API &&
39+
SF->getParentModule()->getLibraryLevel() == LibraryLevel::API)
40+
return false;
41+
42+
// Hack to fix swiftinterfaces in case of missing imports. We can get rid of
43+
// this logic when we don't leak the use of non-locally imported things in
44+
// API.
45+
auto missingImport = ImportedModule(ImportPath::Access(),
46+
const_cast<ModuleDecl *>(M));
47+
SF->addMissingImportedModule(missingImport);
48+
ctx.Diags.diagnose(loc, diag::missing_import_inserted, M->getName());
49+
return true;
50+
}
51+
3152
bool TypeChecker::diagnoseInlinableDeclRefAccess(SourceLoc loc,
3253
const ValueDecl *D,
3354
const ExportContext &where) {
@@ -184,8 +205,7 @@ static bool diagnoseTypeAliasDeclRefExportability(SourceLoc loc,
184205

185206
if (originKind == DisallowedOriginKind::MissingImport &&
186207
!ctx.LangOpts.isSwiftVersionAtLeast(6))
187-
ctx.Diags.diagnose(loc, diag::missing_import_inserted,
188-
definingModule->getName());
208+
addMissingImport(loc, D, where);
189209

190210
return true;
191211
}
@@ -202,7 +222,7 @@ static bool diagnoseValueDeclRefExportability(SourceLoc loc, const ValueDecl *D,
202222
if (originKind == DisallowedOriginKind::None)
203223
return false;
204224

205-
ASTContext &ctx = definingModule->getASTContext();
225+
ASTContext &ctx = where.getDeclContext()->getASTContext();
206226

207227
auto fragileKind = where.getFragileFunctionKind();
208228
auto reason = where.getExportabilityReason();
@@ -236,8 +256,7 @@ static bool diagnoseValueDeclRefExportability(SourceLoc loc, const ValueDecl *D,
236256

237257
if (originKind == DisallowedOriginKind::MissingImport &&
238258
downgradeToWarning == DowngradeToWarning::Yes)
239-
ctx.Diags.diagnose(loc, diag::missing_import_inserted,
240-
definingModule->getName());
259+
addMissingImport(loc, D, where);
241260
}
242261

243262
return true;
@@ -296,9 +315,9 @@ TypeChecker::diagnoseConformanceExportability(SourceLoc loc,
296315
originKind == DisallowedOriginKind::MissingImport,
297316
6);
298317

299-
if (originKind == DisallowedOriginKind::MissingImport &&
300-
!ctx.LangOpts.isSwiftVersionAtLeast(6))
301-
ctx.Diags.diagnose(loc, diag::missing_import_inserted,
302-
M->getName());
318+
if (originKind == DisallowedOriginKind::MissingImport &&
319+
!ctx.LangOpts.isSwiftVersionAtLeast(6))
320+
addMissingImport(loc, ext, where);
321+
303322
return true;
304323
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-emit-module-interface(%t/DefinesProtocol.swiftinterface) -I %t %t/DefinesProtocol.swift -module-name DefinesProtocol
5+
// RUN: %target-swift-typecheck-module-from-interface(%t/DefinesProtocol.swiftinterface) -I %t -module-name DefinesProtocol
6+
7+
// RUN: %target-swift-emit-module-interface(%t/DefinesTypealias.swiftinterface) -I %t %t/DefinesTypealias.swift -module-name DefinesTypealias
8+
// RUN: %target-swift-typecheck-module-from-interface(%t/DefinesTypealias.swiftinterface) -I %t -module-name DefinesTypealias
9+
10+
// RUN: %target-swift-emit-module-interface(%t/DefinesStruct.swiftinterface) -I %t %t/DefinesStruct.swift -module-name DefinesStruct
11+
// RUN: %target-swift-typecheck-module-from-interface(%t/DefinesStruct.swiftinterface) -I %t -module-name DefinesStruct
12+
13+
// RUN: %target-swift-emit-module-interface(%t/DefinesExtension.swiftinterface) -I %t %t/DefinesExtension.swift -module-name DefinesExtension
14+
// RUN: %target-swift-typecheck-module-from-interface(%t/DefinesExtension.swiftinterface) -I %t -module-name DefinesExtension
15+
16+
// RUN: %target-swift-emit-module-interface(%t/Client.swiftinterface) -verify -I %t %t/File2.swift %t/File1.swift -module-name Client
17+
// RUN: %target-swift-typecheck-module-from-interface(%t/Client.swiftinterface) -I %t -module-name Client
18+
// RUN: %FileCheck %t/File2.swift < %t/Client.swiftinterface
19+
20+
//--- DefinesProtocol.swift
21+
22+
public protocol P {}
23+
24+
//--- DefinesTypealias.swift
25+
26+
import DefinesProtocol
27+
28+
public typealias Q = P
29+
30+
//--- DefinesStruct.swift
31+
32+
public struct C {}
33+
34+
//--- DefinesExtension.swift
35+
36+
import DefinesStruct
37+
38+
extension C {
39+
public func foo() {}
40+
}
41+
42+
//--- File1.swift
43+
44+
import DefinesExtension
45+
46+
//--- File2.swift
47+
48+
// CHECK: import DefinesExtension
49+
// CHECK-NEXT: import DefinesProtocol
50+
// CHECK-NEXT: import DefinesStruct
51+
// CHECK-NEXT: import DefinesTypealias
52+
53+
import DefinesTypealias
54+
import DefinesStruct
55+
56+
public func takesQ<T>(_ b: T) where T: Q { }
57+
// expected-warning @-1 {{'Q' aliases 'DefinesProtocol.P' and cannot be used here because 'DefinesProtocol' was not imported by this file; this is an error in Swift 6}}
58+
// expected-note @-2 {{The missing import of module 'DefinesProtocol' will be added implicitly}}
59+
60+
@inlinable public func takesC(_ c: C) {
61+
c.foo()
62+
// expected-warning @-1 {{instance method 'foo()' cannot be used in an '@inlinable' function because 'DefinesExtension' was not imported by this file; this is an error in Swift 6}}
63+
// expected-note @-2 {{The missing import of module 'DefinesExtension' will be added implicitly}}
64+
}

0 commit comments

Comments
 (0)