Skip to content

Commit da4b28d

Browse files
authored
Merge pull request #36512 from DougGregor/isolation-inference-fallthrough
[Concurrency] Don't let "unsafe" inference block other inference.
2 parents 8eaa034 + 72bf30b commit da4b28d

File tree

9 files changed

+64
-34
lines changed

9 files changed

+64
-34
lines changed

include/swift/AST/DiagnosticEngine.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,10 @@ namespace swift {
740740
/// Path to diagnostic documentation directory.
741741
std::string diagnosticDocumentationPath = "";
742742

743+
/// Whether we are actively pretty-printing a declaration as part of
744+
/// diagnostics.
745+
bool IsPrettyPrintingDecl = false;
746+
743747
friend class InFlightDiagnostic;
744748
friend class DiagnosticTransaction;
745749
friend class CompoundDiagnosticTransaction;
@@ -796,6 +800,8 @@ namespace swift {
796800
return diagnosticDocumentationPath;
797801
}
798802

803+
bool isPrettyPrintingDecl() const { return IsPrettyPrintingDecl; }
804+
799805
void setLocalization(std::string locale, std::string path) {
800806
assert(!locale.empty());
801807
assert(!path.empty());

lib/AST/DiagnosticEngine.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,8 @@ DiagnosticEngine::diagnosticInfoForDiagnostic(const Diagnostic &diagnostic) {
10391039
// Pretty-print the declaration we've picked.
10401040
llvm::raw_svector_ostream out(buffer);
10411041
TrackingPrinter printer(entries, out, bufferAccessLevel);
1042+
llvm::SaveAndRestore<bool> isPrettyPrinting(
1043+
IsPrettyPrintingDecl, true);
10421044
ppDecl->print(
10431045
printer,
10441046
PrintOptions::printForDiagnostics(

lib/ClangImporter/ClangImporter.cpp

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,7 +1366,7 @@ bool ClangImporter::Implementation::importHeader(
13661366
// to correct. The fix would be explicitly importing on the command line.
13671367
if (implicitImport && !allParsedDecls.empty() &&
13681368
BridgingHeaderExplicitlyRequested) {
1369-
SwiftContext.Diags.diagnose(
1369+
diagnose(
13701370
diagLoc, diag::implicit_bridging_header_imported_from_module,
13711371
llvm::sys::path::filename(headerName), adapter->getName());
13721372
}
@@ -1401,8 +1401,7 @@ bool ClangImporter::Implementation::importHeader(
14011401

14021402
// FIXME: What do we do if there was already an error?
14031403
if (!hadError && clangDiags.hasErrorOccurred()) {
1404-
SwiftContext.Diags.diagnose(diagLoc, diag::bridging_header_error,
1405-
headerName);
1404+
diagnose(diagLoc, diag::bridging_header_error, headerName);
14061405
return true;
14071406
}
14081407

@@ -1450,8 +1449,7 @@ bool ClangImporter::importBridgingHeader(StringRef header, ModuleDecl *adapter,
14501449
clang::FileManager &fileManager = Impl.Instance->getFileManager();
14511450
auto headerFile = fileManager.getFile(header, /*OpenFile=*/true);
14521451
if (!headerFile) {
1453-
Impl.SwiftContext.Diags.diagnose(diagLoc, diag::bridging_header_missing,
1454-
header);
1452+
Impl.diagnose(diagLoc, diag::bridging_header_missing, header);
14551453
return true;
14561454
}
14571455

@@ -1519,8 +1517,7 @@ std::string ClangImporter::getBridgingHeaderContents(StringRef headerPath,
15191517

15201518
success |= !rewriteInstance.getDiagnostics().hasErrorOccurred();
15211519
if (!success) {
1522-
Impl.SwiftContext.Diags.diagnose({},
1523-
diag::could_not_rewrite_bridging_header);
1520+
Impl.diagnose({}, diag::could_not_rewrite_bridging_header);
15241521
return "";
15251522
}
15261523

@@ -1607,9 +1604,8 @@ ClangImporter::emitBridgingPCH(StringRef headerPath,
16071604
emitInstance->ExecuteAction(*action);
16081605

16091606
if (emitInstance->getDiagnostics().hasErrorOccurred()) {
1610-
Impl.SwiftContext.Diags.diagnose({},
1611-
diag::bridging_header_pch_error,
1612-
outputPCHPath, headerPath);
1607+
Impl.diagnose({}, diag::bridging_header_pch_error,
1608+
outputPCHPath, headerPath);
16131609
return true;
16141610
}
16151611
return false;
@@ -1668,9 +1664,7 @@ bool ClangImporter::emitPrecompiledModule(StringRef moduleMapPath,
16681664
emitInstance->ExecuteAction(*action);
16691665

16701666
if (emitInstance->getDiagnostics().hasErrorOccurred()) {
1671-
Impl.SwiftContext.Diags.diagnose({},
1672-
diag::emit_pcm_error,
1673-
outputPath, moduleMapPath);
1667+
Impl.diagnose({}, diag::emit_pcm_error, outputPath, moduleMapPath);
16741668
return true;
16751669
}
16761670
return false;
@@ -1693,7 +1687,7 @@ bool ClangImporter::dumpPrecompiledModule(StringRef modulePath,
16931687
dumpInstance->ExecuteAction(*action);
16941688

16951689
if (dumpInstance->getDiagnostics().hasErrorOccurred()) {
1696-
Impl.SwiftContext.Diags.diagnose({}, diag::dump_pcm_error, modulePath);
1690+
Impl.diagnose({}, diag::dump_pcm_error, modulePath);
16971691
return true;
16981692
}
16991693
return false;

lib/ClangImporter/ImportDecl.cpp

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3995,18 +3995,15 @@ namespace {
39953995

39963996
if (dc->getSelfProtocolDecl() && !selfIdx) {
39973997
// FIXME: source location...
3998-
Impl.SwiftContext.Diags.diagnose({}, diag::swift_name_protocol_static,
3999-
/*isInit=*/false);
4000-
Impl.SwiftContext.Diags.diagnose({}, diag::note_while_importing,
4001-
decl->getName());
3998+
Impl.diagnose({}, diag::swift_name_protocol_static, /*isInit=*/false);
3999+
Impl.diagnose({}, diag::note_while_importing, decl->getName());
40024000
return nullptr;
40034001
}
40044002

40054003
if (!decl->hasPrototype()) {
40064004
// FIXME: source location...
4007-
Impl.SwiftContext.Diags.diagnose({}, diag::swift_name_no_prototype);
4008-
Impl.SwiftContext.Diags.diagnose({}, diag::note_while_importing,
4009-
decl->getName());
4005+
Impl.diagnose({}, diag::swift_name_no_prototype);
4006+
Impl.diagnose({}, diag::note_while_importing, decl->getName());
40104007
return nullptr;
40114008
}
40124009

@@ -6312,10 +6309,8 @@ Decl *SwiftDeclConverter::importGlobalAsInitializer(
63126309
// Check for some invalid imports
63136310
if (dc->getSelfProtocolDecl()) {
63146311
// FIXME: clang source location
6315-
Impl.SwiftContext.Diags.diagnose({}, diag::swift_name_protocol_static,
6316-
/*isInit=*/true);
6317-
Impl.SwiftContext.Diags.diagnose({}, diag::note_while_importing,
6318-
decl->getName());
6312+
Impl.diagnose({}, diag::swift_name_protocol_static, /*isInit=*/true);
6313+
Impl.diagnose({}, diag::note_while_importing, decl->getName());
63196314
return nullptr;
63206315
}
63216316

@@ -8227,9 +8222,8 @@ void ClangImporter::Implementation::importAttributes(
82278222
getBufferImporterForDiagnostics();
82288223
SourceLoc attrLoc = bufferImporter.resolveSourceLocation(
82298224
clangSrcMgr, swiftAttr->getLocation());
8230-
SwiftContext.Diags.diagnose(
8231-
attrLoc, diag::clang_swift_attr_without_at,
8232-
swiftAttr->getAttribute());
8225+
diagnose(attrLoc, diag::clang_swift_attr_without_at,
8226+
swiftAttr->getAttribute());
82338227
}
82348228
continue;
82358229
}

lib/ClangImporter/ImportType.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2450,12 +2450,12 @@ ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType(
24502450
SourceLoc methodLoc =
24512451
bufferImporter.resolveSourceLocation(srcMgr, clangDecl->getLocation());
24522452
if (methodLoc.isValid()) {
2453-
SwiftContext.Diags.diagnose(methodLoc, diag::invalid_swift_name_method,
2453+
diagnose(methodLoc, diag::invalid_swift_name_method,
24542454
swiftParams.size() < argNames.size(),
24552455
swiftParams.size(), argNames.size());
24562456
ModuleDecl *parentModule = dc->getParentModule();
24572457
if (parentModule != ImportedHeaderUnit->getParentModule()) {
2458-
SwiftContext.Diags.diagnose(
2458+
diagnose(
24592459
methodLoc, diag::unresolvable_clang_decl_is_a_framework_bug,
24602460
parentModule->getName().str());
24612461
}

lib/ClangImporter/ImporterImpl.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,30 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
747747
bool fullyQualified,
748748
llvm::raw_ostream &os);
749749

750+
/// Emit a diagnostic, taking care not to interrupt a diagnostic that's
751+
/// already in flight.
752+
template<typename ...Args>
753+
void diagnose(Args &&...args) {
754+
// If we're in the middle of pretty-printing, suppress diagnostics.
755+
if (SwiftContext.Diags.isPrettyPrintingDecl()) {
756+
return;
757+
}
758+
759+
SwiftContext.Diags.diagnose(std::forward<Args>(args)...);
760+
}
761+
762+
/// Emit a diagnostic, taking care not to interrupt a diagnostic that's
763+
/// already in flight.
764+
template<typename ...Args>
765+
void diagnose(SourceLoc loc, Args &&...args) {
766+
// If we're in the middle of pretty-printing, suppress diagnostics.
767+
if (SwiftContext.Diags.isPrettyPrintingDecl()) {
768+
return;
769+
}
770+
771+
SwiftContext.Diags.diagnose(loc, std::forward<Args>(args)...);
772+
}
773+
750774
/// Import the given Clang identifier into Swift.
751775
///
752776
/// \param identifier The Clang identifier to map into Swift.

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2669,7 +2669,9 @@ ActorIsolation ActorIsolationRequest::evaluate(
26692669
// If the declaration witnesses a protocol requirement that is isolated,
26702670
// use that.
26712671
if (auto witnessedIsolation = getIsolationFromWitnessedRequirements(value)) {
2672-
return inferredIsolation(*witnessedIsolation);
2672+
if (auto inferred = inferredIsolation(
2673+
*witnessedIsolation, /*propagateUnsafe=*/defaultIsolation))
2674+
return inferred;
26732675
}
26742676

26752677
// If the declaration is a class with a superclass that has specified
@@ -2688,7 +2690,8 @@ ActorIsolation ActorIsolationRequest::evaluate(
26882690
superclassIsolation = superclassIsolation.subst(subs);
26892691
}
26902692

2691-
return inferredIsolation(superclassIsolation);
2693+
if (auto inferred = inferredIsolation(superclassIsolation))
2694+
return inferred;
26922695
}
26932696
}
26942697
}

test/ClangImporter/objc_async.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ func testSlowServerOldSchool(slowServer: SlowServer) {
7777
func globalAsync() async { }
7878

7979
actor MySubclassCheckingSwiftAttributes : ProtocolWithSwiftAttributes {
80-
func syncMethod() { } // expected-note {{calls to instance method 'syncMethod()' from outside of its actor context are implicitly asynchronous}}
80+
func syncMethod() { } // expected-note 2{{calls to instance method 'syncMethod()' from outside of its actor context are implicitly asynchronous}}
8181

8282
func independentMethod() {
8383
syncMethod() // expected-error{{ctor-isolated instance method 'syncMethod()' can not be referenced from a non-isolated context}}
@@ -88,7 +88,7 @@ actor MySubclassCheckingSwiftAttributes : ProtocolWithSwiftAttributes {
8888
}
8989

9090
func mainActorMethod() {
91-
syncMethod()
91+
syncMethod() // expected-error{{actor-isolated instance method 'syncMethod()' can not be referenced from synchronous context of global actor 'MainActor'}}
9292
}
9393

9494
func uiActorMethod() { }

test/Concurrency/global_actor_inference.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,13 @@ struct StructUGA2: UGA {
361361
nonisolated func req() { }
362362
}
363363

364+
@SomeGlobalActor
365+
struct StructUGA3: UGA {
366+
func req() {
367+
sibling()
368+
}
369+
}
370+
364371
@GenericGlobalActor<String>
365372
func testUGA<T: UGA>(_ value: T) {
366373
value.req() // expected-error{{instance method 'req()' isolated to global actor 'SomeGlobalActor' can not be referenced from different global actor 'GenericGlobalActor<String>'}}

0 commit comments

Comments
 (0)