Suggest @_predatesConcurrency import to suppress diagnostics.

When diagnosing a `Sendable` violation, suggest the use of
`@_predatesConcurrency` on the corresponding import to suppress those
diagnostics.
This commit is contained in:
Doug Gregor
2021-12-21 10:48:54 -08:00
parent 0367213929
commit 23cc638ccc
6 changed files with 70 additions and 33 deletions

View File

@@ -56,9 +56,6 @@ struct UnboundImport {
/// determine the behavior expected for this import.
AttributedImport<UnloadedImportedModule> import;
/// The source location to use when diagnosing errors for this import.
SourceLoc importLoc;
/// If this UnboundImport directly represents an ImportDecl, contains the
/// ImportDecl it represents. This should only be used for diagnostics and
/// for updating the AST; if you want to read information about the import,
@@ -480,7 +477,8 @@ ModuleImplicitImportsRequest::evaluate(Evaluator &evaluator,
!clangImporter->importBridgingHeader(bridgingHeaderPath, module)) {
auto *headerModule = clangImporter->getImportedHeaderModule();
assert(headerModule && "Didn't load bridging header?");
imports.emplace_back(ImportedModule(headerModule), ImportFlags::Exported);
imports.emplace_back(
ImportedModule(headerModule), SourceLoc(), ImportFlags::Exported);
}
// Implicitly import the underlying Clang half of this module if needed.
@@ -490,7 +488,7 @@ ModuleImplicitImportsRequest::evaluate(Evaluator &evaluator,
ImportPath::Builder importPath(module->getName());
unloadedImports.emplace_back(UnloadedImportedModule(importPath.copyTo(ctx),
/*isScoped=*/false),
ImportFlags::Exported);
SourceLoc(), ImportFlags::Exported);
}
return { ctx.AllocateCopy(imports), ctx.AllocateCopy(unloadedImports) };
@@ -513,7 +511,7 @@ void ImportResolver::addImplicitImports() {
}
UnboundImport::UnboundImport(AttributedImport<UnloadedImportedModule> implicit)
: import(implicit), importLoc(),
: import(implicit),
importOrUnderlyingModuleDecl(static_cast<ImportDecl *>(nullptr)) {}
//===----------------------------------------------------------------------===//
@@ -523,8 +521,8 @@ UnboundImport::UnboundImport(AttributedImport<UnloadedImportedModule> implicit)
/// Create an UnboundImport for a user-written import declaration.
UnboundImport::UnboundImport(ImportDecl *ID)
: import(UnloadedImportedModule(ID->getImportPath(), ID->getImportKind()),
{}),
importLoc(ID->getLoc()), importOrUnderlyingModuleDecl(ID)
ID->getStartLoc(), {}),
importOrUnderlyingModuleDecl(ID)
{
if (ID->isExported())
import.options |= ImportFlags::Exported;
@@ -571,10 +569,11 @@ bool UnboundImport::checkNotTautological(const SourceFile &SF) {
StringRef filename = llvm::sys::path::filename(SF.getFilename());
if (filename.empty())
ctx.Diags.diagnose(importLoc, diag::sema_import_current_module,
ctx.Diags.diagnose(import.importLoc, diag::sema_import_current_module,
modulePath.front().Item);
else
ctx.Diags.diagnose(importLoc, diag::sema_import_current_module_with_file,
ctx.Diags.diagnose(import.importLoc,
diag::sema_import_current_module_with_file,
filename, modulePath.front().Item);
return false;
@@ -584,7 +583,7 @@ bool UnboundImport::checkModuleLoaded(ModuleDecl *M, SourceFile &SF) {
if (M)
return true;
diagnoseNoSuchModule(SF.getParentModule(), importLoc,
diagnoseNoSuchModule(SF.getParentModule(), import.importLoc,
import.module.getModulePath(), /*nonfatalInREPL=*/true);
return false;
}
@@ -963,9 +962,9 @@ UnboundImport::UnboundImport(
ASTContext &ctx, const UnboundImport &base, Identifier overlayName,
const AttributedImport<ImportedModule> &declaringImport,
const AttributedImport<ImportedModule> &bystandingImport)
: import(makeUnimportedCrossImportOverlay(ctx, overlayName, base,
declaringImport), {}),
importLoc(base.importLoc),
: import(makeUnimportedCrossImportOverlay(
ctx, overlayName, base, declaringImport),
base.import.importLoc, {}),
importOrUnderlyingModuleDecl(declaringImport.module.importedModule)
{
// A cross-import is never private or testable, and never comes from a private
@@ -1099,7 +1098,8 @@ void ImportResolver::findCrossImports(
// Find modules we need to import.
SmallVector<Identifier, 4> names;
declaringImport.module.importedModule->findDeclaredCrossImportOverlays(
bystandingImport.module.importedModule->getName(), names, I.importLoc);
bystandingImport.module.importedModule->getName(), names,
I.import.importLoc);
// If we're diagnosing cases where we cross-import in both directions, get the
// inverse list. Otherwise, leave the list empty.
@@ -1107,7 +1107,7 @@ void ImportResolver::findCrossImports(
if (shouldDiagnoseRedundantCrossImports)
bystandingImport.module.importedModule->findDeclaredCrossImportOverlays(
declaringImport.module.importedModule->getName(), oppositeNames,
I.importLoc);
I.import.importLoc);
if (ctx.Stats && !names.empty())
++ctx.Stats->getFrontendCounters().NumCrossImportsFound;
@@ -1124,13 +1124,14 @@ void ImportResolver::findCrossImports(
declaringImport, bystandingImport);
if (llvm::is_contained(oppositeNames, name))
ctx.Diags.diagnose(I.importLoc, diag::cross_imported_by_both_modules,
ctx.Diags.diagnose(I.import.importLoc,
diag::cross_imported_by_both_modules,
declaringImport.module.importedModule->getName(),
bystandingImport.module.importedModule->getName(),
name);
if (ctx.LangOpts.EnableCrossImportRemarks)
ctx.Diags.diagnose(I.importLoc, diag::cross_import_added,
ctx.Diags.diagnose(I.import.importLoc, diag::cross_import_added,
declaringImport.module.importedModule->getName(),
bystandingImport.module.importedModule->getName(),
name);